@volter/twin-stripe 2.0.38 → 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,276 +0,0 @@
|
|
|
1
|
-
// The stripe mirror's SHARED vocabulary — formatters, tones, reference resolution — with no
|
|
2
|
-
// import from the server side: the mirror client bundles this into the browser (a server import
|
|
3
|
-
// would drag core, and with it node:async_hooks, into the bundle and the page would never mount).
|
|
4
|
-
// The server module re-exports it, so nothing else moves.
|
|
5
|
-
/** The name an account shows its customers (Checkout, the customer portal): its public business name,
|
|
6
|
-
* `business_profile.name` ("The customer-facing business name", docs.stripe.com/api/accounts/object), which the
|
|
7
|
-
* operator sets on the Dashboard ("You can change a Checkout page's name by modifying the Business name field",
|
|
8
|
-
* docs.stripe.com/payments/checkout/customization/appearance). Where the documentation stops and the twin decides:
|
|
9
|
-
* with none set it falls back to the Dashboard's account name, `settings.dashboard.display_name` ("used on the Stripe
|
|
10
|
-
* Dashboard to differentiate between accounts", the same object page), and with neither to "Twin Inc.", the name the
|
|
11
|
-
* Dashboard mirror has always given the World's own account. */
|
|
12
|
-
export const PLATFORM_DEFAULT_NAME = 'Twin Inc.';
|
|
13
|
-
/** The bookkeeping type of a connected account's Connect OAuth connection (screens/connect-oauth.tsx): one row per
|
|
14
|
-
* account, `revoked: true` once deauthorized or its code reused. Read by the account list and the event path too. */
|
|
15
|
-
export const OAUTH_CONNECTIONS = '_oauth_connection';
|
|
16
|
-
export function publicBusinessName(account) {
|
|
17
|
-
const named = (v) => (typeof v === 'string' && v.trim() ? v : undefined);
|
|
18
|
-
return named(account?.business_profile?.name) ?? named(account?.settings?.dashboard?.display_name) ?? PLATFORM_DEFAULT_NAME;
|
|
19
|
-
}
|
|
20
|
-
/** Zero-decimal currencies (Stripe stores these in whole units, not cents). */
|
|
21
|
-
const ZERO_DECIMAL = new Set(['bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf']);
|
|
22
|
-
/**
|
|
23
|
-
* Format a Stripe minor-unit amount (cents) as a localized currency string.
|
|
24
|
-
* Honors zero-decimal currencies (¥4200 not ¥42.00). Non-numbers → an em dash.
|
|
25
|
-
*/
|
|
26
|
-
export function formatStripeAmount(value, currency) {
|
|
27
|
-
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
28
|
-
return '—';
|
|
29
|
-
const ccy = String(currency ?? 'usd').toLowerCase();
|
|
30
|
-
const zero = ZERO_DECIMAL.has(ccy);
|
|
31
|
-
const major = zero ? value : value / 100;
|
|
32
|
-
try {
|
|
33
|
-
return new Intl.NumberFormat('en-US', {
|
|
34
|
-
style: 'currency', currency: ccy.toUpperCase(),
|
|
35
|
-
minimumFractionDigits: zero ? 0 : 2, maximumFractionDigits: zero ? 0 : 2,
|
|
36
|
-
}).format(major);
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
// Unknown/invalid currency code → a stable, readable fallback.
|
|
40
|
-
return `${zero ? major : major.toFixed(2)} ${ccy.toUpperCase()}`;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Render a Stripe price's `recurring` block as a short interval label, e.g.
|
|
45
|
-
* "every month", "every 3 months". Returns '' when it isn't a recurring price.
|
|
46
|
-
*/
|
|
47
|
-
export function formatRecurring(recurring) {
|
|
48
|
-
if (!recurring || typeof recurring !== 'object')
|
|
49
|
-
return '';
|
|
50
|
-
const r = recurring;
|
|
51
|
-
const interval = typeof r.interval === 'string' ? r.interval : '';
|
|
52
|
-
if (!interval)
|
|
53
|
-
return '';
|
|
54
|
-
const count = Number(r.interval_count);
|
|
55
|
-
return count > 1 ? `every ${count} ${interval}s` : `every ${interval}`;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Render a saved payment method as a short human label, e.g. "Visa •••• 4242"
|
|
59
|
-
* for a card, or the bare `type` ("us_bank_account") for non-card methods.
|
|
60
|
-
*/
|
|
61
|
-
export function formatPaymentMethod(pm) {
|
|
62
|
-
if (!pm || typeof pm !== 'object')
|
|
63
|
-
return '—';
|
|
64
|
-
const m = pm;
|
|
65
|
-
const card = m.card && typeof m.card === 'object' ? m.card : undefined;
|
|
66
|
-
if (card && (card.brand || card.last4)) {
|
|
67
|
-
const brand = card.brand ? String(card.brand).replace(/\b\w/g, (c) => c.toUpperCase()) : 'Card';
|
|
68
|
-
return card.last4 ? `${brand} •••• ${card.last4}` : brand;
|
|
69
|
-
}
|
|
70
|
-
return typeof m.type === 'string' && m.type ? m.type : (m.id ?? '—');
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Extract the HTTP(S) image URLs from a product's `images` field (Stripe stores an
|
|
74
|
-
* array of URL strings) so the mirror can render them as <img> thumbnails instead
|
|
75
|
-
* of plain text. Non-arrays / non-URL entries are dropped. Order is preserved.
|
|
76
|
-
*/
|
|
77
|
-
export function productImageUrls(images) {
|
|
78
|
-
if (!Array.isArray(images))
|
|
79
|
-
return [];
|
|
80
|
-
return images.filter((u) => typeof u === 'string' && /^https?:\/\//i.test(u));
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Render a payment_intent / charge `last_payment_error` (the test-card decline state)
|
|
84
|
-
* as a single human-readable line, e.g. "card_declined (insufficient_funds): Your card
|
|
85
|
-
* has insufficient funds." Returns '' when there is no error object. This is the
|
|
86
|
-
* vendor-faithful decline reason the twin populates on a declined confirm.
|
|
87
|
-
*/
|
|
88
|
-
export function formatPaymentError(error) {
|
|
89
|
-
if (!error || typeof error !== 'object')
|
|
90
|
-
return '';
|
|
91
|
-
const e = error;
|
|
92
|
-
const code = typeof e.code === 'string' ? e.code : '';
|
|
93
|
-
const declineCode = typeof e.decline_code === 'string' ? e.decline_code : '';
|
|
94
|
-
const message = typeof e.message === 'string' ? e.message : '';
|
|
95
|
-
const head = code ? (declineCode ? `${code} (${declineCode})` : code) : declineCode;
|
|
96
|
-
if (head && message)
|
|
97
|
-
return `${head}: ${message}`;
|
|
98
|
-
return head || message;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Summarize a synthesized Stripe `balance` object (available/pending arrays, one entry
|
|
102
|
-
* per currency) into short per-bucket lines, e.g. ["available: $42.00", "pending: $0.00"].
|
|
103
|
-
* The balance is not a list collection, so the mirror renders this summary directly.
|
|
104
|
-
*/
|
|
105
|
-
export function formatBalanceSummary(balance) {
|
|
106
|
-
if (!balance || typeof balance !== 'object')
|
|
107
|
-
return [];
|
|
108
|
-
const b = balance;
|
|
109
|
-
const sum = (arr) => {
|
|
110
|
-
if (!Array.isArray(arr) || arr.length === 0)
|
|
111
|
-
return formatStripeAmount(0, 'usd');
|
|
112
|
-
return arr
|
|
113
|
-
.map((e) => formatStripeAmount(e?.amount, e?.currency))
|
|
114
|
-
.join(', ');
|
|
115
|
-
};
|
|
116
|
-
const out = [];
|
|
117
|
-
if (Array.isArray(b.available))
|
|
118
|
-
out.push({ bucket: 'available', text: sum(b.available) });
|
|
119
|
-
if (Array.isArray(b.pending))
|
|
120
|
-
out.push({ bucket: 'pending', text: sum(b.pending) });
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
export function formatAccountFlags(account) {
|
|
124
|
-
if (!account || typeof account !== 'object')
|
|
125
|
-
return [];
|
|
126
|
-
const a = account;
|
|
127
|
-
return [
|
|
128
|
-
{ key: 'charges_enabled', label: 'Charges', enabled: a.charges_enabled === true },
|
|
129
|
-
{ key: 'payouts_enabled', label: 'Payouts', enabled: a.payouts_enabled === true },
|
|
130
|
-
{ key: 'details_submitted', label: 'Details submitted', enabled: a.details_submitted === true },
|
|
131
|
-
];
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Extract a Connect account's outstanding onboarding requirements (the
|
|
135
|
-
* `requirements.currently_due` list real Stripe shows as "needs attention"). Returns
|
|
136
|
-
* an ordered list of the still-due field paths; empty when nothing is due.
|
|
137
|
-
*/
|
|
138
|
-
export function accountCurrentlyDue(account) {
|
|
139
|
-
if (!account || typeof account !== 'object')
|
|
140
|
-
return [];
|
|
141
|
-
const req = account.requirements;
|
|
142
|
-
if (!req || typeof req !== 'object')
|
|
143
|
-
return [];
|
|
144
|
-
const due = req.currently_due;
|
|
145
|
-
return Array.isArray(due) ? due.filter((d) => typeof d === 'string') : [];
|
|
146
|
-
}
|
|
147
|
-
const PILL_OK = new Set(['active', 'succeeded', 'paid', 'true', 'enabled', 'available', 'won']);
|
|
148
|
-
const PILL_WARN = new Set(['open', 'draft', 'pending', 'processing', 'incomplete', 'trialing', 'requires_confirmation', 'requires_action', 'requires_capture', 'requires_payment_method', 'past_due', 'unpaid', 'in_transit', 'warning_needs_response', 'needs_response', 'under_review', 'warning_under_review']);
|
|
149
|
-
const PILL_BAD = new Set(['canceled', 'cancelled', 'void', 'uncollectible', 'failed', 'incomplete_expired', 'false', 'disabled', 'lost', 'charge_refunded']);
|
|
150
|
-
export function statusTone(value) {
|
|
151
|
-
const v = String(value ?? '').toLowerCase();
|
|
152
|
-
if (PILL_OK.has(v))
|
|
153
|
-
return 'ok';
|
|
154
|
-
if (PILL_BAD.has(v))
|
|
155
|
-
return 'bad';
|
|
156
|
-
if (PILL_WARN.has(v))
|
|
157
|
-
return 'warn';
|
|
158
|
-
return '';
|
|
159
|
-
}
|
|
160
|
-
/** True when a key names a field whose value is a Stripe object id we can link. */
|
|
161
|
-
export function isReferenceKey(key) {
|
|
162
|
-
return REFERENCE_FIELDS.has(key);
|
|
163
|
-
}
|
|
164
|
-
// field name → the COLLECTION it points at (so the UI can jump sections + select).
|
|
165
|
-
const REFERENCE_FIELD_MAP = {
|
|
166
|
-
customer: 'customers', product: 'products', price: 'prices',
|
|
167
|
-
subscription: 'subscriptions', latest_invoice: 'invoices', invoice: 'invoices',
|
|
168
|
-
payment_intent: 'payment_intents', latest_charge: 'charges', charge: 'charges',
|
|
169
|
-
payment_method: 'payment_methods', default_payment_method: 'payment_methods',
|
|
170
|
-
dispute: 'disputes', payout: 'payouts', balance_transaction: 'balance_transactions',
|
|
171
|
-
source_transaction: 'charges', setup_intent: 'setup_intents',
|
|
172
|
-
// Connect: a transfer's `destination` points at a connected account.
|
|
173
|
-
account: 'accounts', destination: 'accounts',
|
|
174
|
-
// Billing: a customer_balance_transaction may reference the credit_note that created it.
|
|
175
|
-
credit_note: 'credit_notes',
|
|
176
|
-
};
|
|
177
|
-
const REFERENCE_FIELDS = new Set(Object.keys(REFERENCE_FIELD_MAP));
|
|
178
|
-
/** The collection a reference field points at, or undefined if not a reference. */
|
|
179
|
-
export function referenceCollection(key) {
|
|
180
|
-
return REFERENCE_FIELD_MAP[key];
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Flatten an arbitrary nested Stripe value (object / array / scalar) into ordered,
|
|
184
|
-
* indented label/value lines suitable for a readable detail view — instead of the
|
|
185
|
-
* old "[object Object]". Stripe "list" wrappers ({object:'list',data:[...]}) are
|
|
186
|
-
* unwrapped to their `data`. Amount-ish fields are currency-formatted.
|
|
187
|
-
*/
|
|
188
|
-
export function flattenStripeValue(value, opts = {}) {
|
|
189
|
-
const depth = opts.depth ?? 0;
|
|
190
|
-
const label = opts.label ?? '';
|
|
191
|
-
const currency = opts.currency;
|
|
192
|
-
if (value === null || value === undefined)
|
|
193
|
-
return [{ depth, label, value: '—' }];
|
|
194
|
-
if (Array.isArray(value)) {
|
|
195
|
-
if (value.length === 0)
|
|
196
|
-
return [{ depth, label, value: '(none)' }];
|
|
197
|
-
const out = label ? [{ depth, label, value: '' }] : [];
|
|
198
|
-
value.forEach((item, i) => {
|
|
199
|
-
const childDepth = label ? depth + 1 : depth;
|
|
200
|
-
out.push(...flattenStripeValue(item, { label: `#${i + 1}`, depth: childDepth, currency }));
|
|
201
|
-
});
|
|
202
|
-
return out;
|
|
203
|
-
}
|
|
204
|
-
if (typeof value === 'object') {
|
|
205
|
-
const obj = value;
|
|
206
|
-
// Unwrap Stripe list objects to their data array.
|
|
207
|
-
if (obj.object === 'list' && Array.isArray(obj.data)) {
|
|
208
|
-
return flattenStripeValue(obj.data, { label, depth, currency });
|
|
209
|
-
}
|
|
210
|
-
const childCurrency = typeof obj.currency === 'string' ? obj.currency : currency;
|
|
211
|
-
const keys = Object.keys(obj).filter((k) => obj[k] !== null && obj[k] !== undefined && k !== 'object');
|
|
212
|
-
if (keys.length === 0)
|
|
213
|
-
return [{ depth, label, value: '(empty)' }];
|
|
214
|
-
const out = label ? [{ depth, label, value: '' }] : [];
|
|
215
|
-
const childDepth = label ? depth + 1 : depth;
|
|
216
|
-
for (const k of keys)
|
|
217
|
-
out.push(...flattenStripeValue(obj[k], { label: k, depth: childDepth, currency: childCurrency }));
|
|
218
|
-
return out;
|
|
219
|
-
}
|
|
220
|
-
// scalar
|
|
221
|
-
const ref = typeof value === 'string' && isReferenceKey(label) ? value : undefined;
|
|
222
|
-
const isMoney = typeof value === 'number' && (label === 'unit_amount' || /amount|total|subtotal|balance/.test(label));
|
|
223
|
-
const rendered = isMoney ? formatStripeAmount(value, currency) : String(value);
|
|
224
|
-
return [{ depth, label, value: rendered, ...(ref ? { ref } : {}) }];
|
|
225
|
-
}
|
|
226
|
-
const LABELERS = {
|
|
227
|
-
customers: (r) => r.name || r.email || r.id,
|
|
228
|
-
products: (r) => r.name || r.id,
|
|
229
|
-
prices: (r) => `${formatStripeAmount(r.unit_amount, r.currency)}${formatRecurring(r.recurring) ? ` ${formatRecurring(r.recurring)}` : ''}`,
|
|
230
|
-
subscriptions: (r) => `${r.status ?? 'subscription'} · ${r.id}`,
|
|
231
|
-
invoices: (r) => `${r.status ?? 'invoice'} · ${formatStripeAmount(r.total ?? r.amount_due, r.currency)}`,
|
|
232
|
-
payment_intents: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? ''}`,
|
|
233
|
-
charges: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? ''}`,
|
|
234
|
-
refunds: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'refund'}`,
|
|
235
|
-
payment_methods: (r) => `${formatPaymentMethod(r)} · ${r.id}`,
|
|
236
|
-
disputes: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'dispute'}`,
|
|
237
|
-
payouts: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'payout'}`,
|
|
238
|
-
balance_transactions: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.type ?? 'txn'}`,
|
|
239
|
-
events: (r) => `${r.type ?? 'event'} · ${r.id}`,
|
|
240
|
-
setup_intents: (r) => `${r.status ?? 'setup_intent'} · ${r.id}`,
|
|
241
|
-
invoiceitems: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.id}`,
|
|
242
|
-
accounts: (r) => `${r.email || r.id} · ${r.type ?? 'account'}`,
|
|
243
|
-
transfers: (r) => `${formatStripeAmount(r.amount, r.currency)} → ${r.destination ?? '?'}`,
|
|
244
|
-
credit_notes: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'credit_note'}`,
|
|
245
|
-
tax_ids: (r) => `${r.value ?? r.id} · ${r.type ?? ''}`,
|
|
246
|
-
};
|
|
247
|
-
function labelFor(collection, row) {
|
|
248
|
-
return (LABELERS[collection] ?? ((r) => r.id))(row);
|
|
249
|
-
}
|
|
250
|
-
export function resolveCrossRefs(collection, row, data) {
|
|
251
|
-
const outgoing = [];
|
|
252
|
-
const incoming = [];
|
|
253
|
-
if (!row)
|
|
254
|
-
return { outgoing, incoming };
|
|
255
|
-
// Outgoing: every reference field on this row that we can resolve to a row.
|
|
256
|
-
for (const [key, value] of Object.entries(row)) {
|
|
257
|
-
if (typeof value !== 'string' || !isReferenceKey(key))
|
|
258
|
-
continue;
|
|
259
|
-
const target = referenceCollection(key);
|
|
260
|
-
const found = (data[target] ?? []).find((r) => r.id === value);
|
|
261
|
-
outgoing.push({ collection: target, id: value, label: `${key}: ${found ? labelFor(target, found) : value}` });
|
|
262
|
-
}
|
|
263
|
-
// Incoming: rows in other collections whose reference field points at this row.
|
|
264
|
-
for (const [other, rows] of Object.entries(data)) {
|
|
265
|
-
if (other === collection)
|
|
266
|
-
continue;
|
|
267
|
-
for (const r of rows) {
|
|
268
|
-
for (const [key, value] of Object.entries(r)) {
|
|
269
|
-
if (value !== row.id || !isReferenceKey(key))
|
|
270
|
-
continue;
|
|
271
|
-
incoming.push({ collection: other, id: r.id, label: `${labelFor(other, r)}` });
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
return { outgoing, incoming };
|
|
276
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { type UiSurface, type UiCompletenessReport } from '@volter/world-tooling';
|
|
2
|
-
/** What Stripe's Dashboard shows, classified vs the twin + its Dashboard. */
|
|
3
|
-
export declare const STRIPE_UI_INVENTORY: UiSurface[];
|
|
4
|
-
/** Read-only completeness check over the declared Stripe UI inventory. */
|
|
5
|
-
export declare function stripeUiConformance(): UiCompletenessReport;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// Stripe UI conformance — the declared surface inventory of Stripe's Dashboard, classified against THIS
|
|
2
|
-
// twin, and the read-only completeness check over it.
|
|
3
|
-
//
|
|
4
|
-
// Honesty: `status` is the current truth, verified by the structural cross-check in
|
|
5
|
-
// stripe-ui-conformance.test.ts (which builds the actual Dashboard bundle and asserts each 'rendered'
|
|
6
|
-
// surface's label/class is really present — downgrading to 'modeled' otherwise). `rendered` = the
|
|
7
|
-
// Dashboard shows it today; `modeled` = the twin has the data but the Dashboard doesn't show it; `unmodeled`
|
|
8
|
-
// = Stripe shows it but the twin doesn't model it.
|
|
9
|
-
//
|
|
10
|
-
// Classified against the Dashboard (client/stripe-mirror.tsx, reading through client/dashboard-api.ts):
|
|
11
|
-
// Home, Balances, Transactions > Payments and a payment's page, Customers and a customer's page, Product
|
|
12
|
-
// catalog, Billing's Subscriptions (and a subscription's page) and Invoices (and an invoice's page),
|
|
13
|
-
// Developers, Settings, and the resource lists under Connect, Payments, Reporting and More.
|
|
14
|
-
import { checkUiCompleteness } from '@volter/world-tooling';
|
|
15
|
-
/** What Stripe's Dashboard shows, classified vs the twin + its Dashboard. */
|
|
16
|
-
export const STRIPE_UI_INVENTORY = [
|
|
17
|
-
// --- shell ---
|
|
18
|
-
{ key: 'navigation', label: 'Left navigation (Home, Balances, Transactions, Customers, Product catalog, Billing, Developers)', status: 'rendered' },
|
|
19
|
-
{ key: 'testModeBand', label: 'Test-mode band', status: 'rendered' },
|
|
20
|
-
{ key: 'search', label: 'Search across customers, payments, subscriptions, invoices, products', status: 'rendered' },
|
|
21
|
-
{ key: 'statusPill', label: "Status pills in Stripe's words (Succeeded, Refunded, Failed, Active, Trialing, Paid, …)", status: 'rendered' },
|
|
22
|
-
{ key: 'amountFormatting', label: 'Currency-formatted amounts with the currency code', status: 'rendered' },
|
|
23
|
-
// --- Home and Balances ---
|
|
24
|
-
{ key: 'homeToday', label: "Home: today's gross volume, balance and payouts", status: 'rendered' },
|
|
25
|
-
{ key: 'homeOverview', label: 'Home: overview metrics (gross/net volume, successful and failed payments, customers, subscribers)', status: 'rendered' },
|
|
26
|
-
{ key: 'balanceSummary', label: 'Balances: incoming and available per currency', status: 'rendered' },
|
|
27
|
-
{ key: 'balanceTransactions', label: 'Balances: recent activity (balance transactions) and payouts', status: 'rendered' },
|
|
28
|
-
// --- Payments ---
|
|
29
|
-
{ key: 'paymentList', label: 'Payments list: amount + currency, status, payment method, description, customer, date', status: 'rendered' },
|
|
30
|
-
{ key: 'paymentFilters', label: 'Payments status tabs with counts, and filter chips', status: 'rendered' },
|
|
31
|
-
{ key: 'paymentRefundedDate', label: 'Payments list: refunded date and decline reason', status: 'rendered' },
|
|
32
|
-
{ key: 'paymentExport', label: 'Payments export', status: 'rendered' },
|
|
33
|
-
{ key: 'paymentTimeline', label: "A payment's timeline from its events", status: 'rendered' },
|
|
34
|
-
{ key: 'paymentBreakdown', label: "A payment's breakdown (amount, refunded, net)", status: 'rendered' },
|
|
35
|
-
{ key: 'paymentFees', label: "A payment's Stripe fees (balance transaction fee details)", status: 'unmodeled' },
|
|
36
|
-
{ key: 'paymentRefunds', label: "A payment's refunds", status: 'rendered' },
|
|
37
|
-
{ key: 'paymentMethodDetails', label: "A payment's card: last four, expiry, type, origin, CVC check", status: 'rendered' },
|
|
38
|
-
{ key: 'paymentDecline', label: 'A declined payment states its error and decline code', status: 'rendered' },
|
|
39
|
-
{ key: 'refundDialog', label: 'Refund a payment in full or in part, with a reason', status: 'rendered' },
|
|
40
|
-
{ key: 'disputes', label: 'Disputes', status: 'rendered' },
|
|
41
|
-
// --- Customers ---
|
|
42
|
-
{ key: 'customerList', label: 'Customers list: name, email, default payment method, created, total spend, payments, refunds', status: 'rendered' },
|
|
43
|
-
{ key: 'createCustomer', label: 'Create customer', status: 'rendered' },
|
|
44
|
-
{ key: 'customerDetails', label: "A customer's details (ID, since, email, description, billing details)", status: 'rendered' },
|
|
45
|
-
{ key: 'customerSubscriptions', label: "A customer's subscriptions", status: 'rendered' },
|
|
46
|
-
{ key: 'customerPayments', label: "A customer's payments", status: 'rendered' },
|
|
47
|
-
{ key: 'customerPaymentMethods', label: "A customer's saved payment methods, default marked", status: 'rendered' },
|
|
48
|
-
{ key: 'customerInvoices', label: "A customer's invoices", status: 'rendered' },
|
|
49
|
-
{ key: 'customerEvents', label: "A customer's events", status: 'rendered' },
|
|
50
|
-
// --- Billing ---
|
|
51
|
-
{ key: 'subscriptionList', label: 'Subscriptions list: customer, status, billing, product, amount, created', status: 'rendered' },
|
|
52
|
-
{ key: 'subscriptionDetails', label: "A subscription's details: customer, period, trial, billing method, payment method", status: 'rendered' },
|
|
53
|
-
{ key: 'subscriptionPricing', label: "A subscription's pricing items", status: 'rendered' },
|
|
54
|
-
{ key: 'cancelSubscription', label: 'Cancel a subscription now or at period end', status: 'rendered' },
|
|
55
|
-
{ key: 'invoiceList', label: 'Invoices list: amount, status, number, customer, due, created', status: 'rendered' },
|
|
56
|
-
{ key: 'invoiceDetail', label: "An invoice's summary lines and totals", status: 'rendered' },
|
|
57
|
-
{ key: 'quotes', label: 'Quotes', status: 'rendered' },
|
|
58
|
-
// --- Product catalog ---
|
|
59
|
-
{ key: 'productCatalog', label: 'Product catalog: name, pricing, created, updated', status: 'rendered' },
|
|
60
|
-
{ key: 'createProduct', label: 'Create product', status: 'rendered' },
|
|
61
|
-
{ key: 'coupons', label: 'Coupons', status: 'rendered' },
|
|
62
|
-
// --- Developers and Settings ---
|
|
63
|
-
{ key: 'apiKeys', label: 'API keys', status: 'rendered' },
|
|
64
|
-
{ key: 'webhooks', label: 'Webhook endpoints', status: 'rendered' },
|
|
65
|
-
{ key: 'eventsLog', label: 'Events', status: 'rendered' },
|
|
66
|
-
{ key: 'payoutSchedule', label: 'Settings: payout schedule', status: 'rendered' },
|
|
67
|
-
// --- under More ---
|
|
68
|
-
{ key: 'connectAccounts', label: 'Connect: connected accounts, readiness flags and requirements due', status: 'rendered' },
|
|
69
|
-
{ key: 'connectTransfers', label: 'Connect: transfers', status: 'rendered' },
|
|
70
|
-
{ key: 'radar', label: 'Radar: reviews, lists, rules', status: 'rendered' },
|
|
71
|
-
{ key: 'terminal', label: 'Terminal: readers, locations', status: 'rendered' },
|
|
72
|
-
{ key: 'issuing', label: 'Issuing: cards, cardholders', status: 'rendered' },
|
|
73
|
-
{ key: 'taxRates', label: 'Tax: tax rates', status: 'rendered' },
|
|
74
|
-
{ key: 'reports', label: 'Reporting: report runs', status: 'rendered' },
|
|
75
|
-
];
|
|
76
|
-
/** Read-only completeness check over the declared Stripe UI inventory. */
|
|
77
|
-
export function stripeUiConformance() {
|
|
78
|
-
return checkUiCompleteness('stripe', STRIPE_UI_INVENTORY);
|
|
79
|
-
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
// The Stripe Dashboard — structural DOM checklist (RUNG-5).
|
|
2
|
-
//
|
|
3
|
-
// Completeness (stripe-ui-conformance.ts) asks "does the Dashboard SHOW the data?". Structure asks
|
|
4
|
-
// "does its rendered DOM have the landmarks Stripe's Dashboard has?": the left navigation at Stripe's
|
|
5
|
-
// paths, the test-mode band, the Payments table with Stripe's columns and status pills, a payment's page
|
|
6
|
-
// (amount, status, timeline from its events, breakdown, refunds, card), a customer's page (details,
|
|
7
|
-
// subscriptions, payments, payment methods, invoices), a subscription's page (pricing, period, invoices,
|
|
8
|
-
// the cancel control), the balance buckets, a connected account's readiness and the resource lists.
|
|
9
|
-
//
|
|
10
|
-
// Each check's `present` is computed from the ACTUAL markup renderToStaticMarkup() produces from the
|
|
11
|
-
// Dashboard's own components (client/stripe-mirror.tsx) over objects shaped as the API returns them, so a
|
|
12
|
-
// check cannot pass unless the component truly emits that structure. Read-only; deterministic.
|
|
13
|
-
import { createElement } from 'react';
|
|
14
|
-
import { renderToStaticMarkup } from 'react-dom/server';
|
|
15
|
-
import { checkUiStructure } from '@volter/world-tooling';
|
|
16
|
-
import { SECTIONS, SideNav, ListPane, TestModeBand, PaymentsTable, PaymentDetailView, CustomerDetailView, SubscriptionDetailView, BalanceSummary, ConnectAccountPanel, } from "../client/stripe-mirror.js";
|
|
17
|
-
const noop = () => { };
|
|
18
|
-
const AT = 1790263345;
|
|
19
|
-
const CUSTOMER = { id: 'cus_twin001', object: 'customer', name: 'Ada Lovelace', email: 'ada@example.com', created: AT, invoice_settings: { default_payment_method: 'pm_twin001' }, metadata: {} };
|
|
20
|
-
const CARD = { id: 'pm_twin001', object: 'payment_method', type: 'card', customer: 'cus_twin001', card: { brand: 'visa', last4: '4242', exp_month: 12, exp_year: 2034, funding: 'credit', country: 'US', checks: { cvc_check: 'pass' } }, billing_details: {} };
|
|
21
|
-
const INTENT = { id: 'pi_twin001', object: 'payment_intent', amount: 30000, currency: 'usd', status: 'succeeded', customer: 'cus_twin001', payment_method: 'pm_twin001', latest_charge: 'ch_twin001', description: 'Annual workshop seat', created: AT, metadata: {} };
|
|
22
|
-
const CHARGE = { id: 'ch_twin001', object: 'charge', amount: 30000, currency: 'usd', status: 'succeeded', refunded: false, amount_refunded: 10000, payment_intent: 'pi_twin001', customer: 'cus_twin001', created: AT };
|
|
23
|
-
const REFUND = { id: 're_twin001', object: 'refund', amount: 10000, currency: 'usd', status: 'succeeded', charge: 'ch_twin001', payment_intent: 'pi_twin001', reason: 'requested_by_customer', created: AT + 60 };
|
|
24
|
-
const event = (id, type, object, created) => ({ id, object: 'event', type, created, data: { object } });
|
|
25
|
-
const PARTIAL = {
|
|
26
|
-
id: 'pi_twin001', amount: 30000, currency: 'usd', status: 'partially_refunded', description: 'Annual workshop seat', created: AT,
|
|
27
|
-
customer: CUSTOMER, charge: CHARGE, intent: INTENT, paymentMethod: CARD, amountRefunded: 10000, refundedAt: AT + 60,
|
|
28
|
-
refunds: [REFUND],
|
|
29
|
-
events: [
|
|
30
|
-
event('evt_3', 'charge.refunded', CHARGE, AT + 60),
|
|
31
|
-
event('evt_2', 'payment_intent.succeeded', INTENT, AT + 1),
|
|
32
|
-
event('evt_1', 'payment_intent.created', INTENT, AT),
|
|
33
|
-
],
|
|
34
|
-
};
|
|
35
|
-
const DECLINED_INTENT = {
|
|
36
|
-
id: 'pi_twin009', object: 'payment_intent', amount: 15000, currency: 'usd', status: 'requires_payment_method', customer: 'cus_twin001', created: AT,
|
|
37
|
-
last_payment_error: { type: 'card_error', code: 'card_declined', decline_code: 'insufficient_funds', message: 'Your card has insufficient funds.', param: 'card' },
|
|
38
|
-
};
|
|
39
|
-
const DECLINED = {
|
|
40
|
-
id: 'pi_twin009', amount: 15000, currency: 'usd', status: 'failed', created: AT, customer: CUSTOMER, intent: DECLINED_INTENT,
|
|
41
|
-
amountRefunded: 0, declineReason: 'Insufficient funds', declineMessage: 'Your card has insufficient funds.', refunds: [],
|
|
42
|
-
events: [event('evt_9', 'payment_intent.payment_failed', DECLINED_INTENT, AT)],
|
|
43
|
-
};
|
|
44
|
-
const REFUNDED = { id: 'pi_twin002', amount: 2500, currency: 'usd', status: 'refunded', description: 'Twin T-shirt', created: AT, customer: CUSTOMER, paymentMethod: CARD, amountRefunded: 2500, refundedAt: AT + 30 };
|
|
45
|
-
const PAYMENTS = [PARTIAL, DECLINED, REFUNDED, { ...REFUNDED, id: 'pi_twin003', status: 'succeeded', amountRefunded: 0, refundedAt: undefined, description: 'Consulting' }];
|
|
46
|
-
const PRODUCT = { id: 'prod_twin001', object: 'product', name: 'Pro plan' };
|
|
47
|
-
const SUBSCRIPTION = {
|
|
48
|
-
id: 'sub_twin001', object: 'subscription', status: 'trialing', customer: 'cus_twin001', currency: 'usd', created: AT, start_date: AT,
|
|
49
|
-
current_period_start: AT, current_period_end: AT + 14 * 86400, trial_start: AT, trial_end: AT + 14 * 86400, collection_method: 'charge_automatically',
|
|
50
|
-
items: { object: 'list', data: [{ id: 'si_twin001', object: 'subscription_item', quantity: 3, price: { id: 'price_twin001', product: 'prod_twin001', unit_amount: 4900, currency: 'usd', recurring: { interval: 'month' } } }] },
|
|
51
|
-
};
|
|
52
|
-
const INVOICE = { id: 'in_twin001', object: 'invoice', number: 'TWIN-0001', status: 'paid', customer: 'cus_twin001', subscription: 'sub_twin001', currency: 'usd', total: 14700, amount_due: 14700, created: AT };
|
|
53
|
-
const CUSTOMER_PAGE = { customer: CUSTOMER, paymentMethods: [CARD], subscriptions: [SUBSCRIPTION], invoices: [INVOICE], payments: PAYMENTS, products: new Map([[PRODUCT.id, PRODUCT]]), events: [] };
|
|
54
|
-
const SUBSCRIPTION_PAGE = { subscription: SUBSCRIPTION, customer: CUSTOMER, invoices: [INVOICE], products: new Map([[PRODUCT.id, PRODUCT]]), events: [event('evt_s', 'customer.subscription.created', SUBSCRIPTION, AT)], paymentMethod: CARD };
|
|
55
|
-
const BALANCE = { id: 'balance', object: 'balance', available: [{ amount: 16800, currency: 'usd' }], pending: [{ amount: 4200, currency: 'usd' }] };
|
|
56
|
-
const ACCOUNT = {
|
|
57
|
-
id: 'acct_twin001', object: 'account', type: 'express', country: 'US', charges_enabled: false, payouts_enabled: false, details_submitted: false,
|
|
58
|
-
requirements: { currently_due: ['external_account', 'tos_acceptance.date'] },
|
|
59
|
-
};
|
|
60
|
-
const TAX_RATE = { id: 'txr_twin001', object: 'tax_rate', display_name: 'Sales Tax', percentage: 8.5, inclusive: false, active: true, jurisdiction: 'US', created: AT };
|
|
61
|
-
const html = (el) => renderToStaticMarkup(el);
|
|
62
|
-
const count = (markup, needle) => (markup.match(needle) ?? []).length;
|
|
63
|
-
/** Build the structural checklist from the real rendered markup and run it. */
|
|
64
|
-
export function stripeUiStructure() {
|
|
65
|
-
const nav = html(createElement(SideNav, { route: ['payments'], go: noop }));
|
|
66
|
-
const band = html(createElement(TestModeBand));
|
|
67
|
-
const payments = html(createElement(PaymentsTable, { payments: PAYMENTS, go: noop }));
|
|
68
|
-
const partial = html(createElement(PaymentDetailView, { p: PARTIAL, go: noop, onRefund: noop }));
|
|
69
|
-
const declined = html(createElement(PaymentDetailView, { p: DECLINED, go: noop, onRefund: noop }));
|
|
70
|
-
const customer = html(createElement(CustomerDetailView, { data: CUSTOMER_PAGE, go: noop }));
|
|
71
|
-
const subscription = html(createElement(SubscriptionDetailView, { data: SUBSCRIPTION_PAGE, go: noop, onCancel: noop }));
|
|
72
|
-
const balance = html(createElement(BalanceSummary, { row: BALANCE }));
|
|
73
|
-
const account = html(createElement(ConnectAccountPanel, { row: ACCOUNT }));
|
|
74
|
-
const taxRates = html(createElement(ListPane, { section: SECTIONS.find((s) => s.key === 'tax_rates'), rows: [TAX_RATE], onSelect: noop }));
|
|
75
|
-
const checks = [
|
|
76
|
-
{
|
|
77
|
-
key: 'navigation',
|
|
78
|
-
label: "Left navigation: Home, Balances, Transactions, Customers, Product catalog, Billing's Subscriptions and Invoices, Developers — at Stripe's /test/ paths",
|
|
79
|
-
present: ['>Home<', '>Balances<', '>Transactions<', '>Customers<', '>Product catalog<', '>Subscriptions<', '>Invoices<', '>Developers<'].every((l) => nav.includes(l))
|
|
80
|
-
&& nav.includes('href="/test/payments"') && nav.includes('href="/test/customers"') && nav.includes('href="/test/subscriptions"'),
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
key: 'navActive',
|
|
84
|
-
label: 'The navigation marks the section being viewed',
|
|
85
|
-
present: /class="nav-item [^"]*active"[^>]*href="\/test\/payments"|href="\/test\/payments" class="nav-item [^"]*active"/.test(nav),
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
key: 'testModeBand',
|
|
89
|
-
label: "The orange test-mode band across the top",
|
|
90
|
-
present: band.includes('class="test-band"') && band.includes('Test mode'),
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
key: 'paymentsColumns',
|
|
94
|
-
label: "Payments table carries Stripe's columns (Amount, Payment method, Description, Customer, Date, Refunded date, Decline reason)",
|
|
95
|
-
present: ['>Amount<', '>Payment method<', '>Description<', '>Customer<', '>Date<', '>Refunded date<', '>Decline reason<'].every((c) => payments.includes(c)),
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
key: 'paymentsRowPerPayment',
|
|
99
|
-
label: 'Payments table emits one row per payment, amount with its currency',
|
|
100
|
-
present: count(payments, /class="list-row"/g) === PAYMENTS.length && payments.includes('$300.00') && payments.includes('USD'),
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
key: 'paymentsStatusPills',
|
|
104
|
-
label: 'Status pills worded as Stripe words them (Succeeded, Refunded, Partial refund, Failed)',
|
|
105
|
-
present: ['>Succeeded<', '>Refunded<', '>Partial refund<', '>Failed<'].every((l) => payments.includes(l)),
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
key: 'paymentsDeclineReason',
|
|
109
|
-
label: 'A failed payment shows its decline reason in the list',
|
|
110
|
-
present: payments.includes('Insufficient funds'),
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
key: 'paymentHeader',
|
|
114
|
-
label: "A payment's page leads with its amount, currency and status, and a Refund control while refundable",
|
|
115
|
-
present: partial.includes('$300.00') && partial.includes('Partial refund') && partial.includes('Refund</button>'),
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
key: 'paymentTimeline',
|
|
119
|
-
label: "A payment's timeline lists its events (started, succeeded, refunded)",
|
|
120
|
-
present: partial.includes('class="timeline"') && partial.includes('Payment started') && partial.includes('Payment succeeded') && partial.includes('refunded'),
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
key: 'paymentBreakdownAndRefunds',
|
|
124
|
-
label: "A payment's breakdown (amount, refunded, net) and its refunds",
|
|
125
|
-
present: partial.includes('Payment breakdown') && partial.includes('$200.00') && partial.includes('>Refunds<') && partial.includes('re_twin001'),
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
key: 'paymentMethodBlock',
|
|
129
|
-
label: "A payment's card: number's last four, expiry, type, CVC check",
|
|
130
|
-
present: partial.includes('4242') && partial.includes('12 / 2034') && partial.includes('Visa credit card') && partial.includes('Passed'),
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
key: 'paymentDecline',
|
|
134
|
-
label: 'A declined payment states its error and decline code, and offers no refund',
|
|
135
|
-
present: declined.includes('class="pay-error"') && declined.includes('Your card has insufficient funds.') && declined.includes('insufficient_funds') && !declined.includes('Refund</button>'),
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
key: 'customerPage',
|
|
139
|
-
label: "A customer's page: name, email, Details, Subscriptions, Payments, Payment methods, Invoices",
|
|
140
|
-
present: customer.includes('Ada Lovelace') && customer.includes('ada@example.com')
|
|
141
|
-
&& ['>Details<', '>Subscriptions<', '>Payments<', '>Payment methods<', '>Invoices<'].every((h) => customer.includes(h))
|
|
142
|
-
&& customer.includes('Pro plan') && customer.includes('TWIN-0001') && customer.includes('>Default<'),
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
key: 'subscriptionPage',
|
|
146
|
-
label: "A subscription's page: customer on product, status, period, pricing items, invoices and Cancel subscription",
|
|
147
|
-
present: subscription.includes('Ada Lovelace') && subscription.includes('Pro plan') && subscription.includes('>Trialing<')
|
|
148
|
-
&& subscription.includes('Current period') && subscription.includes('>Pricing<') && subscription.includes('$147.00')
|
|
149
|
-
&& subscription.includes('TWIN-0001') && subscription.includes('Cancel subscription'),
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
key: 'balanceSummaryBuckets',
|
|
153
|
-
label: 'The balance renders its incoming and available buckets, amounts formatted',
|
|
154
|
-
present: balance.includes('class="balance-summary"') && balance.includes('Incoming') && balance.includes('Available') && balance.includes('$168.00') && balance.includes('$42.00'),
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
key: 'connectAccountReadiness',
|
|
158
|
-
label: "A connected account's charges/payouts/details flags and what is currently due",
|
|
159
|
-
present: account.includes('class="connect-panel"') && count(account, /connect-flag /g) >= 3 && account.includes('Requirements currently due') && account.includes('external_account'),
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
key: 'resourceListRow',
|
|
163
|
-
label: 'A resource list emits one row per object (Tax rates: name and percentage)',
|
|
164
|
-
present: count(taxRates, /list-row/g) === 1 && taxRates.includes('Sales Tax') && taxRates.includes('8.5'),
|
|
165
|
-
},
|
|
166
|
-
];
|
|
167
|
-
return checkUiStructure('stripe', checks);
|
|
168
|
-
}
|