@stripe/extensibility-sdk 0.24.1 → 0.26.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.
Files changed (54) hide show
  1. package/README.md +328 -0
  2. package/dist/config-values/generate.cjs +1 -1
  3. package/dist/config-values/generate.d.ts +2 -0
  4. package/dist/config-values/generate.d.ts.map +1 -1
  5. package/dist/config-values/generate.js +1 -1
  6. package/dist/extensibility-sdk-alpha.d.ts +141 -98
  7. package/dist/extensibility-sdk-beta.d.ts +141 -98
  8. package/dist/extensibility-sdk-extensions-alpha.d.ts +155 -25
  9. package/dist/extensibility-sdk-extensions-beta.d.ts +155 -25
  10. package/dist/extensibility-sdk-extensions-internal.d.ts +160 -26
  11. package/dist/extensibility-sdk-extensions-public.d.ts +155 -25
  12. package/dist/extensibility-sdk-internal-alpha.d.ts +5 -0
  13. package/dist/extensibility-sdk-internal-beta.d.ts +5 -0
  14. package/dist/extensibility-sdk-internal-internal.d.ts +5 -0
  15. package/dist/extensibility-sdk-internal-public.d.ts +5 -0
  16. package/dist/extensibility-sdk-internal.d.ts +144 -82
  17. package/dist/extensibility-sdk-public.d.ts +141 -98
  18. package/dist/extensibility-sdk-stdlib-alpha.d.ts +146 -98
  19. package/dist/extensibility-sdk-stdlib-beta.d.ts +146 -98
  20. package/dist/extensibility-sdk-stdlib-internal.d.ts +149 -82
  21. package/dist/extensibility-sdk-stdlib-public.d.ts +146 -98
  22. package/dist/extensions/billing/bill/discount_calculation.d.ts +5 -3
  23. package/dist/extensions/billing/customer_balance_application.d.ts +3 -1
  24. package/dist/extensions/billing/invoice_collection_setting.d.ts +15 -11
  25. package/dist/extensions/billing/prorations.d.ts +30 -21
  26. package/dist/extensions/billing/recurring_billing_item_handling.d.ts +41 -23
  27. package/dist/extensions/billing/types.d.ts +4 -4
  28. package/dist/extensions/core/workflows/custom_action.d.ts +6 -2
  29. package/dist/extensions/extend/workflows/custom_action.d.ts +6 -2
  30. package/dist/index.cjs +398 -163
  31. package/dist/index.js +395 -158
  32. package/dist/internal.d.ts +4 -0
  33. package/dist/internal.d.ts.map +1 -1
  34. package/dist/stdlib/brand.d.ts +16 -10
  35. package/dist/stdlib/brand.d.ts.map +1 -1
  36. package/dist/stdlib/decimal.d.ts +50 -22
  37. package/dist/stdlib/decimal.d.ts.map +1 -1
  38. package/dist/stdlib/index.cjs +398 -163
  39. package/dist/stdlib/index.d.ts +11 -5
  40. package/dist/stdlib/index.d.ts.map +1 -1
  41. package/dist/stdlib/index.js +395 -158
  42. package/dist/stdlib/refs.d.ts +12 -20
  43. package/dist/stdlib/refs.d.ts.map +1 -1
  44. package/dist/stdlib/scalars.d.ts +51 -36
  45. package/dist/stdlib/scalars.d.ts.map +1 -1
  46. package/dist/stdlib/to-const.d.ts +35 -0
  47. package/dist/stdlib/to-const.d.ts.map +1 -0
  48. package/dist/stdlib/transforms.d.ts +1 -1
  49. package/dist/stdlib/type-utils.d.ts +3 -1
  50. package/dist/stdlib/types.d.ts +11 -11
  51. package/dist/stdlib/types.d.ts.map +1 -1
  52. package/dist/tsconfig.build.tsbuildinfo +1 -1
  53. package/package.json +11 -11
  54. package/dist/api-surface.d.ts.map +0 -1
