|
| 1 | +import { z } from "../../framework"; |
| 2 | + |
| 3 | +import { FailedAPIOperationSchema } from "../common"; |
| 4 | +import { ProjectIdSchema } from "../projects/common"; |
| 5 | + |
| 6 | +import { |
| 7 | + DayStatementIdSchema, |
| 8 | + InvoiceIdSchema, |
| 9 | + MonthStatementIdSchema, |
| 10 | + PurchaseIdSchema, |
| 11 | +} from "./common"; |
| 12 | + |
| 13 | +const PurchaseServiceSchema = z |
| 14 | + .string() |
| 15 | + .describe("The service being charged for, e.g., `openai-gpt-4`, etc."); |
| 16 | + |
| 17 | +// OpenAPI spec |
| 18 | +// |
| 19 | +export const GetPurchasesInputSchema = z |
| 20 | + .object({ |
| 21 | + limit: z |
| 22 | + .number() |
| 23 | + .default(100) |
| 24 | + .describe("Upper bound on the number of purchases to return.") |
| 25 | + .nullish(), |
| 26 | + offset: z |
| 27 | + .number() |
| 28 | + .describe("Number of purchases by which to offset results.") |
| 29 | + .nullish(), |
| 30 | + service: PurchaseServiceSchema.nullish(), |
| 31 | + project_id: ProjectIdSchema.describe( |
| 32 | + "The project id associated with this purchase, if one exists.", |
| 33 | + ).nullish(), |
| 34 | + group: z |
| 35 | + .boolean() |
| 36 | + .describe( |
| 37 | + `If \`true\`, results are groups by service and project id, and then decreasingly |
| 38 | + ordered by cost. Otherwise, results are ordered by time, with the newest |
| 39 | + purchases returned first.`, |
| 40 | + ) |
| 41 | + .nullish(), |
| 42 | + cutoff: z |
| 43 | + .union([z.string(), z.number()]) |
| 44 | + .describe( |
| 45 | + `When provided, only purchases which occur _after_ the timestamp specified in this |
| 46 | + field will be returned.`, |
| 47 | + ) |
| 48 | + .nullish(), |
| 49 | + thisMonth: z |
| 50 | + .boolean() |
| 51 | + .describe( |
| 52 | + "If `true`, only purchases since the most recent closing date will be returned.", |
| 53 | + ) |
| 54 | + .nullish(), |
| 55 | + day_statement_id: DayStatementIdSchema.describe( |
| 56 | + "Daily statement id of the statement that includes this purchase", |
| 57 | + ).nullish(), |
| 58 | + month_statement_id: MonthStatementIdSchema.describe( |
| 59 | + "Monthly statement id of the statement that includes this purchase", |
| 60 | + ).nullish(), |
| 61 | + no_statement: z |
| 62 | + .boolean() |
| 63 | + .describe( |
| 64 | + `If \`true\`, only purchases which are |
| 65 | + _not_ associated with a monthly or daily statement are returned.`, |
| 66 | + ) |
| 67 | + .nullish(), |
| 68 | + }) |
| 69 | + .describe("Gets user purchases."); |
| 70 | + |
| 71 | +export const GetPurchasesOutputSchema = z.union([ |
| 72 | + FailedAPIOperationSchema, |
| 73 | + z |
| 74 | + .array( |
| 75 | + z.object({ |
| 76 | + id: PurchaseIdSchema, |
| 77 | + time: z.string().describe("Time at which this purchase was logged."), |
| 78 | + cost: z.number().describe( |
| 79 | + `The cost in US dollars. Not set if the purchase isn't finished, e.g., when |
| 80 | + upgrading a project this is only set when project stops or purchase is finalized. |
| 81 | + This takes precedence over the \`cost_per_hour\` times the length of the period |
| 82 | + when active.`, |
| 83 | + ), |
| 84 | + period_start: z.string().describe( |
| 85 | + `When the purchase starts being active (e.g., a 1 week license starts and ends on |
| 86 | + specific days; for metered purchases it is when the purchased started charging) `, |
| 87 | + ), |
| 88 | + period_end: z.string().describe( |
| 89 | + `When the purchase stops being active. For metered purchases, it's when the |
| 90 | + purchase finished being charged, in which case the cost field should be equal to |
| 91 | + the length of the period times the \`cost_per_hour\`.`, |
| 92 | + ), |
| 93 | + cost_per_hour: z.number().describe( |
| 94 | + `The cost in US dollars per hour. This is used to compute the cost so far for |
| 95 | + metered purchases when the cost field isn't set yet. The cost so far is the |
| 96 | + number of hours since \`period_start\` times the \`cost_per_hour\`. The |
| 97 | + description field may also contain redundant cost per hour information, but this |
| 98 | + \`cost_per_hour\` field is the definitive source of truth. Once the \`cost\` |
| 99 | + field is set, this \`cost_per_hour\` is just useful for display purposes.`, |
| 100 | + ), |
| 101 | + cost_so_far: z.number().describe( |
| 102 | + `The cost so far in US dollars for a metered purchase that accumulates. This is |
| 103 | + used, e.g., for data transfer charges.`, |
| 104 | + ), |
| 105 | + service: PurchaseServiceSchema, |
| 106 | + description: z.map(z.string(), z.any()).describe( |
| 107 | + `An object that provides additional details about what was purchased and can have |
| 108 | + an arbitrary format. This is mainly used to provide extra insight when rendering |
| 109 | + this purchase for users, and its content should not be relied on for queries.`, |
| 110 | + ), |
| 111 | + invoice_id: InvoiceIdSchema.nullable().describe( |
| 112 | + `The id of the Stripe invoice that was sent that included this item. May be |
| 113 | + null. **Legacy Behavior:** if paid via a payment intent, this will be the id of |
| 114 | + a payment intent instead, and it will start with \`pi_\`.`, |
| 115 | + ), |
| 116 | + project_id: ProjectIdSchema.nullable().describe( |
| 117 | + `The id of the project where this purchase happened. Not all purchases |
| 118 | + necessarily involve a project, and so this field may be null.`, |
| 119 | + ), |
| 120 | + pending: z |
| 121 | + .boolean() |
| 122 | + .nullable() |
| 123 | + .describe( |
| 124 | + `If \`true\`, then this transaction is considered pending, which means that |
| 125 | + for a few days it doesn't count against the user's quotas for the purposes of |
| 126 | + deciding whether or not a purchase is allowed. This is needed so we can charge |
| 127 | + a user for their subscriptions, then collect the money from them, without all |
| 128 | + of the running pay-as-you-go project upgrades suddenly breaking (etc.).`, |
| 129 | + ), |
| 130 | + note: z |
| 131 | + .string() |
| 132 | + .nullable() |
| 133 | + .describe( |
| 134 | + `Non-private notes about this purchase. The user has read-only access to this |
| 135 | + field.`, |
| 136 | + ), |
| 137 | + }), |
| 138 | + ) |
| 139 | + .describe( |
| 140 | + `An array of purchases filtered and/or grouped according to the provided request |
| 141 | + body.`, |
| 142 | + ), |
| 143 | +]); |
| 144 | + |
| 145 | +export type GetPurchasesInput = z.infer<typeof GetPurchasesInputSchema>; |
| 146 | +export type GetPurchasesOutput = z.infer<typeof GetPurchasesOutputSchema>; |
0 commit comments