@volter/twin-stripe 2.0.37 → 3.0.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/README.md +82 -207
- package/dist/generated/pack-facts.json +94 -0
- package/dist/spec/SOURCE.md +14 -0
- package/dist/spec/fixtures3.json.gz +0 -0
- package/dist/spec/openapi.json.gz +0 -0
- package/dist/spec/patches.json +34 -0
- package/dist/spec/sources.json +378 -0
- package/dist/src/cli.js +12 -30
- package/dist/src/engine/after-payment.d.ts +9 -0
- package/dist/src/engine/after-payment.js +28 -0
- package/dist/src/engine/apps-secrets.d.ts +1 -0
- package/dist/src/engine/apps-secrets.js +3 -0
- package/dist/src/engine/balance.d.ts +5 -0
- package/dist/src/engine/balance.js +15 -0
- package/dist/src/engine/billing.d.ts +5 -0
- package/dist/src/engine/billing.js +6 -0
- package/dist/src/engine/charges.d.ts +6 -0
- package/dist/src/engine/charges.js +13 -0
- package/dist/src/engine/checkout.d.ts +24 -0
- package/dist/src/engine/checkout.js +30 -0
- package/dist/src/engine/common.d.ts +19 -0
- package/dist/src/engine/common.js +32 -0
- package/dist/src/{screens → engine}/connect-settings.d.ts +1 -7
- package/dist/src/engine/connect-settings.js +26 -0
- package/dist/src/engine/connect.d.ts +66 -0
- package/dist/src/engine/connect.js +189 -0
- package/dist/src/engine/coupons.d.ts +0 -0
- package/dist/src/engine/coupons.js +5 -0
- package/dist/src/engine/credit-notes.d.ts +1 -0
- package/dist/src/engine/credit-notes.js +5 -0
- package/dist/src/engine/customers.d.ts +12 -0
- package/dist/src/engine/customers.js +30 -0
- package/dist/src/engine/display.d.ts +14 -0
- package/dist/src/engine/display.js +16 -0
- package/dist/src/engine/disputes.d.ts +0 -0
- package/dist/src/engine/disputes.js +9 -0
- package/dist/src/engine/entitlements.d.ts +1 -0
- package/dist/src/engine/entitlements.js +4 -0
- package/dist/src/engine/ephemeral-keys.d.ts +0 -0
- package/dist/src/engine/ephemeral-keys.js +4 -0
- package/dist/src/engine/files.d.ts +18 -0
- package/dist/src/engine/files.js +33 -0
- package/dist/src/engine/front.d.ts +5 -0
- package/dist/src/engine/front.js +25 -0
- package/dist/src/engine/invoices.d.ts +24 -0
- package/dist/src/engine/invoices.js +57 -0
- package/dist/src/engine/issuing.d.ts +35 -0
- package/dist/src/engine/issuing.js +45 -0
- package/dist/src/engine/ledger.d.ts +9 -0
- package/dist/src/engine/ledger.js +9 -0
- package/dist/src/engine/oauth.d.ts +4 -0
- package/dist/src/engine/oauth.js +25 -0
- package/dist/src/engine/onboarding.d.ts +13 -0
- package/dist/src/engine/onboarding.js +42 -0
- package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
- package/dist/src/{stripe-params.js → engine/params.js} +7 -60
- package/dist/src/engine/payment-intents.d.ts +10 -0
- package/dist/src/engine/payment-intents.js +27 -0
- package/dist/src/engine/payment-links.d.ts +1 -0
- package/dist/src/engine/payment-links.js +5 -0
- package/dist/src/engine/payment-methods.d.ts +16 -0
- package/dist/src/engine/payment-methods.js +22 -0
- package/dist/src/engine/plans.d.ts +6 -0
- package/dist/src/engine/plans.js +26 -0
- package/dist/src/engine/platform.d.ts +39 -0
- package/dist/src/engine/platform.js +34 -0
- package/dist/src/engine/products.d.ts +0 -0
- package/dist/src/engine/products.js +4 -0
- package/dist/src/engine/radar.d.ts +2 -0
- package/dist/src/engine/radar.js +5 -0
- package/dist/src/engine/refunds.d.ts +1 -0
- package/dist/src/engine/refunds.js +28 -0
- package/dist/src/engine/renewals.d.ts +36 -0
- package/dist/src/engine/renewals.js +65 -0
- package/dist/src/engine/setup-intents.d.ts +1 -0
- package/dist/src/engine/setup-intents.js +4 -0
- package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +11 -39
- package/dist/src/{stripe-twin.js → engine/stripe.js} +25 -310
- package/dist/src/engine/subscription-schedules.d.ts +3 -0
- package/dist/src/engine/subscription-schedules.js +1 -0
- package/dist/src/engine/subscriptions.d.ts +12 -0
- package/dist/src/engine/subscriptions.js +31 -0
- package/dist/src/engine/tax.d.ts +7 -0
- package/dist/src/engine/tax.js +28 -0
- package/dist/src/engine/terminal.d.ts +4 -0
- package/dist/src/engine/terminal.js +20 -0
- package/dist/src/engine/test-clocks.d.ts +5 -0
- package/dist/src/engine/test-clocks.js +9 -0
- package/dist/src/engine/tokens.d.ts +7 -0
- package/dist/src/engine/tokens.js +20 -0
- package/dist/src/engine/transfers.d.ts +2 -0
- package/dist/src/engine/transfers.js +1 -0
- package/dist/src/engine/treasury.d.ts +23 -0
- package/dist/src/engine/treasury.js +45 -0
- package/dist/src/{stripe-version.js → engine/version.js} +4 -3
- package/dist/src/engine/webhook-endpoints.d.ts +1 -0
- package/dist/src/engine/webhook-endpoints.js +12 -0
- package/dist/src/engine/webhooks.d.ts +31 -0
- package/dist/src/engine/webhooks.js +68 -0
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +26 -0
- package/dist/src/generated/surface.gen.json +1 -1
- package/dist/src/generated/ui.gen.json +1 -1
- package/dist/src/index.d.ts +5 -14
- package/dist/src/index.js +8 -75
- package/dist/src/manifest.js +232 -758
- package/dist/src/screens/billing-portal.d.ts +3 -0
- package/dist/src/screens/{portal.js → billing-portal.js} +28 -54
- package/dist/src/screens/checkout.d.ts +2 -31
- package/dist/src/screens/checkout.js +32 -121
- package/dist/src/screens/connect-oauth.d.ts +3 -27
- package/dist/src/screens/connect-oauth.js +51 -132
- package/dist/src/screens/connect-onboarding.d.ts +3 -0
- package/dist/src/screens/{onboarding.js → connect-onboarding.js} +36 -102
- package/dist/src/screens/dashboard.d.ts +3 -0
- package/dist/src/screens/dashboard.js +117 -0
- package/dist/src/screens/shared.d.ts +27 -0
- package/dist/src/screens/shared.js +87 -0
- package/dist/src/screens/stripe-js.d.ts +3 -0
- package/dist/src/screens/stripe-js.js +135 -0
- package/dist/src/semantics/account_links.d.ts +2 -0
- package/dist/src/semantics/account_links.js +22 -0
- package/dist/src/semantics/accounts.d.ts +4 -0
- package/dist/src/semantics/accounts.js +38 -0
- package/dist/src/semantics/apps.d.ts +4 -0
- package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
- package/dist/src/semantics/around.d.ts +2 -0
- package/dist/src/semantics/around.js +16 -0
- package/dist/src/semantics/balance.d.ts +2 -11
- package/dist/src/semantics/balance.js +3 -194
- package/dist/src/semantics/balance_transactions.d.ts +2 -0
- package/dist/src/semantics/balance_transactions.js +15 -0
- package/dist/src/semantics/billing_portal.d.ts +5 -0
- package/dist/src/semantics/billing_portal.js +42 -0
- package/dist/src/semantics/charges.d.ts +3 -28
- package/dist/src/semantics/charges.js +5 -202
- package/dist/src/semantics/checkout.d.ts +3 -20
- package/dist/src/semantics/checkout.js +8 -261
- package/dist/src/semantics/clock.d.ts +2 -0
- package/dist/src/semantics/clock.js +21 -0
- package/dist/src/semantics/coupons.d.ts +2 -6
- package/dist/src/semantics/coupons.js +2 -60
- package/dist/src/semantics/customers.d.ts +6 -6
- package/dist/src/semantics/customers.js +27 -387
- package/dist/src/semantics/disputes.d.ts +2 -2
- package/dist/src/semantics/disputes.js +3 -49
- package/dist/src/semantics/doors.d.ts +23 -0
- package/dist/src/semantics/doors.js +73 -0
- package/dist/src/semantics/entitlements.d.ts +2 -2
- package/dist/src/semantics/entitlements.js +5 -50
- package/dist/src/semantics/events.d.ts +12 -0
- package/dist/src/semantics/events.js +36 -0
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +107 -0
- package/dist/src/semantics/invoice_payments.d.ts +2 -0
- package/dist/src/semantics/invoice_payments.js +12 -0
- package/dist/src/semantics/invoiceitems.d.ts +3 -0
- package/dist/src/semantics/invoiceitems.js +59 -0
- package/dist/src/semantics/invoices.d.ts +16 -18
- package/dist/src/semantics/invoices.js +118 -444
- package/dist/src/semantics/payment_intents.d.ts +4 -0
- package/dist/src/semantics/payment_intents.js +79 -0
- package/dist/src/semantics/payment_methods.d.ts +5 -0
- package/dist/src/semantics/payment_methods.js +39 -0
- package/dist/src/semantics/payouts.d.ts +2 -0
- package/dist/src/semantics/payouts.js +21 -0
- package/dist/src/semantics/prices.d.ts +4 -0
- package/dist/src/semantics/prices.js +37 -0
- package/dist/src/semantics/products.d.ts +6 -2
- package/dist/src/semantics/products.js +15 -130
- package/dist/src/semantics/promotion_codes.d.ts +3 -0
- package/dist/src/semantics/promotion_codes.js +35 -0
- package/dist/src/semantics/radar.d.ts +2 -2
- package/dist/src/semantics/radar.js +5 -74
- package/dist/src/semantics/refunds.d.ts +3 -9
- package/dist/src/semantics/refunds.js +6 -192
- package/dist/src/semantics/setup_intents.d.ts +3 -0
- package/dist/src/semantics/{setup-intents.js → setup_intents.js} +10 -53
- package/dist/src/semantics/shared.d.ts +822 -47
- package/dist/src/semantics/shared.js +3044 -78
- package/dist/src/semantics/states.d.ts +531 -0
- package/dist/src/semantics/states.js +852 -0
- package/dist/src/semantics/subscription_items.d.ts +5 -0
- package/dist/src/semantics/subscription_items.js +55 -0
- package/dist/src/semantics/subscription_schedules.d.ts +4 -0
- package/dist/src/semantics/subscription_schedules.js +60 -0
- package/dist/src/semantics/subscriptions.d.ts +7 -11
- package/dist/src/semantics/subscriptions.js +44 -415
- package/dist/src/semantics/test_helpers.d.ts +6 -0
- package/dist/src/semantics/{test-clocks.js → test_helpers.js} +14 -40
- package/dist/src/semantics/transfers.d.ts +2 -2
- package/dist/src/semantics/transfers.js +6 -101
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +94 -0
- package/package.json +10 -20
- package/spec/SOURCE.md +14 -0
- package/spec/fixtures3.json.gz +0 -0
- package/spec/openapi.json.gz +0 -0
- package/spec/patches.json +34 -0
- package/spec/sources.json +378 -0
- package/src/cli.ts +12 -26
- package/src/engine/after-payment.ts +31 -0
- package/src/engine/apps-secrets.ts +4 -0
- package/src/engine/balance.ts +33 -0
- package/src/engine/billing.ts +16 -0
- package/src/engine/charges.ts +19 -0
- package/src/engine/checkout.ts +40 -0
- package/src/engine/common.ts +47 -0
- package/src/engine/connect-settings.ts +23 -0
- package/src/engine/connect.ts +184 -0
- package/src/engine/coupons.ts +5 -0
- package/src/engine/credit-notes.ts +6 -0
- package/src/engine/customers.ts +35 -0
- package/src/engine/display.ts +19 -0
- package/src/engine/disputes.ts +9 -0
- package/src/engine/entitlements.ts +5 -0
- package/src/engine/ephemeral-keys.ts +3 -0
- package/src/engine/files.ts +41 -0
- package/src/engine/front.ts +31 -0
- package/src/engine/invoices.ts +71 -0
- package/src/engine/issuing.ts +61 -0
- package/src/engine/ledger.ts +50 -0
- package/src/engine/oauth.ts +19 -0
- package/src/engine/onboarding.ts +54 -0
- package/src/{stripe-params.ts → engine/params.ts} +8 -56
- package/src/engine/payment-intents.ts +33 -0
- package/src/engine/payment-links.ts +6 -0
- package/src/engine/payment-methods.ts +25 -0
- package/src/engine/plans.ts +42 -0
- package/src/engine/platform.ts +47 -0
- package/src/engine/products.ts +3 -0
- package/src/engine/radar.ts +6 -0
- package/src/engine/refunds.ts +29 -0
- package/src/engine/renewals.ts +73 -0
- package/src/engine/setup-intents.ts +5 -0
- package/src/{stripe-twin.ts → engine/stripe.ts} +28 -323
- package/src/engine/subscription-schedules.ts +10 -0
- package/src/engine/subscriptions.ts +40 -0
- package/src/engine/tax.ts +39 -0
- package/src/engine/terminal.ts +23 -0
- package/src/engine/test-clocks.ts +11 -0
- package/src/engine/tokens.ts +22 -0
- package/src/engine/transfers.ts +23 -0
- package/src/engine/treasury.ts +47 -0
- package/src/{stripe-version.ts → engine/version.ts} +4 -3
- package/src/engine/webhook-endpoints.ts +14 -0
- package/src/engine/webhooks.ts +72 -0
- package/src/fetch.ts +27 -0
- package/src/generated/surface.gen.json +1 -1
- package/src/generated/ui.gen.json +1 -1
- package/src/index.ts +8 -116
- package/src/manifest.ts +234 -786
- package/src/screens/{portal.tsx → billing-portal.tsx} +32 -37
- package/src/screens/checkout.tsx +33 -95
- package/src/screens/connect-oauth.tsx +64 -88
- package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +38 -82
- package/src/screens/dashboard.tsx +198 -0
- package/src/screens/shared.tsx +84 -0
- package/src/screens/stripe-js.ts +170 -0
- package/src/semantics/account_links.ts +21 -0
- package/src/semantics/accounts.ts +43 -0
- package/src/semantics/{apps-secrets.ts → apps.ts} +17 -32
- package/src/semantics/around.ts +20 -0
- package/src/semantics/balance.ts +6 -207
- package/src/semantics/balance_transactions.ts +20 -0
- package/src/semantics/billing_portal.ts +51 -0
- package/src/semantics/charges.ts +12 -211
- package/src/semantics/checkout.ts +13 -268
- package/src/semantics/clock.ts +26 -0
- package/src/semantics/coupons.ts +5 -67
- package/src/semantics/customers.ts +29 -392
- package/src/semantics/disputes.ts +9 -59
- package/src/semantics/doors.ts +80 -0
- package/src/semantics/entitlements.ts +9 -56
- package/src/semantics/events.ts +44 -0
- package/src/semantics/index.ts +111 -0
- package/src/semantics/invoice_payments.ts +18 -0
- package/src/semantics/invoiceitems.ts +59 -0
- package/src/semantics/invoices.ts +109 -443
- package/src/semantics/payment_intents.ts +83 -0
- package/src/semantics/payment_methods.ts +43 -0
- package/src/semantics/payouts.ts +23 -0
- package/src/semantics/prices.ts +42 -0
- package/src/semantics/products.ts +18 -142
- package/src/semantics/promotion_codes.ts +39 -0
- package/src/semantics/radar.ts +8 -77
- package/src/semantics/refunds.ts +9 -212
- package/src/semantics/setup_intents.ts +45 -0
- package/src/semantics/shared.ts +3092 -106
- package/src/semantics/states.ts +883 -0
- package/src/semantics/subscription_items.ts +54 -0
- package/src/semantics/subscription_schedules.ts +66 -0
- package/src/semantics/subscriptions.ts +49 -432
- package/src/semantics/{test-clocks.ts → test_helpers.ts} +23 -47
- package/src/semantics/transfers.ts +11 -131
- package/src/server.ts +8 -0
- package/client/dashboard-api.ts +0 -286
- package/client/stripe-mirror.css +0 -277
- package/client/stripe-mirror.tsx +0 -1559
- package/dist/client/dashboard-api.d.ts +0 -107
- package/dist/client/dashboard-api.js +0 -238
- package/dist/client/dashboard-api.ts +0 -286
- package/dist/client/stripe-mirror.bundle.js +0 -236
- package/dist/client/stripe-mirror.css +0 -277
- package/dist/client/stripe-mirror.d.ts +0 -134
- package/dist/client/stripe-mirror.js +0 -859
- package/dist/client/stripe-mirror.tsx +0 -1559
- package/dist/src/screens/connect-settings.js +0 -103
- package/dist/src/screens/consent-skin.d.ts +0 -4
- package/dist/src/screens/consent-skin.js +0 -18
- package/dist/src/screens/financial-connections.d.ts +0 -5
- package/dist/src/screens/financial-connections.js +0 -90
- package/dist/src/screens/identity.d.ts +0 -5
- package/dist/src/screens/identity.js +0 -86
- package/dist/src/screens/onboarding.d.ts +0 -13
- package/dist/src/screens/portal.d.ts +0 -5
- package/dist/src/screens/public-details.d.ts +0 -5
- package/dist/src/screens/public-details.js +0 -90
- package/dist/src/semantics/after-payment.d.ts +0 -22
- package/dist/src/semantics/after-payment.js +0 -99
- package/dist/src/semantics/apps-secrets.d.ts +0 -2
- package/dist/src/semantics/billing.d.ts +0 -2
- package/dist/src/semantics/billing.js +0 -220
- package/dist/src/semantics/connect.d.ts +0 -5
- package/dist/src/semantics/connect.js +0 -493
- package/dist/src/semantics/credit-notes.d.ts +0 -2
- package/dist/src/semantics/credit-notes.js +0 -172
- package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
- package/dist/src/semantics/ephemeral-keys.js +0 -34
- package/dist/src/semantics/files.d.ts +0 -2
- package/dist/src/semantics/files.js +0 -125
- package/dist/src/semantics/issuing.d.ts +0 -13
- package/dist/src/semantics/issuing.js +0 -575
- package/dist/src/semantics/ledger.d.ts +0 -59
- package/dist/src/semantics/ledger.js +0 -200
- package/dist/src/semantics/payment-intents.d.ts +0 -18
- package/dist/src/semantics/payment-intents.js +0 -452
- package/dist/src/semantics/payment-links.d.ts +0 -2
- package/dist/src/semantics/payment-links.js +0 -133
- package/dist/src/semantics/payment-methods.d.ts +0 -20
- package/dist/src/semantics/payment-methods.js +0 -140
- package/dist/src/semantics/plans.d.ts +0 -5
- package/dist/src/semantics/plans.js +0 -121
- package/dist/src/semantics/platform.d.ts +0 -9
- package/dist/src/semantics/platform.js +0 -206
- package/dist/src/semantics/renewals.d.ts +0 -47
- package/dist/src/semantics/renewals.js +0 -281
- package/dist/src/semantics/setup-intents.d.ts +0 -2
- package/dist/src/semantics/subscription-schedules.d.ts +0 -2
- package/dist/src/semantics/subscription-schedules.js +0 -119
- package/dist/src/semantics/tax.d.ts +0 -2
- package/dist/src/semantics/tax.js +0 -197
- package/dist/src/semantics/terminal.d.ts +0 -5
- package/dist/src/semantics/terminal.js +0 -182
- package/dist/src/semantics/test-clocks.d.ts +0 -6
- package/dist/src/semantics/tokens.d.ts +0 -4
- package/dist/src/semantics/tokens.js +0 -44
- package/dist/src/semantics/treasury.d.ts +0 -2
- package/dist/src/semantics/treasury.js +0 -377
- package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
- package/dist/src/semantics/webhook-endpoints.js +0 -85
- package/dist/src/stripe-budget.d.ts +0 -55
- package/dist/src/stripe-budget.js +0 -155
- package/dist/src/stripe-capabilities.d.ts +0 -3
- package/dist/src/stripe-capabilities.js +0 -5836
- package/dist/src/stripe-conformance.d.ts +0 -43
- package/dist/src/stripe-conformance.js +0 -105
- package/dist/src/stripe-connector.d.ts +0 -161
- package/dist/src/stripe-connector.js +0 -414
- package/dist/src/stripe-emit.d.ts +0 -2
- package/dist/src/stripe-emit.js +0 -145
- package/dist/src/stripe-events.d.ts +0 -93
- package/dist/src/stripe-events.js +0 -392
- package/dist/src/stripe-js.d.ts +0 -4
- package/dist/src/stripe-js.js +0 -70
- package/dist/src/stripe-mirror-ui.d.ts +0 -15
- package/dist/src/stripe-mirror-ui.js +0 -87
- package/dist/src/stripe-perform-harness.d.ts +0 -9
- package/dist/src/stripe-perform-harness.js +0 -26
- package/dist/src/stripe-server.d.ts +0 -33
- package/dist/src/stripe-server.js +0 -429
- package/dist/src/stripe-shared.d.ts +0 -109
- package/dist/src/stripe-shared.js +0 -276
- package/dist/src/stripe-ui-conformance.d.ts +0 -5
- package/dist/src/stripe-ui-conformance.js +0 -79
- package/dist/src/stripe-ui-structure.d.ts +0 -3
- package/dist/src/stripe-ui-structure.js +0 -168
- package/dist/test-fixtures/stripe-known-deviations.json +0 -110
- package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
- package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
- package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
- package/dist/test-fixtures/stripe-schemas.json +0 -3813
- package/src/screens/connect-settings.tsx +0 -121
- package/src/screens/consent-skin.ts +0 -20
- package/src/screens/financial-connections.tsx +0 -101
- package/src/screens/identity.tsx +0 -96
- package/src/screens/public-details.tsx +0 -105
- package/src/semantics/after-payment.ts +0 -118
- package/src/semantics/billing.ts +0 -216
- package/src/semantics/connect.ts +0 -487
- package/src/semantics/credit-notes.ts +0 -168
- package/src/semantics/ephemeral-keys.ts +0 -34
- package/src/semantics/files.ts +0 -143
- package/src/semantics/issuing.ts +0 -590
- package/src/semantics/ledger.ts +0 -253
- package/src/semantics/payment-intents.ts +0 -463
- package/src/semantics/payment-links.ts +0 -148
- package/src/semantics/payment-methods.ts +0 -145
- package/src/semantics/plans.ts +0 -131
- package/src/semantics/platform.ts +0 -220
- package/src/semantics/renewals.ts +0 -279
- package/src/semantics/setup-intents.ts +0 -87
- package/src/semantics/subscription-schedules.ts +0 -129
- package/src/semantics/tax.ts +0 -220
- package/src/semantics/terminal.ts +0 -195
- package/src/semantics/tokens.ts +0 -52
- package/src/semantics/treasury.ts +0 -383
- package/src/semantics/webhook-endpoints.ts +0 -87
- package/src/stripe-budget.ts +0 -181
- package/src/stripe-capabilities.ts +0 -5651
- package/src/stripe-conformance.ts +0 -124
- package/src/stripe-connector.ts +0 -462
- package/src/stripe-emit.ts +0 -157
- package/src/stripe-events.ts +0 -434
- package/src/stripe-js.ts +0 -70
- package/src/stripe-mirror-ui.ts +0 -90
- package/src/stripe-perform-harness.ts +0 -29
- package/src/stripe-server.ts +0 -393
- package/src/stripe-shared.ts +0 -297
- package/src/stripe-ui-conformance.ts +0 -88
- package/src/stripe-ui-structure.ts +0 -182
- package/test-fixtures/stripe-known-deviations.json +0 -110
- package/test-fixtures/stripe-openapi-operations.json +0 -4717
- package/test-fixtures/stripe-schemas.json +0 -3813
- /package/dist/src/{screens → engine}/industries.d.ts +0 -0
- /package/dist/src/{screens → engine}/industries.js +0 -0
- /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
- /package/dist/src/{semantics → engine}/test-cards.js +0 -0
- /package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -0
- /package/src/{screens → engine}/industries.ts +0 -0
- /package/src/{semantics → engine}/test-cards.ts +0 -0
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
// Stripe
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
import { projectResources } from '@volter/world-core';
|
|
13
|
-
import { createStripeTwinFetch } from "./stripe-server.js";
|
|
14
|
-
import { emitStripeEvent, eventTypeFor } from "./stripe-events.js";
|
|
15
|
-
import { SERVED_VERSION } from "./stripe-version.js";
|
|
16
|
-
import { planOf } from "./semantics/plans.js";
|
|
17
|
-
import { platformAccountDefault } from "./semantics/connect.js";
|
|
18
|
-
import { OAUTH_CONNECTIONS } from "./stripe-shared.js";
|
|
19
|
-
const SERVICE = 'stripe';
|
|
20
|
-
// The Stripe API version a request that pins none is served in: the vendored spec's (stripe-version.ts renders
|
|
1
|
+
// Stripe's own computation that its handlers share (docs/contributing/architecture.md, "Pack layout": the engine): money
|
|
2
|
+
// and its declines, 3-D Secure and micro-deposits, the list page and the search grammar, a subscription's items, billing
|
|
3
|
+
// intervals and discounts, Issuing's spending controls, a payment method's sub-object, a Connect account's settings and a
|
|
4
|
+
// Checkout Session's line items. None of it reads or writes state: a caller hands it what it looked up (FindStored).
|
|
5
|
+
import { ownFields } from '@volter/world-core';
|
|
6
|
+
import { SERVED_VERSION } from "./version.js";
|
|
7
|
+
/** Stripe's error body: an invalid_request_error with the message, and the code when there is one. */
|
|
8
|
+
export function err(message, status = 404, code) {
|
|
9
|
+
return { status, body: { error: { type: 'invalid_request_error', message, ...(code ? { code } : {}) } } };
|
|
10
|
+
}
|
|
11
|
+
// The Stripe API version a request that pins none is served in: the vendored spec's (./version.ts renders
|
|
21
12
|
// every answer in it). A request may override it via the `Stripe-Version` header (apiVersion);
|
|
22
13
|
// the value is echoed onto every event the request produces, exactly like real Stripe,
|
|
23
14
|
// whose stored Event.api_version reflects the version in force when the event was created.
|
|
@@ -28,61 +19,6 @@ const API_VERSION_RE = /^\d{4}-\d{2}-\d{2}(\.[a-z_]+)?$/;
|
|
|
28
19
|
export function isValidApiVersion(v) {
|
|
29
20
|
return API_VERSION_RE.test(v);
|
|
30
21
|
}
|
|
31
|
-
// resource type → id prefix (Stripe's conventions).
|
|
32
|
-
const PREFIX = {
|
|
33
|
-
charge: 'ch', customer: 'cus', payment_intent: 'pi', setup_intent: 'seti', payment_method: 'pm',
|
|
34
|
-
subscription: 'sub', price: 'price', product: 'prod', invoice: 'in', invoiceitem: 'ii',
|
|
35
|
-
refund: 're', verification_session: 'vs', ephemeral_key: 'ephkey', file_link: 'link',
|
|
36
|
-
dispute: 'dp', payout: 'po', balance_transaction: 'txn', event: 'evt',
|
|
37
|
-
checkout_session: 'cs', billing_portal_session: 'bps', billing_portal_configuration: 'bpc',
|
|
38
|
-
account: 'acct', transfer: 'tr',
|
|
39
|
-
tax_rate: 'txr', tax_calculation: 'taxcalc', tax_registration: 'taxreg',
|
|
40
|
-
credit_note: 'cn', tax_id: 'txi', customer_balance_transaction: 'cbtxn',
|
|
41
|
-
coupon: 'coupon', promotion_code: 'promo', payment_link: 'plink', quote: 'qt',
|
|
42
|
-
webhook_endpoint: 'we',
|
|
43
|
-
subscription_schedule: 'sub_sched', billing_meter: 'mtr', billing_meter_event: 'mtr_evt',
|
|
44
|
-
usage_record: 'mbur', test_clock: 'clock',
|
|
45
|
-
token: 'tok', mandate: 'mandate', application_fee: 'fee', fee_refund: 'fr',
|
|
46
|
-
transfer_reversal: 'trr', account_link: 'acctlink', person: 'person',
|
|
47
|
-
external_account: 'ba', file: 'file',
|
|
48
|
-
subscription_item: 'si', tax_transaction: 'tax', radar_review: 'prv',
|
|
49
|
-
radar_value_list: 'rsl', radar_value_list_item: 'rsli', radar_rule: 'rule',
|
|
50
|
-
// Issuing family (vendor-faithful Stripe id prefixes).
|
|
51
|
-
issuing_cardholder: 'ich', issuing_card: 'ic', issuing_authorization: 'iauth',
|
|
52
|
-
issuing_transaction: 'ipi', issuing_dispute: 'idp',
|
|
53
|
-
// Terminal family.
|
|
54
|
-
terminal_location: 'tml', terminal_reader: 'tmr', terminal_configuration: 'tmc',
|
|
55
|
-
// Top-ups, identity reports, reporting runs.
|
|
56
|
-
topup: 'tu', verification_report: 'vr', report_run: 'frr',
|
|
57
|
-
// Customer cash balance ledger + legacy sources.
|
|
58
|
-
cash_balance_transaction: 'ccsbtxn', source: 'src',
|
|
59
|
-
// Billing: prepaid credit grants + usage alerts.
|
|
60
|
-
credit_grant: 'credgr', billing_alert: 'alert',
|
|
61
|
-
// Entitlements: account-level features + per-customer active entitlements.
|
|
62
|
-
entitlements_feature: 'feat', active_entitlement: 'ent',
|
|
63
|
-
// Connect: embedded account sessions + apps secret store.
|
|
64
|
-
account_session: 'accts', apps_secret: 'apmc',
|
|
65
|
-
// Issuing: network tokens + card personalization designs.
|
|
66
|
-
issuing_token: 'iss_tok', personalization_design: 'pd',
|
|
67
|
-
// Treasury: financial accounts + money-movement flows + ledger.
|
|
68
|
-
financial_account: 'fa',
|
|
69
|
-
outbound_payment: 'obp', outbound_transfer: 'obt', inbound_transfer: 'ibt',
|
|
70
|
-
received_credit: 'rc', received_debit: 'rd',
|
|
71
|
-
treasury_transaction: 'trxn', treasury_transaction_entry: 'trxne',
|
|
72
|
-
// Climate (carbon removal): orders. (products/suppliers are a fixed read-only catalog.)
|
|
73
|
-
climate_order: 'climorder',
|
|
74
|
-
// Financial Connections: sessions + linked accounts + account transactions.
|
|
75
|
-
fc_session: 'fcsess', fc_account: 'fca', fc_transaction: 'fctxn',
|
|
76
|
-
// Forwarding (PAN forwarding) requests + Crypto onramp sessions.
|
|
77
|
-
forwarding_request: 'fwdr', onramp_session: 'cos',
|
|
78
|
-
// Entitlements: a product↔feature grant.
|
|
79
|
-
product_feature: 'prodft',
|
|
80
|
-
// Tax settings singleton.
|
|
81
|
-
tax_settings: 'taxset',
|
|
82
|
-
};
|
|
83
|
-
function err(message, status = 404, code) {
|
|
84
|
-
return { status, body: { error: { type: status === 404 ? 'invalid_request_error' : 'invalid_request_error', message, ...(code ? { code } : {}) } } };
|
|
85
|
-
}
|
|
86
22
|
// Fidelity: real Stripe rejects a charge/payment_intent missing or with a non-positive
|
|
87
23
|
// amount, or missing currency, before any state change.
|
|
88
24
|
export function validateMoney(params) {
|
|
@@ -270,19 +206,6 @@ export function cardError(outcome, attach = {}) {
|
|
|
270
206
|
export function nowUnix(occurredAt) {
|
|
271
207
|
return Math.floor((occurredAt ? Date.parse(occurredAt) : 0) / 1000);
|
|
272
208
|
}
|
|
273
|
-
function rows(type, root) {
|
|
274
|
-
return projectResources(SERVICE, root).filter((r) => r.type === type);
|
|
275
|
-
}
|
|
276
|
-
function nextId(type, root) {
|
|
277
|
-
const prefix = PREFIX[type] ?? type;
|
|
278
|
-
let max = 0;
|
|
279
|
-
for (const r of rows(type, root)) {
|
|
280
|
-
const m = new RegExp(`^${prefix}_twin_(\\d+)$`).exec(r.id);
|
|
281
|
-
if (m)
|
|
282
|
-
max = Math.max(max, Number(m[1]));
|
|
283
|
-
}
|
|
284
|
-
return `${prefix}_twin_${max + 1}`;
|
|
285
|
-
}
|
|
286
209
|
// Real Stripe embeds the resource's OWN id inside its client_secret (format
|
|
287
210
|
// `<id>_secret_<random>`) — Stripe.js's confirmPayment/confirmSetup parse the id back
|
|
288
211
|
// out of the client_secret (splitting on `_secret`) to build the same-origin confirm
|
|
@@ -290,25 +213,14 @@ function nextId(type, root) {
|
|
|
290
213
|
// A secret that doesn't carry the real id breaks that round trip: a browser Stripe.js
|
|
291
214
|
// call would try to confirm a resource whose id it invented from the string
|
|
292
215
|
// (`'pi_twin_secret'` → `'pi_twin'`, which was never actually created). Every PI/SI a
|
|
293
|
-
// caller might confirm CLIENT-SIDE (real Stripe.js
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
// stored vendor field literally named `type` is dropped on projection (see actions.ts
|
|
302
|
-
// META). Several Stripe objects (payout.type, balance_transaction.type, event.type,
|
|
303
|
-
// dispute uses `reason` not `type`) DO have a vendor `type`, so the create path stashes
|
|
304
|
-
// it under the reserved key `_stripe_type` (a `_`-prefixed twin-internal field that the
|
|
305
|
-
// conformance gate exempts) and we restore it to `type` here. This keeps the vendor
|
|
306
|
-
// field faithful without touching the kernel discriminator. (price.type stays a declared
|
|
307
|
-
// deviation — its create path predates this and one_time/recurring is derivable.)
|
|
308
|
-
// A few Stripe objects have a DOTTED `object` value that differs from the twin's
|
|
309
|
-
// (identifier-safe) resource type — e.g. type 'checkout_session' emits object
|
|
310
|
-
// 'checkout.session'. Map them on emit so the `object` field is vendor-faithful.
|
|
311
|
-
// (stripe-conformance.ts emitted() mirrors this map.)
|
|
216
|
+
// caller might confirm CLIENT-SIDE (real Stripe.js) must mint a secret this way.
|
|
217
|
+
/** An intent's client secret: its id, `_secret_`, and a secret the World holds for it (ctx.secret, passed in), so no one
|
|
218
|
+
* derives it from the intent's id; Stripe.js confirms an intent with it and the publishable key. */
|
|
219
|
+
export function mintClientSecret(id, secret) {
|
|
220
|
+
return `${id}_secret_${secret.replace(/[^A-Za-z0-9]/g, '').slice(0, 24)}`;
|
|
221
|
+
}
|
|
222
|
+
// A few Stripe objects have a DOTTED `object` value that differs from the twin's (identifier-safe) resource type: type
|
|
223
|
+
// 'checkout_session' is object 'checkout.session'.
|
|
312
224
|
export const OBJECT_NAME = {
|
|
313
225
|
checkout_session: 'checkout.session',
|
|
314
226
|
billing_portal_session: 'billing_portal.session',
|
|
@@ -369,18 +281,11 @@ export const OBJECT_NAME = {
|
|
|
369
281
|
// Forwarding + Crypto onramp.
|
|
370
282
|
forwarding_request: 'forwarding.request', onramp_session: 'crypto.onramp_session',
|
|
371
283
|
};
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
// projection, no drift. Not a public API for consumers.
|
|
284
|
+
/** A stored row as Stripe answers it: its `object`, its own fields (the vendor's `type` among them, which the tree's
|
|
285
|
+
* shadows: world-core ownFields) without the twin's `_` bookkeeping, and its id. */
|
|
375
286
|
export function view(type, r) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
// subscription) — real Stripe never returns it on the Session, so strip it here.
|
|
379
|
-
const { type: _t, updatedAt: _u, _stripe_type, _subscription_data, ...rest } = r;
|
|
380
|
-
const out = { object: OBJECT_NAME[type] ?? type, ...rest, id: r.id };
|
|
381
|
-
if (_stripe_type !== undefined)
|
|
382
|
-
out.type = _stripe_type;
|
|
383
|
-
return out;
|
|
287
|
+
const own = Object.fromEntries(Object.entries(ownFields(r)).filter(([k]) => !k.startsWith('_') && k !== 'updatedAt'));
|
|
288
|
+
return { object: OBJECT_NAME[type] ?? type, ...own, id: r.id };
|
|
384
289
|
}
|
|
385
290
|
// Real Stripe list pagination. Honors limit (default 10, max 100, min 1),
|
|
386
291
|
// starting_after (cursor: exclude up to & including that id), ending_before
|
|
@@ -414,90 +319,6 @@ export function paginate(items, params) {
|
|
|
414
319
|
const page = items.slice(from, from + limit);
|
|
415
320
|
return { page, hasMore: from + limit < items.length };
|
|
416
321
|
}
|
|
417
|
-
async function writeResource(type, id, fields, op, root, occurredAt, apiVersion) {
|
|
418
|
-
const { resource } = await applyTwinWrite(SERVICE, { operation: op, subjectType: type, subjectId: id, fields, ...(occurredAt ? { occurredAt } : {}), actor: { kind: 'agent' } }, root);
|
|
419
|
-
const out = view(type, resource);
|
|
420
|
-
await afterStripeWrite(type, op, out, root, occurredAt, apiVersion);
|
|
421
|
-
return out;
|
|
422
|
-
}
|
|
423
|
-
/** What follows every stored Stripe write: the webhook for the state change and the stored Event
|
|
424
|
-
* the Events API lists. The derived pack's write hook (manifest.ts) is this same function. */
|
|
425
|
-
export async function afterStripeWrite(type, op, out, root, occurredAt, apiVersion, stripeAccount) {
|
|
426
|
-
// R17: fire the Stripe event/webhook for this state change (no-op if none registered). An event is a connected
|
|
427
|
-
// account's when its resource lives in one (a request made as it, the Stripe-Account header) or is a connected
|
|
428
|
-
// account itself (its account.updated): docs.stripe.com/connect/webhooks, "Connected accounts" scope.
|
|
429
|
-
// A write with no header is still a connected account's when the row it wrote is kept on that account's books (a
|
|
430
|
-
// payout or ledger entry's `_account`: an automatic payout time makes for it, semantics/balance.ts).
|
|
431
|
-
const account = stripeAccount ?? (type === 'account' && typeof out.id === 'string' && out.id !== PLATFORM_ACCOUNT_ID ? out.id : undefined) ?? ownerOf(type, out.id, root);
|
|
432
|
-
// a plan is stored as the recurring price it is; its own events carry the plan object (semantics/plans.ts)
|
|
433
|
-
const object = type === 'price' && op.startsWith('plan.') ? planOf(out) : out;
|
|
434
|
-
// events.full_types: the Stripe `event` envelope for this state change is also stored, so it appears in GET
|
|
435
|
-
// /v1/events (independent of webhook registration), exactly like real Stripe's stored Events API. Skip when the op
|
|
436
|
-
// has no mapped event type, and never for event/_idempotency writes themselves (no recursion / no meta-events). The
|
|
437
|
-
// event's id is minted once and is the delivered webhook's id and the stored event's alike: one event, one id, which
|
|
438
|
-
// a consumer deduplicates by and retrieves by.
|
|
439
|
-
const eventType = type !== 'event' && type !== IDEMPOTENCY_TYPE ? eventTypeFor(op) : null;
|
|
440
|
-
const id = eventType ? nextStripeEventId(root) : undefined;
|
|
441
|
-
// stored before it is delivered: a consumer that looks its webhook's event up finds it
|
|
442
|
-
if (eventType)
|
|
443
|
-
await persistStripeEvent(eventType, object, root, occurredAt, apiVersion, account, id);
|
|
444
|
-
// a connected account whose OAuth connection was revoked "can't be accessed by your platform" (docs.stripe.com/connect/
|
|
445
|
-
// oauth-reference): its events (a payout time makes, a renewal) are its own and no longer reach the platform's Connect
|
|
446
|
-
// endpoints, except the account.application.deauthorized that says so (screens/connect-oauth.tsx)
|
|
447
|
-
if (account && eventType !== 'account.application.deauthorized' && rows(OAUTH_CONNECTIONS, root).some((c) => c.id === account && c.revoked === true))
|
|
448
|
-
return;
|
|
449
|
-
await emitStripeEvent(op, object, { occurredAt: occurredAt ?? '1970-01-01T00:00:00.000Z', endpoints: webhookTargets(root), ...(account ? { account } : {}), ...(id ? { id } : {}) });
|
|
450
|
-
}
|
|
451
|
-
/** Event numbers taken in this process, per root, before their events are stored: two writes whose events overlap
|
|
452
|
-
* (a webhook handler calling back in, concurrent requests) never take the same number. */
|
|
453
|
-
const takenEventNumbers = new Map();
|
|
454
|
-
/** The id the World's next event takes: its place in the World's events, so it is deterministic and never repeats
|
|
455
|
-
* within a World (a Balance has no id of its own, so nothing about the object can tell two events apart). The number
|
|
456
|
-
* is taken synchronously — the count of stored events, or the last number taken, whichever is higher. */
|
|
457
|
-
export function nextStripeEventId(root) {
|
|
458
|
-
const key = root ?? '';
|
|
459
|
-
const n = Math.max(rows('event', root).length, takenEventNumbers.get(key) ?? 0) + 1;
|
|
460
|
-
takenEventNumbers.set(key, n);
|
|
461
|
-
return `evt_twin_${n}`;
|
|
462
|
-
}
|
|
463
|
-
/** The connected account whose books a stored row is kept on (its `_account`), if any. */
|
|
464
|
-
function ownerOf(type, id, root) {
|
|
465
|
-
if (typeof id !== 'string')
|
|
466
|
-
return undefined;
|
|
467
|
-
const owner = rows(type, root).find((r) => r.id === id)?._account;
|
|
468
|
-
return typeof owner === 'string' ? owner : undefined;
|
|
469
|
-
}
|
|
470
|
-
// Persist a Stripe `event` resource (object 'event') for a state change into the action
|
|
471
|
-
// log so the Events API (GET /v1/events) lists/retrieves it. Deterministic id derived
|
|
472
|
-
// from the per-root event count; data.object carries the resource snapshot. Written via
|
|
473
|
-
// applyTwinWrite directly (NOT writeResource) to avoid re-emitting an event for the event.
|
|
474
|
-
export async function persistStripeEvent(eventType, resource, root, occurredAt, apiVersion, account, id) {
|
|
475
|
-
const eventId = id ?? nextStripeEventId(root);
|
|
476
|
-
const fields = {
|
|
477
|
-
object: 'event', _stripe_type: eventType, created: nowUnix(occurredAt), livemode: false,
|
|
478
|
-
pending_webhooks: 0, api_version: apiVersion && isValidApiVersion(apiVersion) ? apiVersion : TWIN_API_VERSION,
|
|
479
|
-
request: { id: null, idempotency_key: null },
|
|
480
|
-
data: { object: resource },
|
|
481
|
-
// a connected account's event names it, and is listed to requests made as it (semantics/webhook-endpoints.ts)
|
|
482
|
-
...(account ? { account } : {}),
|
|
483
|
-
};
|
|
484
|
-
await applyTwinWrite(SERVICE, { operation: 'event.record', subjectType: 'event', subjectId: eventId, fields, ...(occurredAt ? { occurredAt } : {}), actor: { kind: 'system' } }, root);
|
|
485
|
-
}
|
|
486
|
-
function getOne(type, id, root) {
|
|
487
|
-
const r = rows(type, root).find((x) => x.id === id);
|
|
488
|
-
return r ? view(type, r) : undefined;
|
|
489
|
-
}
|
|
490
|
-
// Stripe list order: newest first by `created` (or `date` for invoiceitem), ties
|
|
491
|
-
// broken by id descending so the order is stable for cursor pagination.
|
|
492
|
-
/** The World's live webhook endpoints, from its tree: delivery survives a restart and belongs to
|
|
493
|
-
* this World alone. A disabled or deleted endpoint receives nothing, like the vendor. */
|
|
494
|
-
function webhookTargets(root) {
|
|
495
|
-
// `connect` is a create parameter the endpoint object does not answer, so it is read off the stored row
|
|
496
|
-
return rows('webhook_endpoint', root)
|
|
497
|
-
.map((r) => ({ w: view('webhook_endpoint', r), connect: asBool(r.connect) }))
|
|
498
|
-
.filter(({ w }) => !w.deleted && w.status !== 'disabled' && typeof w.url === 'string')
|
|
499
|
-
.map(({ w, connect }) => ({ url: String(w.url), ...(typeof w.secret === 'string' ? { secret: w.secret } : {}), ...(Array.isArray(w.enabled_events) ? { enabledEvents: w.enabled_events.map(String) } : {}), connect }));
|
|
500
|
-
}
|
|
501
322
|
// Stripe's `active=true|false` filters arrive as strings/booleans; normalize.
|
|
502
323
|
export function asBool(v) {
|
|
503
324
|
return v === true || v === 'true' || v === 1 || v === '1';
|
|
@@ -748,35 +569,15 @@ export function resolveTrial(params, at) {
|
|
|
748
569
|
}
|
|
749
570
|
return undefined;
|
|
750
571
|
}
|
|
751
|
-
// Create a resource from form params, stamping object + id + created + the given
|
|
752
|
-
// defaults. Only real Stripe field names are emitted (conformance-checked).
|
|
753
|
-
// A vendor `type` field (a price's one_time or recurring, a payout's bank_account) always collides with the kernel's
|
|
754
|
-
// row type, so it is stashed under `_stripe_type` and restored by view().
|
|
755
|
-
export function stashVendorType(_type, fields) {
|
|
756
|
-
if (!('type' in fields))
|
|
757
|
-
return fields;
|
|
758
|
-
const { type: vt, ...rest } = fields;
|
|
759
|
-
return { ...rest, _stripe_type: vt };
|
|
760
|
-
}
|
|
761
|
-
async function create(type, params, defaults, req, opts = {}) {
|
|
762
|
-
// honor a caller-provided id (seeding uses the catalog's real prod_*/price_* ids);
|
|
763
|
-
// otherwise assign one. The id is identity, not a stored field.
|
|
764
|
-
const { id: providedId, ...rest } = params;
|
|
765
|
-
const id = typeof providedId === 'string' && providedId ? providedId : nextId(type, req.root);
|
|
766
|
-
// Most Stripe objects stamp `created`; a few (invoiceitem) use a differently-named
|
|
767
|
-
// timestamp instead (`date`) and have NO `created` field — honor that, don't fabricate.
|
|
768
|
-
const fields = stashVendorType(type, { object: OBJECT_NAME[type] ?? type, [opts.timeField ?? 'created']: nowUnix(req.occurredAt), ...defaults, ...rest });
|
|
769
|
-
return { status: 200, body: await writeResource(type, id, fields, `${type}.create`, req.root, req.occurredAt, req.apiVersion) };
|
|
770
|
-
}
|
|
771
572
|
// ── ISSUING helpers: spending controls, real-time-auth shapes ─────────────────────────
|
|
772
573
|
// Authorization.card is the FULL Card object in every vendor egress (API responses and
|
|
773
574
|
// webhook payloads) — it is not expandable (stripe@22.3.0 Issuing.Authorization.card:
|
|
774
575
|
// Stripe.Issuing.Card). The twin stores the id internally and embeds at the boundary;
|
|
775
576
|
// cardholder stays an id string (expandable, unexpanded default). Caught live: the
|
|
776
577
|
// issuing-bridge reads event.data.object.card.id and refused every twin presentment.
|
|
777
|
-
export function embedIssuingAuthorizationCard(body,
|
|
578
|
+
export function embedIssuingAuthorizationCard(body, find) {
|
|
778
579
|
if (typeof body.card === 'string') {
|
|
779
|
-
const cardRow =
|
|
580
|
+
const cardRow = find('issuing_card', body.card);
|
|
780
581
|
if (cardRow !== undefined)
|
|
781
582
|
body.card = cardRow;
|
|
782
583
|
}
|
|
@@ -1121,18 +922,6 @@ export function lineItemEntries(params) {
|
|
|
1121
922
|
const li = params.line_items;
|
|
1122
923
|
return Array.isArray(li) ? li.filter((x) => x && typeof x === 'object') : [];
|
|
1123
924
|
}
|
|
1124
|
-
// ---- IDEMPOTENCY KEYS (vendor-faithful) ----
|
|
1125
|
-
// Real Stripe honors the `Idempotency-Key` header on POST: the first request with a
|
|
1126
|
-
// key executes and the (status + body) response is stored against the key; a replay
|
|
1127
|
-
// with the SAME key returns the SAME stored response WITHOUT re-applying the write.
|
|
1128
|
-
// We persist the stored response as an `_idempotency` resource in the action log
|
|
1129
|
-
// (per-root, so a fork has its own keyspace). `_idempotency` is a twin-internal type
|
|
1130
|
-
// (never served as a Stripe object), so it does not affect spec conformance.
|
|
1131
|
-
//
|
|
1132
|
-
// Note: real Stripe only persists idempotency for responses it considers "completed"
|
|
1133
|
-
// (2xx and most 4xx, including card 402s) and scopes the key to the account; here we
|
|
1134
|
-
// store every executed POST response (success and error alike), keyed per-root.
|
|
1135
|
-
const IDEMPOTENCY_TYPE = '_idempotency';
|
|
1136
925
|
// ── THE MONEY MODEL: a charge and the refunds taken out of it ──────────────────────────
|
|
1137
926
|
//
|
|
1138
927
|
// The rule this section exists to hold: A FACT RECORDED ON ONE MONEY OBJECT IS VISIBLE FROM
|
|
@@ -1154,79 +943,5 @@ export function chargeDefaults(chargeId, amount, captured, occurredAt) {
|
|
|
1154
943
|
billing_details: { address: null, email: null, name: null, phone: null }, livemode: false,
|
|
1155
944
|
};
|
|
1156
945
|
}
|
|
1157
|
-
/**
|
|
1158
|
-
* Public entry: honors the Idempotency-Key (replay → stored response, no re-write)
|
|
1159
|
-
* then delegates to the router. Only POSTs are idempotent (matches Stripe; GET/DELETE
|
|
1160
|
-
* pass straight through). A read-only twin never stores (it cannot write).
|
|
1161
|
-
*/
|
|
1162
|
-
/** Stripe's API as one call: the request goes through the pack's own dispatch (the derived dispatch over
|
|
1163
|
-
* its semantics, its derived core and the hand-written routes below), so a caller that holds no
|
|
1164
|
-
* HTTP server reaches exactly what an SDK does. `occurredAt` pins the World instant. */
|
|
1165
|
-
export async function handleStripeTwinRequest(req) {
|
|
1166
|
-
const twin = createStripeTwinFetch({ ...(req.root !== undefined ? { root: req.root } : {}), readOnly: req.readOnly ?? false, ...(req.occurredAt ? { clock: () => req.occurredAt } : {}) });
|
|
1167
|
-
const method = req.method.toUpperCase();
|
|
1168
|
-
const headers = { 'content-type': 'application/x-www-form-urlencoded' };
|
|
1169
|
-
if (req.idempotencyKey)
|
|
1170
|
-
headers['idempotency-key'] = req.idempotencyKey;
|
|
1171
|
-
if (req.apiVersion !== undefined)
|
|
1172
|
-
headers['stripe-version'] = req.apiVersion;
|
|
1173
|
-
if (req.stripeAccount)
|
|
1174
|
-
headers['stripe-account'] = req.stripeAccount;
|
|
1175
|
-
// a GET carries its parameters in the query; a caller that handed them as a body keeps them
|
|
1176
|
-
let path = req.path.startsWith('/') ? req.path : `/${req.path}`;
|
|
1177
|
-
if ((method === 'GET' || method === 'HEAD') && req.body)
|
|
1178
|
-
path += (path.includes('?') ? '&' : '?') + req.body;
|
|
1179
|
-
const response = await twin(new Request(`http://stripe.test${path}`, { method, headers, ...(method !== 'GET' && method !== 'HEAD' && req.body ? { body: req.body } : {}) }));
|
|
1180
|
-
const text = await response.text();
|
|
1181
|
-
return { status: response.status, body: text ? JSON.parse(text) : null };
|
|
1182
|
-
}
|
|
1183
|
-
/**
|
|
1184
|
-
* The twin's doors: what stands in for an act Stripe's API does not have, each under `/_twin/`. The
|
|
1185
|
-
* platform's own account settings (its payout schedule) change on Stripe's Dashboard, which has no API:
|
|
1186
|
-
* POST /_twin/account stands in for that page. Answers nothing for any other path.
|
|
1187
|
-
*/
|
|
1188
|
-
export async function handleStripeDoor(req, params) {
|
|
1189
|
-
const method = req.method.toUpperCase();
|
|
1190
|
-
const path = (req.path.split('?')[0] ?? '/').replace(/\/+$/, '') || '/';
|
|
1191
|
-
const seg = path.replace(/^\/+/, '').split('/');
|
|
1192
|
-
if (seg[0] !== '_twin')
|
|
1193
|
-
return undefined;
|
|
1194
|
-
if (req.readOnly)
|
|
1195
|
-
return err('twin is read-only; omit readOnly to accept writes', 405);
|
|
1196
|
-
if (path === '/_twin/account' && method === 'POST') {
|
|
1197
|
-
const ex = getOne('account', PLATFORM_ACCOUNT_ID, req.root);
|
|
1198
|
-
const { type: _t, settings: rawSettings, business_profile: rawProfile, ...rest } = params;
|
|
1199
|
-
// the platform's account is Stripe's default until the page first changes it (semantics/connect.ts, the same
|
|
1200
|
-
// default GET /v1/account answers and the Public details page stores)
|
|
1201
|
-
const fields = {
|
|
1202
|
-
...(ex ? {} : (({ id: _id, ...base }) => base)(platformAccountDefault())),
|
|
1203
|
-
...rest,
|
|
1204
|
-
settings: accountSettings(rawSettings, ex?.settings),
|
|
1205
|
-
// a hash is merged into what the account holds, as an update merges it (the name the Public details page saved stays)
|
|
1206
|
-
...(rawProfile && typeof rawProfile === 'object' ? { business_profile: { ...(ex?.business_profile ?? {}), ...rawProfile } } : {}),
|
|
1207
|
-
};
|
|
1208
|
-
return { status: 200, body: await writeResource('account', PLATFORM_ACCOUNT_ID, stashVendorType('account', fields), 'account.update', req.root, req.occurredAt) };
|
|
1209
|
-
}
|
|
1210
|
-
// Issuing network tokens are minted by the card network when a cardholder adds the card to a
|
|
1211
|
-
// phone's wallet (docs.stripe.com/issuing/cards/digital-wallets): there is no API create, and the
|
|
1212
|
-
// act happens in the phone's wallet app, not on a Stripe page. POST /_twin/issuing/cards/:card/wallets
|
|
1213
|
-
// stands in for that act ({wallet_provider, network}); the API reads the token and moves its status.
|
|
1214
|
-
// Where the documentation stops and the twin decides: the network approves at once (the token is active).
|
|
1215
|
-
if (seg[0] === '_twin' && seg[1] === 'issuing' && seg[2] === 'cards' && seg[3] && seg[4] === 'wallets' && seg.length === 5 && method === 'POST') {
|
|
1216
|
-
const card = decodeURIComponent(seg[3]);
|
|
1217
|
-
const c = getOne('issuing_card', card, req.root);
|
|
1218
|
-
if (!c)
|
|
1219
|
-
return err(`No such card: '${card}'`, 400, 'resource_missing');
|
|
1220
|
-
const wallet = typeof params.wallet_provider === 'string' && ['apple_pay', 'google_pay', 'samsung_pay'].includes(params.wallet_provider)
|
|
1221
|
-
? params.wallet_provider : 'apple_pay';
|
|
1222
|
-
const network = typeof params.network === 'string' && ['visa', 'mastercard'].includes(params.network) ? params.network : 'visa';
|
|
1223
|
-
const last4 = typeof c.last4 === 'string' ? c.last4 : '0000';
|
|
1224
|
-
return create('issuing_token', { card, cardholder: typeof c.cardholder === 'string' ? c.cardholder : (c.cardholder?.id ?? null) }, {
|
|
1225
|
-
status: 'active', wallet_provider: wallet, network, last4, livemode: false,
|
|
1226
|
-
device_fingerprint: null, network_data: null, network_updated_at: nowUnix(req.occurredAt),
|
|
1227
|
-
}, req);
|
|
1228
|
-
}
|
|
1229
|
-
return undefined;
|
|
1230
|
-
}
|
|
1231
946
|
// collection path segment → resource type, for the generic list of a collection Stripe does not
|
|
1232
947
|
// list at that path (the twin's test clocks, which Stripe lists under /v1/test_helpers).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SS = 'subscription_schedule';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Row } from './common.js';
|
|
2
|
+
export declare const SUB = "subscription";
|
|
3
|
+
/** pause_collection pauses billing (the paused event fires) and clearing it resumes
|
|
4
|
+
* (docs.stripe.com/billing/subscriptions/pause-payment); answers the event, or nothing for a value it does not take. */
|
|
5
|
+
export declare function pauseCollection(pc: unknown, fields: Row): string | undefined;
|
|
6
|
+
/** The longest trial Stripe takes: `trial_end` "Can be at most two years from `billing_cycle_anchor`"
|
|
7
|
+
* (docs.stripe.com/api/subscriptions/update#update_subscription-trial_end); "The trial period must be 730 days (2 years)
|
|
8
|
+
* or less" (docs.stripe.com/billing/subscriptions/trials/free-trials). */
|
|
9
|
+
export declare const MAX_TRIAL: number;
|
|
10
|
+
/** A trial moved to end at `end`, or a new one to `end` on a subscription out of its trial (applyTrialEnd). */
|
|
11
|
+
export declare function movedTrial(sub: Row, fields: Row, end: number, now: number): undefined;
|
|
12
|
+
export declare const ITEM_ATTRIBUTES: Set<string>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const SUB = 'subscription';
|
|
2
|
+
// pause_collection pauses billing (the subscription stays active; the paused event fires) and
|
|
3
|
+
// clearing it resumes; cancel_at_period_end schedules or withdraws a cancel; a coupon replaces the
|
|
4
|
+
// discount and an empty one clears it
|
|
5
|
+
/** pause_collection pauses billing (the paused event fires) and clearing it resumes
|
|
6
|
+
* (docs.stripe.com/billing/subscriptions/pause-payment); answers the event, or nothing for a value it does not take. */
|
|
7
|
+
export function pauseCollection(pc, fields) {
|
|
8
|
+
const isClear = pc === '' || pc === null || (typeof pc === 'object' && pc !== null && Object.keys(pc).length === 0);
|
|
9
|
+
if (isClear) {
|
|
10
|
+
fields.pause_collection = null;
|
|
11
|
+
return 'customer.subscription.resumed';
|
|
12
|
+
}
|
|
13
|
+
if (!pc || typeof pc !== 'object')
|
|
14
|
+
return undefined;
|
|
15
|
+
const p = pc;
|
|
16
|
+
fields.pause_collection = { behavior: typeof p.behavior === 'string' ? p.behavior : 'void', resumes_at: p.resumes_at !== undefined ? Number(p.resumes_at) : null };
|
|
17
|
+
return 'customer.subscription.paused';
|
|
18
|
+
}
|
|
19
|
+
/** The longest trial Stripe takes: `trial_end` "Can be at most two years from `billing_cycle_anchor`"
|
|
20
|
+
* (docs.stripe.com/api/subscriptions/update#update_subscription-trial_end); "The trial period must be 730 days (2 years)
|
|
21
|
+
* or less" (docs.stripe.com/billing/subscriptions/trials/free-trials). */
|
|
22
|
+
export const MAX_TRIAL = 730 * 86400;
|
|
23
|
+
/** A trial moved to end at `end`, or a new one to `end` on a subscription out of its trial (applyTrialEnd). */
|
|
24
|
+
export function movedTrial(sub, fields, end, now) {
|
|
25
|
+
Object.assign(fields, {
|
|
26
|
+
status: 'trialing', trial_end: end, trial_start: sub.trial_start ?? now, billing_cycle_anchor: end,
|
|
27
|
+
current_period_end: end, ...(sub.status !== 'trialing' ? { current_period_start: now } : {}),
|
|
28
|
+
});
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
export const ITEM_ATTRIBUTES = new Set(['billing_thresholds', 'discounts', 'metadata', 'price', 'quantity', 'tax_rates']);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Row } from './common.js';
|
|
2
|
+
export declare const TWIN_TAX_RATE_PCT = 10;
|
|
3
|
+
export declare const ADDRESS_LINES: string[];
|
|
4
|
+
export declare function settingsBody(stored: Row | undefined): Row;
|
|
5
|
+
export declare const TX = "tax.transaction";
|
|
6
|
+
export declare const txLine: (id: string, i: number, l: Row, sign: 1 | -1, reversal: Row | null, type: string) => Row;
|
|
7
|
+
export declare const linesOf: (holder: Row) => Row[];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const TWIN_TAX_RATE_PCT = 10;
|
|
2
|
+
// ── settings: active once a head office is set; the answer has no id ──
|
|
3
|
+
// the defaults' provider: "The tax calculation provider this account uses. Defaults to `stripe` when not using a
|
|
4
|
+
// third-party provider" (the served spec's tax settings defaults); the head office's address answers each line, the
|
|
5
|
+
// lines not given null (the served spec's address: each "(string, nullable)"; the settings page's example answers
|
|
6
|
+
// line2 null)
|
|
7
|
+
export const ADDRESS_LINES = ['city', 'country', 'line1', 'line2', 'postal_code', 'state'];
|
|
8
|
+
export function settingsBody(stored) {
|
|
9
|
+
const given = (stored?.head_office ?? null);
|
|
10
|
+
const address = given && typeof given.address === 'object' && given.address ? given.address : undefined;
|
|
11
|
+
const headOffice = given ? { ...given, ...(address ? { address: Object.fromEntries(ADDRESS_LINES.map((k) => [k, address[k] ?? null])) } : {}) } : null;
|
|
12
|
+
const active = !!headOffice;
|
|
13
|
+
return {
|
|
14
|
+
object: 'tax.settings', livemode: false,
|
|
15
|
+
defaults: { provider: 'stripe', ...(stored?.defaults ?? { tax_behavior: null, tax_code: null }) }, head_office: headOffice,
|
|
16
|
+
status: active ? 'active' : 'pending',
|
|
17
|
+
status_details: active ? { active: {} } : { pending: { missing_fields: ['head_office'] } },
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// ── transactions: committing a calculation, or reversing a transaction with negated amounts ──
|
|
21
|
+
export const TX = 'tax.transaction';
|
|
22
|
+
export const txLine = (id, i, l, sign, reversal, type) => ({
|
|
23
|
+
object: 'tax.transaction_line_item', id: `tax_li_${id}_${i + 1}`,
|
|
24
|
+
amount: sign === 1 ? l.amount : -(Number(l.amount) || 0), amount_tax: sign === 1 ? l.amount_tax : -(Number(l.amount_tax) || 0),
|
|
25
|
+
reference: l.reference ?? null, tax_behavior: l.tax_behavior ?? 'exclusive', tax_code: l.tax_code ?? 'txcd_99999999',
|
|
26
|
+
quantity: l.quantity ?? 1, reversal, type, livemode: false, metadata: {},
|
|
27
|
+
});
|
|
28
|
+
export const linesOf = (holder) => holder.line_items?.data ?? [];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Terminal and top-up semantics: in-person locations, readers (handed a PaymentIntent to process)
|
|
2
|
+
// and their configurations, the reader SDK's connection tokens, and top-ups that fund the balance
|
|
3
|
+
// (a test top-up succeeds at once; only a pending one cancels, the machine in ../manifest.ts). In test mode a
|
|
4
|
+
// simulated reader is presented a card by a test helper: the PaymentIntent the reader is processing is paid with a
|
|
5
|
+
// card_present payment method (succeeded, or requires_capture under manual capture) and the reader's action succeeds
|
|
6
|
+
// (docs.stripe.com/terminal/references/testing#simulated-test-cards,
|
|
7
|
+
// docs.stripe.com/api/terminal/readers/present_payment_method). Where the documentation stops and the twin decides:
|
|
8
|
+
// the presented card is the simulated reader's default Visa, and the reader answers at once.
|
|
9
|
+
// Lists and retrieves are the derived core's.
|
|
10
|
+
export const LOC = 'terminal.location';
|
|
11
|
+
export const READER = 'terminal.reader';
|
|
12
|
+
export const CONF = 'terminal.configuration';
|
|
13
|
+
// ── top-ups ──
|
|
14
|
+
// a top-up adds money to the balance it names, through the ledger, once its funds arrive: "USA (USD) ACH Debit Transfer
|
|
15
|
+
// 5 days" (docs.stripe.com/connect/top-ups), and to the Issuing balance alike: "Top-ups debit your bank account. Your
|
|
16
|
+
// top-ups can take up to 5 business days to become available. While they're pending, they won't be added to your
|
|
17
|
+
// Issuing balance" (docs.stripe.com/issuing/funding/balance). It is pending until its expected_availability_date, then
|
|
18
|
+
// settled by settleTopups. Where the documentation stops and the twin decides: every top-up takes exactly five days,
|
|
19
|
+
// whatever its currency and balance, and succeeds.
|
|
20
|
+
export const TOPUP_DAYS = 5;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const CLOCK = "test_helpers.test_clock";
|
|
2
|
+
/** How long an advance takes: "it takes a few seconds to advance to the specified time"
|
|
3
|
+
* (docs.stripe.com/billing/testing/test-clocks/api-advanced-usage). Where the documentation stops and the twin decides:
|
|
4
|
+
* five seconds of World time from the advance. */
|
|
5
|
+
export declare const ADVANCE_SECONDS = 5;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Test clock semantics. A test clock is Stripe's own door for a transition no API verb makes: the
|
|
2
|
+
// passage of time. Advancing it moves the subscriptions of the clock's customers as a real clock tick does:
|
|
3
|
+
// trials that ended end, and periods that ended renew (./renewals.ts advanceBilling). List, retrieve and delete are
|
|
4
|
+
// the derived core's.
|
|
5
|
+
export const CLOCK = 'test_helpers.test_clock';
|
|
6
|
+
/** How long an advance takes: "it takes a few seconds to advance to the specified time"
|
|
7
|
+
* (docs.stripe.com/billing/testing/test-clocks/api-advanced-usage). Where the documentation stops and the twin decides:
|
|
8
|
+
* five seconds of World time from the advance. */
|
|
9
|
+
export const ADVANCE_SECONDS = 5;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Row } from './common.js';
|
|
2
|
+
/** The Card object a card token carries, as the served spec's `card` describes it: its brand as a name ("Card brand.
|
|
3
|
+
* Can be `American Express`, ... `MasterCard`, `UnionPay`, `Visa`, or `Unknown`"), the holder's name and address as
|
|
4
|
+
* given ("Cardholder name"), and the CVC's check when one was given ("If a CVC was provided, results of the check:
|
|
5
|
+
* pass, fail, unavailable, or unchecked"). Where the documentation stops and the twin decides: a test card's CVC passes. */
|
|
6
|
+
export declare const BRAND_NAMES: Record<string, string>;
|
|
7
|
+
export declare function legacyCard(id: string, card: Row): Row;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Token semantics: the older integrations' single-use tokens for a card, a bank account or PII. A
|
|
2
|
+
// token carries only the safe fields of its instrument, never the card or account number. Retrieve
|
|
3
|
+
// is the derived core's.
|
|
4
|
+
import { paymentMethodSubObject } from "./stripe.js";
|
|
5
|
+
/** The Card object a card token carries, as the served spec's `card` describes it: its brand as a name ("Card brand.
|
|
6
|
+
* Can be `American Express`, ... `MasterCard`, `UnionPay`, `Visa`, or `Unknown`"), the holder's name and address as
|
|
7
|
+
* given ("Cardholder name"), and the CVC's check when one was given ("If a CVC was provided, results of the check:
|
|
8
|
+
* pass, fail, unavailable, or unchecked"). Where the documentation stops and the twin decides: a test card's CVC passes. */
|
|
9
|
+
export const BRAND_NAMES = { amex: 'American Express', cartes_bancaires: 'Cartes Bancaires', diners: 'Diners Club', discover: 'Discover', eftpos_au: 'Eftpos Australia', girocard: 'Girocard', jcb: 'JCB', mastercard: 'MasterCard', unionpay: 'UnionPay', visa: 'Visa' };
|
|
10
|
+
export function legacyCard(id, card) {
|
|
11
|
+
const pm = paymentMethodSubObject('card', { card }).card;
|
|
12
|
+
const given = (k) => (typeof card[k] === 'string' && card[k] !== '' ? card[k] : null);
|
|
13
|
+
return {
|
|
14
|
+
id, object: 'card', brand: BRAND_NAMES[String(pm.brand)] ?? 'Unknown', last4: pm.last4, exp_month: pm.exp_month, exp_year: pm.exp_year,
|
|
15
|
+
funding: pm.funding ?? 'credit', country: pm.country ?? null, fingerprint: pm.fingerprint ?? null, name: given('name'),
|
|
16
|
+
address_line1: given('address_line1'), address_line2: given('address_line2'), address_city: given('address_city'), address_state: given('address_state'),
|
|
17
|
+
address_zip: given('address_zip'), address_country: given('address_country'), address_line1_check: null, address_zip_check: null,
|
|
18
|
+
cvc_check: card.cvc !== undefined && card.cvc !== '' ? 'pass' : null, dynamic_last4: null, tokenization_method: null, metadata: {}, customer: null,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const emptyList = (url) => ({ object: 'list', data: [], has_more: false, total_count: 0, url });
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Row } from './common.js';
|
|
2
|
+
export declare const FA = "treasury.financial_account";
|
|
3
|
+
export declare const TX = "treasury.transaction";
|
|
4
|
+
export declare const ENTRY = "treasury.transaction_entry";
|
|
5
|
+
export declare const ENTRY_TYPES: Set<string>;
|
|
6
|
+
/** A financial account's features as the served spec's treasury.financial_account_features gives them: a toggle
|
|
7
|
+
* (card_issuing, deposit_insurance, intra_stripe_flows) or a feature per network (financial_addresses.aba,
|
|
8
|
+
* inbound_transfers.ach, outbound_payments.ach and .us_domestic_wire, outbound_transfers likewise), each
|
|
9
|
+
* { requested, status, status_details }. What a request asks for is laid over what the account had. Where the
|
|
10
|
+
* documentation stops and the twin decides: a requested feature is active at once (test mode), and one never requested
|
|
11
|
+
* is left out (each is optional in the served spec). Answers the features and the active features' paths. */
|
|
12
|
+
export declare const NETWORKS: Record<string, string[]>;
|
|
13
|
+
export declare const TOGGLES: string[];
|
|
14
|
+
export declare function featuresOf(requested: Row, had?: Row): {
|
|
15
|
+
features: Row;
|
|
16
|
+
active: string[];
|
|
17
|
+
};
|
|
18
|
+
export declare const noTransitions: {
|
|
19
|
+
canceled_at: null;
|
|
20
|
+
failed_at: null;
|
|
21
|
+
posted_at: null;
|
|
22
|
+
returned_at: null;
|
|
23
|
+
};
|