package/README.md ADDED
@@ -0,0 +1,328 @@
1
+ # @stripe/extensibility-sdk
2
+
3
+ Runtime SDK for Stripe script extensions. Provides TypeScript extension interfaces, a
4
+ Stripe-safe arbitrary-precision `Decimal` type, scalar primitives, and the wire-format
5
+ transformation framework used by the platform dispatcher.
6
+
7
+ ---
8
+
9
+ ## Subpath exports
10
+
11
+ | Import path | Use for |
12
+ | ----------------------------------------- | ------------------------------------------------ |
13
+ | `@stripe/extensibility-sdk/extensions` | Implementing extension interfaces |
14
+ | `@stripe/extensibility-sdk/stdlib` | `Decimal`, scalar types, `Ref`, wire errors |
15
+ | `@stripe/extensibility-sdk/internal` | Internal registry metadata (used by build tools) |
16
+ | `@stripe/extensibility-sdk/jsonschema` | JSON Schema types and helpers |
17
+ | `@stripe/extensibility-sdk/config-values` | Configuration value types and helpers |
18
+
19
+ ---
20
+
21
+ ## Extension interfaces
22
+
23
+ Each extension interface is a TypeScript interface your default-export class must implement.
24
+ The `Config` type parameter is the shape of your extension's configuration object.
25
+
26
+ ### Billing
27
+
28
+ #### `Billing.Bill.DiscountCalculation`
29
+
30
+ Computes discounts applied to a bill.
31
+
32
+ ```typescript
33
+ import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
34
+
35
+ interface MyConfig extends Record<string, unknown> {
36
+ maxDiscountPercent: number;
37
+ }
38
+
39
+ export default class MyExtension implements Billing.Bill.DiscountCalculation<MyConfig> {
40
+ computeDiscounts(
41
+ request: Billing.Bill.DiscountCalculation.DiscountableItem,
42
+ config: MyConfig,
43
+ context: Context
44
+ ): Billing.Bill.DiscountCalculation.DiscountResult {
45
+ const { grossAmount } = request;
46
+ const discountAmount = grossAmount.amount
47
+ .mul(config.maxDiscountPercent)
48
+ .div(100, 8, 'half-even');
49
+ return {
50
+ discount: {
51
+ amount: { amount: discountAmount, currency: grossAmount.currency },
52
+ },
53
+ };
54
+ }
55
+ }
56
+ ```
57
+
58
+ Key types in the `Billing.Bill.DiscountCalculation` namespace:
59
+
60
+ | Type | Description |
61
+ | ------------------ | ------------------------------------------------------------------------- |
62
+ | `DiscountableItem` | Request: line items, gross amount, customer, billing reason, subscription |
63
+ | `DiscountResult` | Response: discount with `MonetaryAmount` |
64
+ | `LineItem` | A single line with subtotal, quantity, price, period |
65
+ | `Price` | Price with scheme, tiers, recurring config |
66
+ | `BillingReason` | Enum: `'subscription_cycle'`, `'manual'`, etc. |
67
+ | `AnyTimeRange` | Discriminated union: `oneTime` \| `timeRange` |
68
+ | `MonetaryAmount` | `{ amount: Decimal; currency: Currency }` |
69
+
70
+ ---
71
+
72
+ #### `Billing.CustomerBalanceApplication`
73
+
74
+ Computes how much of a customer's credit balance to apply to a bill.
75
+
76
+ ```typescript
77
+ import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
78
+
79
+ export default class MyExtension implements Billing.CustomerBalanceApplication<
80
+ Record<string, unknown>
81
+ > {
82
+ computeAppliedCustomerBalance(
83
+ request: Billing.CustomerBalanceApplication.CustomerBalanceApplicationInput,
84
+ _config: Record<string, unknown>,
85
+ _context: Context
86
+ ): Billing.CustomerBalanceApplication.CustomerBalanceApplicationResult {
87
+ // Apply at most 50% of the bill total from the customer balance
88
+ const halfTotal = request.totalAmount.amount.div(2, 8, 'half-even');
89
+ const applied = request.customerBalance.amount.lt(halfTotal)
90
+ ? request.customerBalance.amount
91
+ : halfTotal;
92
+ return {
93
+ appliedCustomerBalance: { amount: applied, currency: request.totalAmount.currency },
94
+ };
95
+ }
96
+ }
97
+ ```
98
+
99
+ Key types:
100
+
101
+ | Type | Description |
102
+ | ---------------------------------- | ------------------------------------------------------------------ |
103
+ | `CustomerBalanceApplicationInput` | `{ totalAmount: MonetaryAmount; customerBalance: MonetaryAmount }` |
104
+ | `CustomerBalanceApplicationResult` | `{ appliedCustomerBalance: MonetaryAmount }` |
105
+
106
+ ---
107
+
108
+ #### `Billing.InvoiceCollectionSetting`
109
+
110
+ Overrides collection settings (payment method, auto-advance, etc.) for an invoice.
111
+
112
+ ```typescript
113
+ import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
114
+
115
+ export default class MyExtension implements Billing.InvoiceCollectionSetting<
116
+ Record<string, unknown>
117
+ > {
118
+ collectionOverride(
119
+ request: Billing.InvoiceCollectionSetting.InvoiceCollectionRequest,
120
+ _config: Record<string, unknown>,
121
+ _context: Context
122
+ ): Billing.InvoiceCollectionSetting.InvoiceCollectionResponse {
123
+ const isSubscription = request.parent.type === 'subscription';
124
+ return {
125
+ autoAdvance: isSubscription,
126
+ };
127
+ }
128
+ }
129
+ ```
130
+
131
+ Key types:
132
+
133
+ | Type | Description |
134
+ | --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
135
+ | `InvoiceCollectionRequest` | Request: collection settings, parent, customer |
136
+ | `InvoiceCollectionResponse` | Response: optional `autoAdvance` override |
137
+ | `CollectionSettings` | Current settings with `autoAdvance`, `collectionMethod`, `paymentMethods` |
138
+ | `ParentType` | `'subscription'` \| `'contract'` \| `'quote'` \| `'billing_cadence'` \| `'subscription_schedule'` \| `'standalone'` |
139
+ | `CollectionMethod` | `'charge_automatically'` \| `'send_invoice'` |
140
+ | `PaymentMethodType` | `'card'` \| `'sepa_debit'` \| … |
141
+
142
+ ---
143
+
144
+ #### `Billing.Prorations`
145
+
146
+ Computes proration adjustments when subscription items change mid-period.
147
+
148
+ ```typescript
149
+ import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
150
+
151
+ export default class MyExtension implements Billing.Prorations<Record<string, unknown>> {
152
+ prorateItems(
153
+ request: Billing.Prorations.ProrateItemsInput,
154
+ _config: Record<string, unknown>,
155
+ _context: Context
156
+ ): Billing.Prorations.ProrateItemsResult {
157
+ return {
158
+ items: request.items.map((item) => ({
159
+ key: item.key,
160
+ prorationFactor: item.currentProrationFactor,
161
+ lineItemPeriod: item.servicePeriod,
162
+ })),
163
+ };
164
+ }
165
+ }
166
+ ```
167
+
168
+ Key types:
169
+
170
+ | Type | Description |
171
+ | -------------------- | ----------------------------------------------------------------- |
172
+ | `ProrateItemsInput` | `{ items: ProratableItem[] }` |
173
+ | `ProrateItemsResult` | `{ items: ProratedItem[] }` |
174
+ | `ProratableItem` | Line item with key, type, price, proration factor, service period |
175
+ | `ProratedItem` | Output: key, proration factor, line item period |
176
+ | `ItemType` | `'credit'` \| `'debit'` |
177
+
178
+ ---
179
+
180
+ ### Core
181
+
182
+ #### `Core.Workflows.CustomAction`
183
+
184
+ Implements a custom action callable from Stripe workflows. `execute` is required;
185
+ `getFormState` is optional and drives dynamic form rendering.
186
+
187
+ ```typescript
188
+ import type { Core, Context } from '@stripe/extensibility-sdk/extensions';
189
+
190
+ interface MyConfig extends Record<string, unknown> {
191
+ webhookEndpoint: string;
192
+ webhookPath: string;
193
+ }
194
+
195
+ export default class MyExtension implements Core.Workflows.CustomAction<MyConfig> {
196
+ async execute(
197
+ request: Core.Workflows.CustomAction.ExecuteCustomActionRequest,
198
+ config: MyConfig,
199
+ _context: Context
200
+ ): Promise<Core.Workflows.CustomAction.ExecuteCustomActionResponse> {
201
+ const { customInput } = request;
202
+
203
+ await endpointFetch({
204
+ endpoint: config.webhookEndpoint,
205
+ path: config.webhookPath,
206
+ method: 'POST',
207
+ body: JSON.stringify(customInput),
208
+ });
209
+
210
+ return {};
211
+ }
212
+
213
+ async getFormState(
214
+ request: Core.Workflows.CustomAction.GetFormStateRequest,
215
+ _config: MyConfig,
216
+ _context: Context
217
+ ): Promise<Core.Workflows.CustomAction.GetFormStateResponse> {
218
+ return { values: request.values, config: {} };
219
+ }
220
+ }
221
+ ```
222
+
223
+ Key types:
224
+
225
+ | Type | Description |
226
+ | ----------------------------- | ---------------------------------------------------------------------- |
227
+ | `ExecuteCustomActionRequest` | `{ customInput: Record<string, unknown> }` |
228
+ | `ExecuteCustomActionResponse` | `Record<string, never>` (empty object) |
229
+ | `GetFormStateRequest` | `{ values: Record<string, unknown>; changedField?: string }` |
230
+ | `GetFormStateResponse` | `{ values: Record<string, unknown>; config: Record<string, unknown> }` |
231
+
232
+ Both `execute` and `getFormState` may return synchronously or as `Promise`.
233
+
234
+ ---
235
+
236
+ ### Context
237
+
238
+ Every extension method receives a `Context` as its third argument:
239
+
240
+ ```typescript
241
+ import type { Context } from '@stripe/extensibility-sdk/extensions';
242
+
243
+ function handleContext(context: Context) {
244
+ console.log(context.type); // e.g. "core.workflows.custom_workflow_action"
245
+ console.log(context.id); // unique call ID, for debugging
246
+ console.log(context.livemode);
247
+ console.log(context.stripeContext); // set for cross-account calls
248
+ console.log(context.clockTime); // optional SDK-provided clock timestamp
249
+ }
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Stdlib
255
+
256
+ ### `Decimal`
257
+
258
+ Arbitrary-precision decimal arithmetic backed by `big.js`. All monetary values in
259
+ extension interface requests and responses use `Decimal`.
260
+
261
+ ```typescript
262
+ import { Decimal } from '@stripe/extensibility-sdk/stdlib';
263
+
264
+ const a = Decimal.from('10.50');
265
+ const b = Decimal.from(3);
266
+
267
+ a.add(b); // Decimal('13.50')
268
+ a.sub(b); // Decimal('7.50')
269
+ a.mul(b); // Decimal('31.50')
270
+ a.div(b, 8, 'half-even'); // Decimal('3.50000000')
271
+
272
+ a.round({ precision: 2, direction: 'half-even' }); // Decimal('10.50')
273
+ a.round('penny'); // Decimal('10.50') — preset shorthand
274
+
275
+ a.eq(Decimal.from('10.50')); // true
276
+ a.lt(b); // false
277
+ a.lte(b); // false
278
+ a.gt(b); // true
279
+ a.gte(b); // true
280
+
281
+ a.toString(); // '10.50'
282
+ a.toFixed(4, 'half-even'); // '10.5000'
283
+ ```
284
+
285
+ **Rounding directions:** `'ceil'` · `'floor'` · `'round-down'` · `'round-up'` ·
286
+ `'half-up'` · `'half-down'` · `'half-even'`
287
+
288
+ **Rounding presets:** `'penny'` (2 dp, `half-even`) · `'dollar'` (0 dp, `half-even`)
289
+
290
+ `div()` and `toFixed()` always require an explicit precision and rounding direction —
291
+ there are no implicit defaults to prevent silent precision loss.
292
+
293
+ ---
294
+
295
+ ### Scalar types
296
+
297
+ | Type | Description | Constructor |
298
+ | ----------------- | -------------------------- | ------------------------------------ |
299
+ | `Integer` | Whole number (no decimals) | `Integer.from(n, direction)` |
300
+ | `PositiveInteger` | Non-negative integer (≥ 0) | `PositiveInteger.from(n, direction)` |
301
+
302
+ These are branded types — they carry a compile-time brand so TypeScript rejects raw
303
+ `number` or `string` where the stricter type is required.
304
+
305
+ ```typescript
306
+ import { Integer, PositiveInteger } from '@stripe/extensibility-sdk';
307
+
308
+ const count = Integer.from(42, 'round-down'); // Integer
309
+ const qty = PositiveInteger.from(3, 'round-down'); // PositiveInteger
310
+ ```
311
+
312
+ ---
313
+
314
+ ### `Ref`
315
+
316
+ A typed reference to a Stripe object (ID + optional resolved value).
317
+
318
+ ```typescript
319
+ import { Ref } from '@stripe/extensibility-sdk/stdlib';
320
+
321
+ type CustomerRef = Ref<{ id: string; name: string }>;
322
+ ```
323
+
324
+ ---
325
+
326
+ ## License
327
+
328
+ MIT
@@ -157,7 +157,7 @@ function isStdlibDecimalType(type) {
157
157
  if (symbol?.getName() !== "Decimal") return false;
158
158
  return symbol.getDeclarations().some((declaration) => {
159
159
  const srcPath = declaration.getSourceFile().getFilePath();
160
- return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index");
160
+ return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index") || srcPath.includes("extensibility-sdk");
161
161
  });
162
162
  });
163
163
  }
@@ -2,6 +2,8 @@
2
2
  * Emits TypeScript code for a config field descriptor constant and its
3
3
  * corresponding `transformX` function.
4
4
  *
5
+ * @deprecated Import from `@stripe/extensibility-sdk` instead.
6
+ *
5
7
  * @see ./parse.ts — produces the ConfigAnalysisResult input
6
8
  */
7
9
  import type { ConfigAnalysisResult } from './parse.js';
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/config-values/generate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAuB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAG5E,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,kFAAkF;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yDAAyD;IACzD,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,6DAA6D;IAC7D,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,oBAAoB,GAC3B,yBAAyB,CA8C3B"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/config-values/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAuB,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAG5E,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,GACnC,MAAM,YAAY,CAAC;AAMpB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,kFAAkF;IAClF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yDAAyD;IACzD,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,6DAA6D;IAC7D,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,oBAAoB,GAC3B,yBAAyB,CA8C3B"}
@@ -128,7 +128,7 @@ function isStdlibDecimalType(type) {
128
128
  if (symbol?.getName() !== "Decimal") return false;
129
129
  return symbol.getDeclarations().some((declaration) => {
130
130
  const srcPath = declaration.getSourceFile().getFilePath();
131
- return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index");
131
+ return srcPath.includes("stdlib/decimal") || srcPath.includes("stdlib/index") || srcPath.includes("extensibility-sdk");
132
132
  });
133
133
  });
134
134
  }