alchemy 0.32.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cloudflare/astro.d.ts +3 -3
- package/lib/cloudflare/astro.d.ts.map +1 -1
- package/lib/cloudflare/astro.js +11 -79
- package/lib/cloudflare/astro.js.map +1 -1
- package/lib/cloudflare/vite.d.ts +1 -1
- package/lib/cloudflare/vite.d.ts.map +1 -1
- package/lib/cloudflare/vite.js +2 -0
- package/lib/cloudflare/vite.js.map +1 -1
- package/lib/cloudflare/website.d.ts +6 -0
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +1 -1
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-assets.d.ts.map +1 -1
- package/lib/cloudflare/worker-assets.js +0 -3
- package/lib/cloudflare/worker-assets.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +6 -8
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/stripe/price.d.ts +112 -8
- package/lib/stripe/price.d.ts.map +1 -1
- package/lib/stripe/price.js +104 -9
- package/lib/stripe/price.js.map +1 -1
- package/package.json +1 -1
- package/src/cloudflare/astro.ts +15 -102
- package/src/cloudflare/vite.ts +4 -1
- package/src/cloudflare/website.ts +8 -1
- package/src/cloudflare/worker-assets.ts +0 -4
- package/src/cloudflare/worker.ts +6 -9
- package/src/stripe/price.ts +199 -12
package/src/stripe/price.ts
CHANGED
|
@@ -37,6 +37,37 @@ export interface PriceRecurring {
|
|
|
37
37
|
type TaxBehavior = Stripe.PriceCreateParams.TaxBehavior;
|
|
38
38
|
type BillingScheme = Stripe.PriceCreateParams.BillingScheme;
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Properties for price tier configuration
|
|
42
|
+
*/
|
|
43
|
+
export interface PriceTier {
|
|
44
|
+
/**
|
|
45
|
+
* The flat billing amount for an entire tier, regardless of the number of units in the tier
|
|
46
|
+
*/
|
|
47
|
+
flatAmount?: number;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Same as flat_amount, but accepts a decimal string with at most 12 decimal places
|
|
51
|
+
*/
|
|
52
|
+
flatAmountDecimal?: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The per-unit amount to charge for units within this tier
|
|
56
|
+
*/
|
|
57
|
+
unitAmount?: number;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Same as unit_amount, but accepts a decimal string with at most 12 decimal places
|
|
61
|
+
*/
|
|
62
|
+
unitAmountDecimal?: string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Specifies the upper bound of the tier. Can be a number or 'inf' for infinity.
|
|
66
|
+
* The last tier should have up_to set to 'inf'.
|
|
67
|
+
*/
|
|
68
|
+
upTo: number | "inf";
|
|
69
|
+
}
|
|
70
|
+
|
|
40
71
|
/**
|
|
41
72
|
* Properties for creating a Stripe price
|
|
42
73
|
*/
|
|
@@ -119,6 +150,36 @@ export interface PriceProps {
|
|
|
119
150
|
* If true, adopt existing resource if creation fails due to conflict
|
|
120
151
|
*/
|
|
121
152
|
adopt?: boolean;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Each element represents a pricing tier. This parameter requires `billingScheme` to be set to `tiered`.
|
|
156
|
+
* An array of up to 250 tiers. Each tier has an upper bound and a price.
|
|
157
|
+
*/
|
|
158
|
+
tiers?: PriceTier[];
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Defines if the tiering price should be `graduated` or `volume` based.
|
|
162
|
+
* In `volume`-based tiering, the maximum quantity within a period determines the per unit price.
|
|
163
|
+
* In `graduated` tiering, pricing can change as the quantity grows.
|
|
164
|
+
*/
|
|
165
|
+
tiersMode?: "graduated" | "volume" | undefined;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Apply a transformation to the reported usage or set quantity before computing the amount billed
|
|
169
|
+
*/
|
|
170
|
+
transformQuantity?:
|
|
171
|
+
| {
|
|
172
|
+
/**
|
|
173
|
+
* Divide usage by this number
|
|
174
|
+
*/
|
|
175
|
+
divideBy: number;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* After dividing usage, either round the result `up` or `down`
|
|
179
|
+
*/
|
|
180
|
+
round: "up" | "down";
|
|
181
|
+
}
|
|
182
|
+
| undefined;
|
|
122
183
|
}
|
|
123
184
|
|
|
124
185
|
/**
|
|
@@ -149,6 +210,26 @@ export interface Price extends Resource<"stripe::Price">, PriceProps {
|
|
|
149
210
|
* The lookup key (if any) used by the customer to identify this price object
|
|
150
211
|
*/
|
|
151
212
|
lookupKey?: string;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The pricing tiers (if using tiered billing scheme)
|
|
216
|
+
*/
|
|
217
|
+
tiers?: PriceTier[];
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* The tiering mode (graduated or volume)
|
|
221
|
+
*/
|
|
222
|
+
tiersMode?: "graduated" | "volume" | undefined;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Transform quantity configuration
|
|
226
|
+
*/
|
|
227
|
+
transformQuantity?:
|
|
228
|
+
| {
|
|
229
|
+
divideBy: number;
|
|
230
|
+
round: "up" | "down";
|
|
231
|
+
}
|
|
232
|
+
| undefined;
|
|
152
233
|
}
|
|
153
234
|
|
|
154
235
|
/**
|
|
@@ -188,17 +269,56 @@ export interface Price extends Resource<"stripe::Price">, PriceProps {
|
|
|
188
269
|
* });
|
|
189
270
|
*
|
|
190
271
|
* @example
|
|
191
|
-
* // Create a tiered price with
|
|
192
|
-
* const tieredPrice = await Price("
|
|
272
|
+
* // Create a graduated tiered price with usage-based billing
|
|
273
|
+
* const tieredPrice = await Price("api-usage", {
|
|
193
274
|
* currency: "usd",
|
|
194
|
-
* unitAmount: 10000, // $100.00
|
|
195
275
|
* product: "prod_xyz",
|
|
196
276
|
* billingScheme: "tiered",
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* }
|
|
277
|
+
* tiersMode: "graduated",
|
|
278
|
+
* recurring: {
|
|
279
|
+
* interval: "month",
|
|
280
|
+
* usageType: "metered"
|
|
281
|
+
* },
|
|
282
|
+
* tiers: [
|
|
283
|
+
* {
|
|
284
|
+
* upTo: 10000,
|
|
285
|
+
* unitAmount: 0 // First 10k API calls free
|
|
286
|
+
* },
|
|
287
|
+
* {
|
|
288
|
+
* upTo: 50000,
|
|
289
|
+
* unitAmount: 2 // $0.02 per call up to 50k
|
|
290
|
+
* },
|
|
291
|
+
* {
|
|
292
|
+
* upTo: "inf",
|
|
293
|
+
* unitAmount: 1 // $0.01 per call beyond 50k
|
|
294
|
+
* }
|
|
295
|
+
* ]
|
|
296
|
+
* });
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* // Create a volume-based tiered price with overage cap
|
|
300
|
+
* const volumePrice = await Price("storage", {
|
|
301
|
+
* currency: "usd",
|
|
302
|
+
* product: "prod_xyz",
|
|
303
|
+
* billingScheme: "tiered",
|
|
304
|
+
* tiersMode: "volume",
|
|
305
|
+
* recurring: {
|
|
306
|
+
* interval: "month"
|
|
307
|
+
* },
|
|
308
|
+
* tiers: [
|
|
309
|
+
* {
|
|
310
|
+
* upTo: 100,
|
|
311
|
+
* unitAmount: 500 // $5 per GB for up to 100GB
|
|
312
|
+
* },
|
|
313
|
+
* {
|
|
314
|
+
* upTo: 1000,
|
|
315
|
+
* unitAmount: 400 // $4 per GB for 101-1000GB
|
|
316
|
+
* },
|
|
317
|
+
* {
|
|
318
|
+
* upTo: "inf",
|
|
319
|
+
* flatAmount: 300000 // Cap at $3000 for unlimited storage
|
|
320
|
+
* }
|
|
321
|
+
* ]
|
|
202
322
|
* });
|
|
203
323
|
*/
|
|
204
324
|
export const Price = Resource(
|
|
@@ -222,23 +342,38 @@ export const Price = Resource(
|
|
|
222
342
|
|
|
223
343
|
return this.destroy();
|
|
224
344
|
}
|
|
345
|
+
|
|
346
|
+
// Validate tier-related constraints
|
|
347
|
+
if (props.tiers && props.billingScheme !== "tiered") {
|
|
348
|
+
throw new Error("Tiers can only be used with billingScheme: 'tiered'");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (props.tiers && (props.unitAmount || props.unitAmountDecimal)) {
|
|
352
|
+
throw new Error("Cannot set both tiers and unitAmount/unitAmountDecimal");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (props.tiersMode && !props.tiers) {
|
|
356
|
+
throw new Error("tiersMode requires tiers to be defined");
|
|
357
|
+
}
|
|
358
|
+
|
|
225
359
|
try {
|
|
226
360
|
let price: Stripe.Price;
|
|
227
361
|
|
|
228
362
|
if (this.phase === "update" && this.output?.id) {
|
|
229
363
|
// Update existing price (limited properties can be updated)
|
|
230
|
-
const updateParams: Stripe.PriceUpdateParams = {
|
|
364
|
+
const updateParams: Stripe.PriceUpdateParams & { expand?: string[] } = {
|
|
231
365
|
active: props.active,
|
|
232
366
|
metadata: props.metadata,
|
|
233
367
|
nickname: props.nickname,
|
|
234
368
|
lookup_key: props.lookupKey,
|
|
235
369
|
transfer_lookup_key: props.transferLookupKey,
|
|
370
|
+
expand: ["tiers"],
|
|
236
371
|
};
|
|
237
372
|
|
|
238
373
|
price = await stripe.prices.update(this.output.id, updateParams);
|
|
239
374
|
} else {
|
|
240
375
|
// Create new price
|
|
241
|
-
const createParams: Stripe.PriceCreateParams = {
|
|
376
|
+
const createParams: Stripe.PriceCreateParams & { expand?: string[] } = {
|
|
242
377
|
currency: props.currency,
|
|
243
378
|
product: props.product,
|
|
244
379
|
active: props.active,
|
|
@@ -248,6 +383,7 @@ export const Price = Resource(
|
|
|
248
383
|
tax_behavior: props.taxBehavior,
|
|
249
384
|
lookup_key: props.lookupKey,
|
|
250
385
|
transfer_lookup_key: props.transferLookupKey,
|
|
386
|
+
expand: ["tiers"],
|
|
251
387
|
};
|
|
252
388
|
|
|
253
389
|
// Add unit amount fields
|
|
@@ -267,6 +403,29 @@ export const Price = Resource(
|
|
|
267
403
|
};
|
|
268
404
|
}
|
|
269
405
|
|
|
406
|
+
// Add tier configuration if present
|
|
407
|
+
if (props.tiers) {
|
|
408
|
+
createParams.tiers = props.tiers.map((tier) => ({
|
|
409
|
+
up_to: tier.upTo === "inf" ? "inf" : tier.upTo,
|
|
410
|
+
flat_amount: tier.flatAmount,
|
|
411
|
+
flat_amount_decimal: tier.flatAmountDecimal,
|
|
412
|
+
unit_amount: tier.unitAmount,
|
|
413
|
+
unit_amount_decimal: tier.unitAmountDecimal,
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (props.tiersMode) {
|
|
418
|
+
createParams.tiers_mode = props.tiersMode;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Add transform quantity if present
|
|
422
|
+
if (props.transformQuantity) {
|
|
423
|
+
createParams.transform_quantity = {
|
|
424
|
+
divide_by: props.transformQuantity.divideBy,
|
|
425
|
+
round: props.transformQuantity.round,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
270
429
|
if (props.lookupKey) {
|
|
271
430
|
const existingPrices = await stripe.prices.list({
|
|
272
431
|
lookup_keys: [props.lookupKey],
|
|
@@ -275,19 +434,25 @@ export const Price = Resource(
|
|
|
275
434
|
if (existingPrices.data.length > 0) {
|
|
276
435
|
if (props.adopt) {
|
|
277
436
|
const existingPrice = existingPrices.data[0];
|
|
278
|
-
const updateParams: Stripe.PriceUpdateParams
|
|
437
|
+
const updateParams: Stripe.PriceUpdateParams & {
|
|
438
|
+
expand?: string[];
|
|
439
|
+
} = {
|
|
279
440
|
active: props.active,
|
|
280
441
|
metadata: props.metadata,
|
|
281
442
|
nickname: props.nickname,
|
|
282
443
|
lookup_key: props.lookupKey,
|
|
283
444
|
transfer_lookup_key: props.transferLookupKey,
|
|
445
|
+
expand: ["tiers"],
|
|
284
446
|
};
|
|
285
447
|
price = await stripe.prices.update(
|
|
286
448
|
existingPrice.id,
|
|
287
449
|
updateParams,
|
|
288
450
|
);
|
|
289
451
|
} else {
|
|
290
|
-
|
|
452
|
+
// Need to retrieve with expanded tiers
|
|
453
|
+
price = await stripe.prices.retrieve(existingPrices.data[0].id, {
|
|
454
|
+
expand: ["tiers"],
|
|
455
|
+
} as any);
|
|
291
456
|
}
|
|
292
457
|
} else {
|
|
293
458
|
price = await stripe.prices.create(createParams);
|
|
@@ -310,6 +475,25 @@ export const Price = Resource(
|
|
|
310
475
|
}
|
|
311
476
|
: undefined;
|
|
312
477
|
|
|
478
|
+
// Transform Stripe tiers array to our format
|
|
479
|
+
const tiers = price.tiers
|
|
480
|
+
? price.tiers.map((tier) => ({
|
|
481
|
+
flatAmount: tier.flat_amount || undefined,
|
|
482
|
+
flatAmountDecimal: tier.flat_amount_decimal || undefined,
|
|
483
|
+
unitAmount: tier.unit_amount || undefined,
|
|
484
|
+
unitAmountDecimal: tier.unit_amount_decimal || undefined,
|
|
485
|
+
upTo: tier.up_to === null ? ("inf" as const) : tier.up_to!,
|
|
486
|
+
}))
|
|
487
|
+
: undefined;
|
|
488
|
+
|
|
489
|
+
// Transform transform_quantity if present
|
|
490
|
+
const transformQuantity = price.transform_quantity
|
|
491
|
+
? {
|
|
492
|
+
divideBy: price.transform_quantity.divide_by,
|
|
493
|
+
round: price.transform_quantity.round as "up" | "down",
|
|
494
|
+
}
|
|
495
|
+
: undefined;
|
|
496
|
+
|
|
313
497
|
// Map Stripe API response to our output format
|
|
314
498
|
return this({
|
|
315
499
|
id: price.id,
|
|
@@ -328,6 +512,9 @@ export const Price = Resource(
|
|
|
328
512
|
livemode: price.livemode,
|
|
329
513
|
type: price.type as Stripe.Price.Type,
|
|
330
514
|
lookupKey: price.lookup_key || undefined,
|
|
515
|
+
tiers: tiers,
|
|
516
|
+
tiersMode: price.tiers_mode ?? undefined,
|
|
517
|
+
transformQuantity: transformQuantity,
|
|
331
518
|
});
|
|
332
519
|
} catch (error) {
|
|
333
520
|
logger.error("Error creating/updating price:", error);
|