@volter/twin-stripe 2.0.38 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/README.md +112 -207
  2. package/dist/generated/pack-facts.json +94 -0
  3. package/dist/journeys/coverage.json +596 -0
  4. package/dist/journeys/customer-life.json +6108 -0
  5. package/dist/journeys/customer-life.outline.md +371 -0
  6. package/dist/journeys/decisions.json +677 -0
  7. package/dist/journeys/demand.json +706 -0
  8. package/dist/journeys/score.json +853 -0
  9. package/dist/journeys/unreachable.json +102 -0
  10. package/dist/journeys/vendor-examples.json +8010 -0
  11. package/dist/spec/SOURCE.md +18 -0
  12. package/dist/spec/doc-examples.json +445 -0
  13. package/dist/spec/fixtures3.json.gz +0 -0
  14. package/dist/spec/openapi.json.gz +0 -0
  15. package/dist/spec/patches.json +34 -0
  16. package/dist/spec/sources.json +306 -0
  17. package/dist/src/cli.d.ts +0 -1
  18. package/dist/src/cli.js +11 -31
  19. package/dist/src/engine/after-payment.d.ts +8 -0
  20. package/dist/src/engine/after-payment.js +27 -0
  21. package/dist/src/engine/apps-secrets.d.ts +1 -0
  22. package/dist/src/engine/apps-secrets.js +3 -0
  23. package/dist/src/engine/balance.d.ts +5 -0
  24. package/dist/src/engine/balance.js +15 -0
  25. package/dist/src/engine/checkout.d.ts +24 -0
  26. package/dist/src/engine/checkout.js +30 -0
  27. package/dist/src/engine/common.d.ts +19 -0
  28. package/dist/src/engine/common.js +34 -0
  29. package/dist/src/engine/connect.d.ts +45 -0
  30. package/dist/src/engine/connect.js +108 -0
  31. package/dist/src/engine/customers.d.ts +4 -0
  32. package/dist/src/engine/customers.js +8 -0
  33. package/dist/src/engine/display.d.ts +11 -0
  34. package/dist/src/engine/display.js +13 -0
  35. package/dist/src/engine/files.d.ts +11 -0
  36. package/dist/src/engine/files.js +23 -0
  37. package/dist/src/engine/invoices.d.ts +21 -0
  38. package/dist/src/engine/invoices.js +84 -0
  39. package/dist/src/engine/issuing.d.ts +33 -0
  40. package/dist/src/engine/issuing.js +54 -0
  41. package/dist/src/engine/ledger.d.ts +8 -0
  42. package/dist/src/engine/ledger.js +8 -0
  43. package/dist/src/engine/oauth.d.ts +4 -0
  44. package/dist/src/engine/oauth.js +24 -0
  45. package/dist/src/engine/onboarding.d.ts +13 -0
  46. package/dist/src/engine/onboarding.js +42 -0
  47. package/dist/src/{stripe-params.d.ts → engine/params.d.ts} +20 -3
  48. package/dist/src/{stripe-params.js → engine/params.js} +7 -60
  49. package/dist/src/engine/payment-intents.d.ts +10 -0
  50. package/dist/src/engine/payment-intents.js +27 -0
  51. package/dist/src/engine/payment-methods.d.ts +16 -0
  52. package/dist/src/engine/payment-methods.js +22 -0
  53. package/dist/src/engine/radar.d.ts +2 -0
  54. package/dist/src/engine/radar.js +5 -0
  55. package/dist/src/engine/refunds.d.ts +1 -0
  56. package/dist/src/engine/refunds.js +3 -0
  57. package/dist/src/engine/renewals.d.ts +36 -0
  58. package/dist/src/engine/renewals.js +65 -0
  59. package/dist/src/{stripe-twin.d.ts → engine/stripe.d.ts} +12 -45
  60. package/dist/src/{stripe-twin.js → engine/stripe.js} +53 -387
  61. package/dist/src/engine/subscriptions.d.ts +11 -0
  62. package/dist/src/engine/subscriptions.js +30 -0
  63. package/dist/src/engine/transfers.d.ts +2 -0
  64. package/dist/src/engine/transfers.js +1 -0
  65. package/dist/src/{stripe-version.d.ts → engine/version.d.ts} +0 -2
  66. package/dist/src/{stripe-version.js → engine/version.js} +21 -9
  67. package/dist/src/engine/webhook-endpoints.d.ts +1 -0
  68. package/dist/src/engine/webhook-endpoints.js +12 -0
  69. package/dist/src/engine/webhooks.d.ts +31 -0
  70. package/dist/src/engine/webhooks.js +68 -0
  71. package/dist/src/fetch.d.ts +2 -0
  72. package/dist/src/fetch.js +26 -0
  73. package/dist/src/generated/surface.gen.json +1 -1
  74. package/dist/src/generated/ui.gen.json +1 -1
  75. package/dist/src/index.d.ts +5 -14
  76. package/dist/src/index.js +10 -75
  77. package/dist/src/manifest.js +478 -876
  78. package/dist/src/screens/billing-portal.d.ts +3 -0
  79. package/dist/src/screens/{portal.js → billing-portal.js} +32 -58
  80. package/dist/src/screens/checkout-js.d.ts +2 -0
  81. package/dist/src/screens/checkout-js.js +84 -0
  82. package/dist/src/screens/checkout.d.ts +2 -31
  83. package/dist/src/screens/checkout.js +32 -121
  84. package/dist/src/screens/connect-onboarding.d.ts +3 -0
  85. package/dist/src/screens/{onboarding.js → connect-onboarding.js} +38 -104
  86. package/dist/src/screens/dashboard.d.ts +3 -0
  87. package/dist/src/screens/dashboard.js +116 -0
  88. package/dist/src/screens/shared.d.ts +27 -0
  89. package/dist/src/screens/shared.js +87 -0
  90. package/dist/src/screens/stripe-js.d.ts +3 -0
  91. package/dist/src/screens/stripe-js.js +95 -0
  92. package/dist/src/semantics/account.d.ts +2 -0
  93. package/dist/src/semantics/account.js +8 -0
  94. package/dist/src/semantics/account_links.d.ts +2 -0
  95. package/dist/src/semantics/account_links.js +22 -0
  96. package/dist/src/semantics/accounts.d.ts +4 -0
  97. package/dist/src/semantics/accounts.js +40 -0
  98. package/dist/src/semantics/apps.d.ts +4 -0
  99. package/dist/src/semantics/{apps-secrets.js → apps.js} +14 -26
  100. package/dist/src/semantics/around.d.ts +2 -0
  101. package/dist/src/semantics/around.js +13 -0
  102. package/dist/src/semantics/balance.d.ts +2 -11
  103. package/dist/src/semantics/balance.js +3 -194
  104. package/dist/src/semantics/balance_transactions.d.ts +2 -0
  105. package/dist/src/semantics/balance_transactions.js +15 -0
  106. package/dist/src/semantics/billing_portal.d.ts +4 -0
  107. package/dist/src/semantics/billing_portal.js +36 -0
  108. package/dist/src/semantics/charges.d.ts +3 -28
  109. package/dist/src/semantics/charges.js +5 -202
  110. package/dist/src/semantics/checkout.d.ts +3 -20
  111. package/dist/src/semantics/checkout.js +21 -271
  112. package/dist/src/semantics/clock.d.ts +2 -0
  113. package/dist/src/semantics/clock.js +15 -0
  114. package/dist/src/semantics/coupons.d.ts +2 -6
  115. package/dist/src/semantics/coupons.js +2 -60
  116. package/dist/src/semantics/customers.d.ts +5 -6
  117. package/dist/src/semantics/customers.js +47 -413
  118. package/dist/src/semantics/doors.d.ts +23 -0
  119. package/dist/src/semantics/doors.js +73 -0
  120. package/dist/src/semantics/entitlements.d.ts +0 -2
  121. package/dist/src/semantics/entitlements.js +4 -95
  122. package/dist/src/semantics/events.d.ts +11 -0
  123. package/dist/src/semantics/events.js +31 -0
  124. package/dist/src/semantics/index.d.ts +2 -0
  125. package/dist/src/semantics/index.js +85 -0
  126. package/dist/src/semantics/invoice_payments.d.ts +2 -0
  127. package/dist/src/semantics/invoice_payments.js +12 -0
  128. package/dist/src/semantics/invoices.d.ts +11 -18
  129. package/dist/src/semantics/invoices.js +121 -440
  130. package/dist/src/semantics/issuing.d.ts +6 -13
  131. package/dist/src/semantics/issuing.js +58 -556
  132. package/dist/src/semantics/payment_intents.d.ts +3 -0
  133. package/dist/src/semantics/payment_intents.js +71 -0
  134. package/dist/src/semantics/payment_methods.d.ts +3 -0
  135. package/dist/src/semantics/payment_methods.js +15 -0
  136. package/dist/src/semantics/payouts.d.ts +3 -0
  137. package/dist/src/semantics/payouts.js +28 -0
  138. package/dist/src/semantics/prices.d.ts +4 -0
  139. package/dist/src/semantics/prices.js +37 -0
  140. package/dist/src/semantics/products.d.ts +4 -2
  141. package/dist/src/semantics/products.js +12 -138
  142. package/dist/src/semantics/promotion_codes.d.ts +3 -0
  143. package/dist/src/semantics/promotion_codes.js +35 -0
  144. package/dist/src/semantics/radar.d.ts +2 -2
  145. package/dist/src/semantics/radar.js +5 -74
  146. package/dist/src/semantics/refunds.d.ts +2 -9
  147. package/dist/src/semantics/refunds.js +3 -193
  148. package/dist/src/semantics/shared.d.ts +558 -55
  149. package/dist/src/semantics/shared.js +2070 -114
  150. package/dist/src/semantics/states.d.ts +462 -0
  151. package/dist/src/semantics/states.js +634 -0
  152. package/dist/src/semantics/subscriptions.d.ts +6 -11
  153. package/dist/src/semantics/subscriptions.js +37 -530
  154. package/dist/src/semantics/test_helpers.d.ts +3 -0
  155. package/dist/src/semantics/test_helpers.js +125 -0
  156. package/dist/src/semantics/transfers.d.ts +2 -2
  157. package/dist/src/semantics/transfers.js +6 -101
  158. package/dist/src/semantics/webhook_endpoints.d.ts +2 -0
  159. package/dist/src/semantics/webhook_endpoints.js +26 -0
  160. package/dist/src/server.d.ts +7 -0
  161. package/dist/src/server.js +7 -0
  162. package/generated/pack-facts.json +94 -0
  163. package/journeys/coverage.json +596 -0
  164. package/journeys/customer-life.json +6108 -0
  165. package/journeys/customer-life.outline.md +371 -0
  166. package/journeys/decisions.json +677 -0
  167. package/journeys/demand.json +706 -0
  168. package/journeys/score.json +853 -0
  169. package/journeys/unreachable.json +102 -0
  170. package/journeys/vendor-examples.json +8010 -0
  171. package/package.json +11 -20
  172. package/spec/SOURCE.md +18 -0
  173. package/spec/doc-examples.json +445 -0
  174. package/spec/fixtures3.json.gz +0 -0
  175. package/spec/openapi.json.gz +0 -0
  176. package/spec/patches.json +34 -0
  177. package/spec/sources.json +306 -0
  178. package/src/cli.ts +11 -28
  179. package/src/engine/after-payment.ts +29 -0
  180. package/src/engine/apps-secrets.ts +4 -0
  181. package/src/engine/balance.ts +32 -0
  182. package/src/engine/checkout.ts +39 -0
  183. package/src/engine/common.ts +49 -0
  184. package/src/engine/connect.ts +106 -0
  185. package/src/engine/customers.ts +10 -0
  186. package/src/engine/display.ts +18 -0
  187. package/src/engine/files.ts +28 -0
  188. package/src/engine/invoices.ts +102 -0
  189. package/src/engine/issuing.ts +66 -0
  190. package/src/engine/ledger.ts +48 -0
  191. package/src/engine/oauth.ts +18 -0
  192. package/src/engine/onboarding.ts +53 -0
  193. package/src/{stripe-params.ts → engine/params.ts} +7 -56
  194. package/src/engine/payment-intents.ts +32 -0
  195. package/src/engine/payment-methods.ts +24 -0
  196. package/src/engine/radar.ts +6 -0
  197. package/src/engine/refunds.ts +3 -0
  198. package/src/engine/renewals.ts +72 -0
  199. package/src/{stripe-twin.ts → engine/stripe.ts} +57 -400
  200. package/src/engine/subscriptions.ts +37 -0
  201. package/src/engine/transfers.ts +22 -0
  202. package/src/{stripe-version.ts → engine/version.ts} +19 -10
  203. package/src/engine/webhook-endpoints.ts +14 -0
  204. package/src/engine/webhooks.ts +70 -0
  205. package/src/fetch.ts +27 -0
  206. package/src/generated/surface.gen.json +1 -1
  207. package/src/generated/ui.gen.json +1 -1
  208. package/src/index.ts +10 -116
  209. package/src/manifest.ts +480 -904
  210. package/src/screens/{portal.tsx → billing-portal.tsx} +35 -42
  211. package/src/screens/checkout-js.ts +80 -0
  212. package/src/screens/checkout.tsx +32 -96
  213. package/src/screens/{onboarding.tsx → connect-onboarding.tsx} +39 -85
  214. package/src/screens/dashboard.tsx +178 -0
  215. package/src/screens/shared.tsx +84 -0
  216. package/src/screens/stripe-js.ts +102 -0
  217. package/src/semantics/account.ts +10 -0
  218. package/src/semantics/account_links.ts +20 -0
  219. package/src/semantics/accounts.ts +44 -0
  220. package/src/semantics/{apps-secrets.ts → apps.ts} +17 -33
  221. package/src/semantics/around.ts +17 -0
  222. package/src/semantics/balance.ts +6 -208
  223. package/src/semantics/balance_transactions.ts +18 -0
  224. package/src/semantics/billing_portal.ts +45 -0
  225. package/src/semantics/charges.ts +8 -212
  226. package/src/semantics/checkout.ts +25 -276
  227. package/src/semantics/clock.ts +19 -0
  228. package/src/semantics/coupons.ts +5 -68
  229. package/src/semantics/customers.ts +48 -414
  230. package/src/semantics/doors.ts +79 -0
  231. package/src/semantics/entitlements.ts +3 -94
  232. package/src/semantics/events.ts +37 -0
  233. package/src/semantics/index.ts +89 -0
  234. package/src/semantics/invoice_payments.ts +16 -0
  235. package/src/semantics/invoices.ts +112 -441
  236. package/src/semantics/issuing.ts +57 -573
  237. package/src/semantics/payment_intents.ts +76 -0
  238. package/src/semantics/payment_methods.ts +20 -0
  239. package/src/semantics/payouts.ts +29 -0
  240. package/src/semantics/prices.ts +41 -0
  241. package/src/semantics/products.ts +12 -146
  242. package/src/semantics/promotion_codes.ts +38 -0
  243. package/src/semantics/radar.ts +8 -79
  244. package/src/semantics/refunds.ts +4 -216
  245. package/src/semantics/shared.ts +2089 -135
  246. package/src/semantics/states.ts +662 -0
  247. package/src/semantics/subscriptions.ts +39 -542
  248. package/src/semantics/test_helpers.ts +119 -0
  249. package/src/semantics/transfers.ts +10 -132
  250. package/src/semantics/webhook_endpoints.ts +27 -0
  251. package/src/server.ts +7 -0
  252. package/client/dashboard-api.ts +0 -286
  253. package/client/stripe-mirror.css +0 -277
  254. package/client/stripe-mirror.tsx +0 -1559
  255. package/dist/client/dashboard-api.d.ts +0 -107
  256. package/dist/client/dashboard-api.js +0 -238
  257. package/dist/client/dashboard-api.ts +0 -286
  258. package/dist/client/stripe-mirror.bundle.js +0 -236
  259. package/dist/client/stripe-mirror.css +0 -277
  260. package/dist/client/stripe-mirror.d.ts +0 -134
  261. package/dist/client/stripe-mirror.js +0 -859
  262. package/dist/client/stripe-mirror.tsx +0 -1559
  263. package/dist/src/screens/connect-oauth.d.ts +0 -27
  264. package/dist/src/screens/connect-oauth.js +0 -414
  265. package/dist/src/screens/connect-settings.d.ts +0 -22
  266. package/dist/src/screens/connect-settings.js +0 -103
  267. package/dist/src/screens/consent-skin.d.ts +0 -4
  268. package/dist/src/screens/consent-skin.js +0 -18
  269. package/dist/src/screens/financial-connections.d.ts +0 -5
  270. package/dist/src/screens/financial-connections.js +0 -90
  271. package/dist/src/screens/identity.d.ts +0 -5
  272. package/dist/src/screens/identity.js +0 -86
  273. package/dist/src/screens/onboarding.d.ts +0 -13
  274. package/dist/src/screens/portal.d.ts +0 -5
  275. package/dist/src/screens/public-details.d.ts +0 -5
  276. package/dist/src/screens/public-details.js +0 -90
  277. package/dist/src/semantics/after-payment.d.ts +0 -22
  278. package/dist/src/semantics/after-payment.js +0 -99
  279. package/dist/src/semantics/apps-secrets.d.ts +0 -2
  280. package/dist/src/semantics/billing.d.ts +0 -2
  281. package/dist/src/semantics/billing.js +0 -220
  282. package/dist/src/semantics/connect.d.ts +0 -5
  283. package/dist/src/semantics/connect.js +0 -493
  284. package/dist/src/semantics/credit-notes.d.ts +0 -2
  285. package/dist/src/semantics/credit-notes.js +0 -172
  286. package/dist/src/semantics/disputes.d.ts +0 -2
  287. package/dist/src/semantics/disputes.js +0 -51
  288. package/dist/src/semantics/ephemeral-keys.d.ts +0 -2
  289. package/dist/src/semantics/ephemeral-keys.js +0 -34
  290. package/dist/src/semantics/files.d.ts +0 -2
  291. package/dist/src/semantics/files.js +0 -125
  292. package/dist/src/semantics/ledger.d.ts +0 -59
  293. package/dist/src/semantics/ledger.js +0 -200
  294. package/dist/src/semantics/payment-intents.d.ts +0 -18
  295. package/dist/src/semantics/payment-intents.js +0 -452
  296. package/dist/src/semantics/payment-links.d.ts +0 -2
  297. package/dist/src/semantics/payment-links.js +0 -133
  298. package/dist/src/semantics/payment-methods.d.ts +0 -20
  299. package/dist/src/semantics/payment-methods.js +0 -140
  300. package/dist/src/semantics/plans.d.ts +0 -5
  301. package/dist/src/semantics/plans.js +0 -121
  302. package/dist/src/semantics/platform.d.ts +0 -9
  303. package/dist/src/semantics/platform.js +0 -206
  304. package/dist/src/semantics/renewals.d.ts +0 -47
  305. package/dist/src/semantics/renewals.js +0 -281
  306. package/dist/src/semantics/setup-intents.d.ts +0 -2
  307. package/dist/src/semantics/setup-intents.js +0 -84
  308. package/dist/src/semantics/subscription-schedules.d.ts +0 -2
  309. package/dist/src/semantics/subscription-schedules.js +0 -119
  310. package/dist/src/semantics/tax.d.ts +0 -2
  311. package/dist/src/semantics/tax.js +0 -197
  312. package/dist/src/semantics/terminal.d.ts +0 -5
  313. package/dist/src/semantics/terminal.js +0 -182
  314. package/dist/src/semantics/test-clocks.d.ts +0 -6
  315. package/dist/src/semantics/test-clocks.js +0 -73
  316. package/dist/src/semantics/tokens.d.ts +0 -4
  317. package/dist/src/semantics/tokens.js +0 -44
  318. package/dist/src/semantics/treasury.d.ts +0 -2
  319. package/dist/src/semantics/treasury.js +0 -377
  320. package/dist/src/semantics/webhook-endpoints.d.ts +0 -3
  321. package/dist/src/semantics/webhook-endpoints.js +0 -85
  322. package/dist/src/stripe-budget.d.ts +0 -55
  323. package/dist/src/stripe-budget.js +0 -155
  324. package/dist/src/stripe-capabilities.d.ts +0 -3
  325. package/dist/src/stripe-capabilities.js +0 -5836
  326. package/dist/src/stripe-conformance.d.ts +0 -43
  327. package/dist/src/stripe-conformance.js +0 -105
  328. package/dist/src/stripe-connector.d.ts +0 -161
  329. package/dist/src/stripe-connector.js +0 -414
  330. package/dist/src/stripe-emit.d.ts +0 -2
  331. package/dist/src/stripe-emit.js +0 -145
  332. package/dist/src/stripe-events.d.ts +0 -93
  333. package/dist/src/stripe-events.js +0 -392
  334. package/dist/src/stripe-js.d.ts +0 -4
  335. package/dist/src/stripe-js.js +0 -70
  336. package/dist/src/stripe-mirror-ui.d.ts +0 -15
  337. package/dist/src/stripe-mirror-ui.js +0 -87
  338. package/dist/src/stripe-perform-harness.d.ts +0 -9
  339. package/dist/src/stripe-perform-harness.js +0 -26
  340. package/dist/src/stripe-server.d.ts +0 -33
  341. package/dist/src/stripe-server.js +0 -429
  342. package/dist/src/stripe-shared.d.ts +0 -109
  343. package/dist/src/stripe-shared.js +0 -276
  344. package/dist/src/stripe-ui-conformance.d.ts +0 -5
  345. package/dist/src/stripe-ui-conformance.js +0 -79
  346. package/dist/src/stripe-ui-structure.d.ts +0 -3
  347. package/dist/src/stripe-ui-structure.js +0 -168
  348. package/dist/test-fixtures/stripe-known-deviations.json +0 -110
  349. package/dist/test-fixtures/stripe-openapi-operations.SOURCE.md +0 -14
  350. package/dist/test-fixtures/stripe-openapi-operations.json +0 -4717
  351. package/dist/test-fixtures/stripe-schemas.SOURCE.md +0 -35
  352. package/dist/test-fixtures/stripe-schemas.json +0 -3813
  353. package/src/screens/connect-oauth.tsx +0 -400
  354. package/src/screens/connect-settings.tsx +0 -121
  355. package/src/screens/consent-skin.ts +0 -20
  356. package/src/screens/financial-connections.tsx +0 -101
  357. package/src/screens/identity.tsx +0 -96
  358. package/src/screens/public-details.tsx +0 -105
  359. package/src/semantics/after-payment.ts +0 -118
  360. package/src/semantics/billing.ts +0 -216
  361. package/src/semantics/connect.ts +0 -487
  362. package/src/semantics/credit-notes.ts +0 -168
  363. package/src/semantics/disputes.ts +0 -62
  364. package/src/semantics/ephemeral-keys.ts +0 -34
  365. package/src/semantics/files.ts +0 -143
  366. package/src/semantics/ledger.ts +0 -253
  367. package/src/semantics/payment-intents.ts +0 -463
  368. package/src/semantics/payment-links.ts +0 -148
  369. package/src/semantics/payment-methods.ts +0 -145
  370. package/src/semantics/plans.ts +0 -131
  371. package/src/semantics/platform.ts +0 -220
  372. package/src/semantics/renewals.ts +0 -279
  373. package/src/semantics/setup-intents.ts +0 -87
  374. package/src/semantics/subscription-schedules.ts +0 -129
  375. package/src/semantics/tax.ts +0 -220
  376. package/src/semantics/terminal.ts +0 -195
  377. package/src/semantics/test-clocks.ts +0 -77
  378. package/src/semantics/tokens.ts +0 -52
  379. package/src/semantics/treasury.ts +0 -383
  380. package/src/semantics/webhook-endpoints.ts +0 -87
  381. package/src/stripe-budget.ts +0 -181
  382. package/src/stripe-capabilities.ts +0 -5651
  383. package/src/stripe-conformance.ts +0 -124
  384. package/src/stripe-connector.ts +0 -462
  385. package/src/stripe-emit.ts +0 -157
  386. package/src/stripe-events.ts +0 -434
  387. package/src/stripe-js.ts +0 -70
  388. package/src/stripe-mirror-ui.ts +0 -90
  389. package/src/stripe-perform-harness.ts +0 -29
  390. package/src/stripe-server.ts +0 -393
  391. package/src/stripe-shared.ts +0 -297
  392. package/src/stripe-ui-conformance.ts +0 -88
  393. package/src/stripe-ui-structure.ts +0 -182
  394. package/test-fixtures/stripe-known-deviations.json +0 -110
  395. package/test-fixtures/stripe-openapi-operations.json +0 -4717
  396. package/test-fixtures/stripe-schemas.json +0 -3813
  397. /package/dist/src/{screens → engine}/industries.d.ts +0 -0
  398. /package/dist/src/{screens → engine}/industries.js +0 -0
  399. /package/dist/src/{semantics → engine}/test-cards.d.ts +0 -0
  400. /package/dist/src/{semantics → engine}/test-cards.js +0 -0
  401. /package/src/{screens → engine}/industries.ts +0 -0
  402. /package/src/{semantics → engine}/test-cards.ts +0 -0
@@ -1,297 +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
-
6
- export type StripeRow = Record<string, any>;
7
-
8
- /** The name an account shows its customers (Checkout, the customer portal): its public business name,
9
- * `business_profile.name` ("The customer-facing business name", docs.stripe.com/api/accounts/object), which the
10
- * operator sets on the Dashboard ("You can change a Checkout page's name by modifying the Business name field",
11
- * docs.stripe.com/payments/checkout/customization/appearance). Where the documentation stops and the twin decides:
12
- * with none set it falls back to the Dashboard's account name, `settings.dashboard.display_name` ("used on the Stripe
13
- * Dashboard to differentiate between accounts", the same object page), and with neither to "Twin Inc.", the name the
14
- * Dashboard mirror has always given the World's own account. */
15
- export const PLATFORM_DEFAULT_NAME = 'Twin Inc.';
16
- /** The bookkeeping type of a connected account's Connect OAuth connection (screens/connect-oauth.tsx): one row per
17
- * account, `revoked: true` once deauthorized or its code reused. Read by the account list and the event path too. */
18
- export const OAUTH_CONNECTIONS = '_oauth_connection';
19
- export function publicBusinessName(account: StripeRow | undefined): string {
20
- const named = (v: unknown): string | undefined => (typeof v === 'string' && v.trim() ? v : undefined);
21
- return named(account?.business_profile?.name) ?? named(account?.settings?.dashboard?.display_name) ?? PLATFORM_DEFAULT_NAME;
22
- }
23
-
24
- /** Zero-decimal currencies (Stripe stores these in whole units, not cents). */
25
- const ZERO_DECIMAL = new Set(['bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf']);
26
-
27
- /**
28
- * Format a Stripe minor-unit amount (cents) as a localized currency string.
29
- * Honors zero-decimal currencies (¥4200 not ¥42.00). Non-numbers → an em dash.
30
- */
31
- export function formatStripeAmount(value: unknown, currency?: string): string {
32
- if (typeof value !== 'number' || !Number.isFinite(value)) return '—';
33
- const ccy = String(currency ?? 'usd').toLowerCase();
34
- const zero = ZERO_DECIMAL.has(ccy);
35
- const major = zero ? value : value / 100;
36
- try {
37
- return new Intl.NumberFormat('en-US', {
38
- style: 'currency', currency: ccy.toUpperCase(),
39
- minimumFractionDigits: zero ? 0 : 2, maximumFractionDigits: zero ? 0 : 2,
40
- }).format(major);
41
- } catch {
42
- // Unknown/invalid currency code → a stable, readable fallback.
43
- return `${zero ? major : major.toFixed(2)} ${ccy.toUpperCase()}`;
44
- }
45
- }
46
-
47
- /**
48
- * Render a Stripe price's `recurring` block as a short interval label, e.g.
49
- * "every month", "every 3 months". Returns '' when it isn't a recurring price.
50
- */
51
- export function formatRecurring(recurring: unknown): string {
52
- if (!recurring || typeof recurring !== 'object') return '';
53
- const r = recurring as Record<string, unknown>;
54
- const interval = typeof r.interval === 'string' ? r.interval : '';
55
- if (!interval) return '';
56
- const count = Number(r.interval_count);
57
- return count > 1 ? `every ${count} ${interval}s` : `every ${interval}`;
58
- }
59
-
60
- /**
61
- * Render a saved payment method as a short human label, e.g. "Visa •••• 4242"
62
- * for a card, or the bare `type` ("us_bank_account") for non-card methods.
63
- */
64
- export function formatPaymentMethod(pm: unknown): string {
65
- if (!pm || typeof pm !== 'object') return '—';
66
- const m = pm as Record<string, any>;
67
- const card = m.card && typeof m.card === 'object' ? (m.card as Record<string, any>) : undefined;
68
- if (card && (card.brand || card.last4)) {
69
- const brand = card.brand ? String(card.brand).replace(/\b\w/g, (c) => c.toUpperCase()) : 'Card';
70
- return card.last4 ? `${brand} •••• ${card.last4}` : brand;
71
- }
72
- return typeof m.type === 'string' && m.type ? m.type : (m.id ?? '—');
73
- }
74
-
75
- /**
76
- * Extract the HTTP(S) image URLs from a product's `images` field (Stripe stores an
77
- * array of URL strings) so the mirror can render them as <img> thumbnails instead
78
- * of plain text. Non-arrays / non-URL entries are dropped. Order is preserved.
79
- */
80
- export function productImageUrls(images: unknown): string[] {
81
- if (!Array.isArray(images)) return [];
82
- return images.filter((u): u is string => typeof u === 'string' && /^https?:\/\//i.test(u));
83
- }
84
-
85
- /**
86
- * Render a payment_intent / charge `last_payment_error` (the test-card decline state)
87
- * as a single human-readable line, e.g. "card_declined (insufficient_funds): Your card
88
- * has insufficient funds." Returns '' when there is no error object. This is the
89
- * vendor-faithful decline reason the twin populates on a declined confirm.
90
- */
91
- export function formatPaymentError(error: unknown): string {
92
- if (!error || typeof error !== 'object') return '';
93
- const e = error as Record<string, any>;
94
- const code = typeof e.code === 'string' ? e.code : '';
95
- const declineCode = typeof e.decline_code === 'string' ? e.decline_code : '';
96
- const message = typeof e.message === 'string' ? e.message : '';
97
- const head = code ? (declineCode ? `${code} (${declineCode})` : code) : declineCode;
98
- if (head && message) return `${head}: ${message}`;
99
- return head || message;
100
- }
101
-
102
- /**
103
- * Summarize a synthesized Stripe `balance` object (available/pending arrays, one entry
104
- * per currency) into short per-bucket lines, e.g. ["available: $42.00", "pending: $0.00"].
105
- * The balance is not a list collection, so the mirror renders this summary directly.
106
- */
107
- export function formatBalanceSummary(balance: unknown): Array<{ bucket: string; text: string }> {
108
- if (!balance || typeof balance !== 'object') return [];
109
- const b = balance as Record<string, any>;
110
- const sum = (arr: unknown): string => {
111
- if (!Array.isArray(arr) || arr.length === 0) return formatStripeAmount(0, 'usd');
112
- return arr
113
- .map((e) => formatStripeAmount((e as Record<string, any>)?.amount, (e as Record<string, any>)?.currency))
114
- .join(', ');
115
- };
116
- const out: Array<{ bucket: string; text: string }> = [];
117
- if (Array.isArray(b.available)) out.push({ bucket: 'available', text: sum(b.available) });
118
- if (Array.isArray(b.pending)) out.push({ bucket: 'pending', text: sum(b.pending) });
119
- return out;
120
- }
121
-
122
- /**
123
- * Summarize a Connect connected `account` object's enablement state into the three
124
- * boolean capability flags a real Stripe Connect dashboard shows up front:
125
- * charges_enabled, payouts_enabled, details_submitted. Each is rendered as a tone-
126
- * carrying flag (true → ok, false → warn) so an un-onboarded account reads as such.
127
- */
128
- export type AccountFlag = { key: string; label: string; enabled: boolean };
129
- export function formatAccountFlags(account: unknown): AccountFlag[] {
130
- if (!account || typeof account !== 'object') return [];
131
- const a = account as Record<string, any>;
132
- return [
133
- { key: 'charges_enabled', label: 'Charges', enabled: a.charges_enabled === true },
134
- { key: 'payouts_enabled', label: 'Payouts', enabled: a.payouts_enabled === true },
135
- { key: 'details_submitted', label: 'Details submitted', enabled: a.details_submitted === true },
136
- ];
137
- }
138
-
139
- /**
140
- * Extract a Connect account's outstanding onboarding requirements (the
141
- * `requirements.currently_due` list real Stripe shows as "needs attention"). Returns
142
- * an ordered list of the still-due field paths; empty when nothing is due.
143
- */
144
- export function accountCurrentlyDue(account: unknown): string[] {
145
- if (!account || typeof account !== 'object') return [];
146
- const req = (account as Record<string, any>).requirements;
147
- if (!req || typeof req !== 'object') return [];
148
- const due = (req as Record<string, any>).currently_due;
149
- return Array.isArray(due) ? due.filter((d): d is string => typeof d === 'string') : [];
150
- }
151
-
152
- /** Tone for a status pill: 'ok' (green), 'warn' (amber), 'bad' (red), '' (neutral). */
153
- export type PillTone = 'ok' | 'warn' | 'bad' | '';
154
- const PILL_OK = new Set(['active', 'succeeded', 'paid', 'true', 'enabled', 'available', 'won']);
155
- 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']);
156
- const PILL_BAD = new Set(['canceled', 'cancelled', 'void', 'uncollectible', 'failed', 'incomplete_expired', 'false', 'disabled', 'lost', 'charge_refunded']);
157
- export function statusTone(value: unknown): PillTone {
158
- const v = String(value ?? '').toLowerCase();
159
- if (PILL_OK.has(v)) return 'ok';
160
- if (PILL_BAD.has(v)) return 'bad';
161
- if (PILL_WARN.has(v)) return 'warn';
162
- return '';
163
- }
164
-
165
- /** True when a key names a field whose value is a Stripe object id we can link. */
166
- export function isReferenceKey(key: string): boolean {
167
- return REFERENCE_FIELDS.has(key);
168
- }
169
- // field name → the COLLECTION it points at (so the UI can jump sections + select).
170
- const REFERENCE_FIELD_MAP: Record<string, string> = {
171
- customer: 'customers', product: 'products', price: 'prices',
172
- subscription: 'subscriptions', latest_invoice: 'invoices', invoice: 'invoices',
173
- payment_intent: 'payment_intents', latest_charge: 'charges', charge: 'charges',
174
- payment_method: 'payment_methods', default_payment_method: 'payment_methods',
175
- dispute: 'disputes', payout: 'payouts', balance_transaction: 'balance_transactions',
176
- source_transaction: 'charges', setup_intent: 'setup_intents',
177
- // Connect: a transfer's `destination` points at a connected account.
178
- account: 'accounts', destination: 'accounts',
179
- // Billing: a customer_balance_transaction may reference the credit_note that created it.
180
- credit_note: 'credit_notes',
181
- };
182
- const REFERENCE_FIELDS = new Set(Object.keys(REFERENCE_FIELD_MAP));
183
- /** The collection a reference field points at, or undefined if not a reference. */
184
- export function referenceCollection(key: string): string | undefined {
185
- return REFERENCE_FIELD_MAP[key];
186
- }
187
-
188
- /** A single line in the flattened, human-readable view of a nested value. */
189
- export type FlatLine = { depth: number; label: string; value: string; ref?: string };
190
-
191
- /**
192
- * Flatten an arbitrary nested Stripe value (object / array / scalar) into ordered,
193
- * indented label/value lines suitable for a readable detail view — instead of the
194
- * old "[object Object]". Stripe "list" wrappers ({object:'list',data:[...]}) are
195
- * unwrapped to their `data`. Amount-ish fields are currency-formatted.
196
- */
197
- export function flattenStripeValue(value: unknown, opts: { label?: string; depth?: number; currency?: string } = {}): FlatLine[] {
198
- const depth = opts.depth ?? 0;
199
- const label = opts.label ?? '';
200
- const currency = opts.currency;
201
- if (value === null || value === undefined) return [{ depth, label, value: '—' }];
202
-
203
- if (Array.isArray(value)) {
204
- if (value.length === 0) return [{ depth, label, value: '(none)' }];
205
- const out: FlatLine[] = label ? [{ depth, label, value: '' }] : [];
206
- value.forEach((item, i) => {
207
- const childDepth = label ? depth + 1 : depth;
208
- out.push(...flattenStripeValue(item, { label: `#${i + 1}`, depth: childDepth, currency }));
209
- });
210
- return out;
211
- }
212
-
213
- if (typeof value === 'object') {
214
- const obj = value as Record<string, unknown>;
215
- // Unwrap Stripe list objects to their data array.
216
- if (obj.object === 'list' && Array.isArray(obj.data)) {
217
- return flattenStripeValue(obj.data, { label, depth, currency });
218
- }
219
- const childCurrency = typeof obj.currency === 'string' ? obj.currency : currency;
220
- const keys = Object.keys(obj).filter((k) => obj[k] !== null && obj[k] !== undefined && k !== 'object');
221
- if (keys.length === 0) return [{ depth, label, value: '(empty)' }];
222
- const out: FlatLine[] = label ? [{ depth, label, value: '' }] : [];
223
- const childDepth = label ? depth + 1 : depth;
224
- for (const k of keys) out.push(...flattenStripeValue(obj[k], { label: k, depth: childDepth, currency: childCurrency }));
225
- return out;
226
- }
227
-
228
- // scalar
229
- const ref = typeof value === 'string' && isReferenceKey(label) ? value : undefined;
230
- const isMoney = typeof value === 'number' && (label === 'unit_amount' || /amount|total|subtotal|balance/.test(label));
231
- const rendered = isMoney ? formatStripeAmount(value, currency) : String(value);
232
- return [{ depth, label, value: rendered, ...(ref ? { ref } : {}) }];
233
- }
234
-
235
- /**
236
- * Resolve the cross-references for a row: the rows in other collections that this
237
- * row points AT (outgoing, e.g. invoice→customer) and the rows that point BACK at
238
- * it (incoming, e.g. customer←subscriptions). Resolved purely from already-fetched
239
- * collection data, so the UI can render clickable links without extra requests.
240
- */
241
- export type RefLink = { collection: string; id: string; label: string };
242
- export type CrossRefs = { outgoing: RefLink[]; incoming: RefLink[] };
243
-
244
- const LABELERS: Record<string, (r: StripeRow) => string> = {
245
- customers: (r) => r.name || r.email || r.id,
246
- products: (r) => r.name || r.id,
247
- prices: (r) => `${formatStripeAmount(r.unit_amount, r.currency)}${formatRecurring(r.recurring) ? ` ${formatRecurring(r.recurring)}` : ''}`,
248
- subscriptions: (r) => `${r.status ?? 'subscription'} · ${r.id}`,
249
- invoices: (r) => `${r.status ?? 'invoice'} · ${formatStripeAmount(r.total ?? r.amount_due, r.currency)}`,
250
- payment_intents: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? ''}`,
251
- charges: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? ''}`,
252
- refunds: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'refund'}`,
253
- payment_methods: (r) => `${formatPaymentMethod(r)} · ${r.id}`,
254
- disputes: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'dispute'}`,
255
- payouts: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'payout'}`,
256
- balance_transactions: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.type ?? 'txn'}`,
257
- events: (r) => `${r.type ?? 'event'} · ${r.id}`,
258
- setup_intents: (r) => `${r.status ?? 'setup_intent'} · ${r.id}`,
259
- invoiceitems: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.id}`,
260
- accounts: (r) => `${r.email || r.id} · ${r.type ?? 'account'}`,
261
- transfers: (r) => `${formatStripeAmount(r.amount, r.currency)} → ${r.destination ?? '?'}`,
262
- credit_notes: (r) => `${formatStripeAmount(r.amount, r.currency)} · ${r.status ?? 'credit_note'}`,
263
- tax_ids: (r) => `${r.value ?? r.id} · ${r.type ?? ''}`,
264
- };
265
- function labelFor(collection: string, row: StripeRow): string {
266
- return (LABELERS[collection] ?? ((r: StripeRow) => r.id))(row);
267
- }
268
-
269
- export function resolveCrossRefs(
270
- collection: string,
271
- row: StripeRow,
272
- data: Record<string, StripeRow[]>,
273
- ): CrossRefs {
274
- const outgoing: RefLink[] = [];
275
- const incoming: RefLink[] = [];
276
- if (!row) return { outgoing, incoming };
277
-
278
- // Outgoing: every reference field on this row that we can resolve to a row.
279
- for (const [key, value] of Object.entries(row)) {
280
- if (typeof value !== 'string' || !isReferenceKey(key)) continue;
281
- const target = referenceCollection(key)!;
282
- const found = (data[target] ?? []).find((r) => r.id === value);
283
- outgoing.push({ collection: target, id: value, label: `${key}: ${found ? labelFor(target, found) : value}` });
284
- }
285
-
286
- // Incoming: rows in other collections whose reference field points at this row.
287
- for (const [other, rows] of Object.entries(data)) {
288
- if (other === collection) continue;
289
- for (const r of rows) {
290
- for (const [key, value] of Object.entries(r)) {
291
- if (value !== row.id || !isReferenceKey(key)) continue;
292
- incoming.push({ collection: other, id: r.id, label: `${labelFor(other, r)}` });
293
- }
294
- }
295
- }
296
- return { outgoing, incoming };
297
- }
@@ -1,88 +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, type UiSurface, type UiCompletenessReport } from '@volter/world-tooling';
15
-
16
- /** What Stripe's Dashboard shows, classified vs the twin + its Dashboard. */
17
- export const STRIPE_UI_INVENTORY: UiSurface[] = [
18
- // --- shell ---
19
- { key: 'navigation', label: 'Left navigation (Home, Balances, Transactions, Customers, Product catalog, Billing, Developers)', status: 'rendered' },
20
- { key: 'testModeBand', label: 'Test-mode band', status: 'rendered' },
21
- { key: 'search', label: 'Search across customers, payments, subscriptions, invoices, products', status: 'rendered' },
22
- { key: 'statusPill', label: "Status pills in Stripe's words (Succeeded, Refunded, Failed, Active, Trialing, Paid, …)", status: 'rendered' },
23
- { key: 'amountFormatting', label: 'Currency-formatted amounts with the currency code', status: 'rendered' },
24
-
25
- // --- Home and Balances ---
26
- { key: 'homeToday', label: "Home: today's gross volume, balance and payouts", status: 'rendered' },
27
- { key: 'homeOverview', label: 'Home: overview metrics (gross/net volume, successful and failed payments, customers, subscribers)', status: 'rendered' },
28
- { key: 'balanceSummary', label: 'Balances: incoming and available per currency', status: 'rendered' },
29
- { key: 'balanceTransactions', label: 'Balances: recent activity (balance transactions) and payouts', status: 'rendered' },
30
-
31
- // --- Payments ---
32
- { key: 'paymentList', label: 'Payments list: amount + currency, status, payment method, description, customer, date', status: 'rendered' },
33
- { key: 'paymentFilters', label: 'Payments status tabs with counts, and filter chips', status: 'rendered' },
34
- { key: 'paymentRefundedDate', label: 'Payments list: refunded date and decline reason', status: 'rendered' },
35
- { key: 'paymentExport', label: 'Payments export', status: 'rendered' },
36
- { key: 'paymentTimeline', label: "A payment's timeline from its events", status: 'rendered' },
37
- { key: 'paymentBreakdown', label: "A payment's breakdown (amount, refunded, net)", status: 'rendered' },
38
- { key: 'paymentFees', label: "A payment's Stripe fees (balance transaction fee details)", status: 'unmodeled' },
39
- { key: 'paymentRefunds', label: "A payment's refunds", status: 'rendered' },
40
- { key: 'paymentMethodDetails', label: "A payment's card: last four, expiry, type, origin, CVC check", status: 'rendered' },
41
- { key: 'paymentDecline', label: 'A declined payment states its error and decline code', status: 'rendered' },
42
- { key: 'refundDialog', label: 'Refund a payment in full or in part, with a reason', status: 'rendered' },
43
- { key: 'disputes', label: 'Disputes', status: 'rendered' },
44
-
45
- // --- Customers ---
46
- { key: 'customerList', label: 'Customers list: name, email, default payment method, created, total spend, payments, refunds', status: 'rendered' },
47
- { key: 'createCustomer', label: 'Create customer', status: 'rendered' },
48
- { key: 'customerDetails', label: "A customer's details (ID, since, email, description, billing details)", status: 'rendered' },
49
- { key: 'customerSubscriptions', label: "A customer's subscriptions", status: 'rendered' },
50
- { key: 'customerPayments', label: "A customer's payments", status: 'rendered' },
51
- { key: 'customerPaymentMethods', label: "A customer's saved payment methods, default marked", status: 'rendered' },
52
- { key: 'customerInvoices', label: "A customer's invoices", status: 'rendered' },
53
- { key: 'customerEvents', label: "A customer's events", status: 'rendered' },
54
-
55
- // --- Billing ---
56
- { key: 'subscriptionList', label: 'Subscriptions list: customer, status, billing, product, amount, created', status: 'rendered' },
57
- { key: 'subscriptionDetails', label: "A subscription's details: customer, period, trial, billing method, payment method", status: 'rendered' },
58
- { key: 'subscriptionPricing', label: "A subscription's pricing items", status: 'rendered' },
59
- { key: 'cancelSubscription', label: 'Cancel a subscription now or at period end', status: 'rendered' },
60
- { key: 'invoiceList', label: 'Invoices list: amount, status, number, customer, due, created', status: 'rendered' },
61
- { key: 'invoiceDetail', label: "An invoice's summary lines and totals", status: 'rendered' },
62
- { key: 'quotes', label: 'Quotes', status: 'rendered' },
63
-
64
- // --- Product catalog ---
65
- { key: 'productCatalog', label: 'Product catalog: name, pricing, created, updated', status: 'rendered' },
66
- { key: 'createProduct', label: 'Create product', status: 'rendered' },
67
- { key: 'coupons', label: 'Coupons', status: 'rendered' },
68
-
69
- // --- Developers and Settings ---
70
- { key: 'apiKeys', label: 'API keys', status: 'rendered' },
71
- { key: 'webhooks', label: 'Webhook endpoints', status: 'rendered' },
72
- { key: 'eventsLog', label: 'Events', status: 'rendered' },
73
- { key: 'payoutSchedule', label: 'Settings: payout schedule', status: 'rendered' },
74
-
75
- // --- under More ---
76
- { key: 'connectAccounts', label: 'Connect: connected accounts, readiness flags and requirements due', status: 'rendered' },
77
- { key: 'connectTransfers', label: 'Connect: transfers', status: 'rendered' },
78
- { key: 'radar', label: 'Radar: reviews, lists, rules', status: 'rendered' },
79
- { key: 'terminal', label: 'Terminal: readers, locations', status: 'rendered' },
80
- { key: 'issuing', label: 'Issuing: cards, cardholders', status: 'rendered' },
81
- { key: 'taxRates', label: 'Tax: tax rates', status: 'rendered' },
82
- { key: 'reports', label: 'Reporting: report runs', status: 'rendered' },
83
- ];
84
-
85
- /** Read-only completeness check over the declared Stripe UI inventory. */
86
- export function stripeUiConformance(): UiCompletenessReport {
87
- return checkUiCompleteness('stripe', STRIPE_UI_INVENTORY);
88
- }
@@ -1,182 +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, type UiStructureReport } from '@volter/world-tooling';
16
- import {
17
- SECTIONS, SideNav, ListPane, TestModeBand, PaymentsTable, PaymentDetailView, CustomerDetailView,
18
- SubscriptionDetailView, BalanceSummary, ConnectAccountPanel,
19
- } from '../client/stripe-mirror.tsx';
20
- import type { CustomerDetail, Payment, PaymentDetail, SubscriptionDetail } from '../client/dashboard-api.ts';
21
- import type { StripeRow } from './stripe-mirror-ui.ts';
22
-
23
- const noop = () => {};
24
- const AT = 1790263345;
25
-
26
- const CUSTOMER: StripeRow = { id: 'cus_twin001', object: 'customer', name: 'Ada Lovelace', email: 'ada@example.com', created: AT, invoice_settings: { default_payment_method: 'pm_twin001' }, metadata: {} };
27
- const CARD: StripeRow = { 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: {} };
28
- const INTENT: StripeRow = { 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: {} };
29
- const CHARGE: StripeRow = { 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 };
30
- const REFUND: StripeRow = { 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 };
31
- const event = (id: string, type: string, object: StripeRow, created: number): StripeRow => ({ id, object: 'event', type, created, data: { object } });
32
-
33
- const PARTIAL: PaymentDetail = {
34
- id: 'pi_twin001', amount: 30000, currency: 'usd', status: 'partially_refunded', description: 'Annual workshop seat', created: AT,
35
- customer: CUSTOMER, charge: CHARGE, intent: INTENT, paymentMethod: CARD, amountRefunded: 10000, refundedAt: AT + 60,
36
- refunds: [REFUND],
37
- events: [
38
- event('evt_3', 'charge.refunded', CHARGE, AT + 60),
39
- event('evt_2', 'payment_intent.succeeded', INTENT, AT + 1),
40
- event('evt_1', 'payment_intent.created', INTENT, AT),
41
- ],
42
- };
43
- const DECLINED_INTENT: StripeRow = {
44
- id: 'pi_twin009', object: 'payment_intent', amount: 15000, currency: 'usd', status: 'requires_payment_method', customer: 'cus_twin001', created: AT,
45
- last_payment_error: { type: 'card_error', code: 'card_declined', decline_code: 'insufficient_funds', message: 'Your card has insufficient funds.', param: 'card' },
46
- };
47
- const DECLINED: PaymentDetail = {
48
- id: 'pi_twin009', amount: 15000, currency: 'usd', status: 'failed', created: AT, customer: CUSTOMER, intent: DECLINED_INTENT,
49
- amountRefunded: 0, declineReason: 'Insufficient funds', declineMessage: 'Your card has insufficient funds.', refunds: [],
50
- events: [event('evt_9', 'payment_intent.payment_failed', DECLINED_INTENT, AT)],
51
- };
52
- const REFUNDED: Payment = { id: 'pi_twin002', amount: 2500, currency: 'usd', status: 'refunded', description: 'Twin T-shirt', created: AT, customer: CUSTOMER, paymentMethod: CARD, amountRefunded: 2500, refundedAt: AT + 30 };
53
- const PAYMENTS: Payment[] = [PARTIAL, DECLINED, REFUNDED, { ...REFUNDED, id: 'pi_twin003', status: 'succeeded', amountRefunded: 0, refundedAt: undefined, description: 'Consulting' }];
54
-
55
- const PRODUCT: StripeRow = { id: 'prod_twin001', object: 'product', name: 'Pro plan' };
56
- const SUBSCRIPTION: StripeRow = {
57
- id: 'sub_twin001', object: 'subscription', status: 'trialing', customer: 'cus_twin001', currency: 'usd', created: AT, start_date: AT,
58
- current_period_start: AT, current_period_end: AT + 14 * 86400, trial_start: AT, trial_end: AT + 14 * 86400, collection_method: 'charge_automatically',
59
- 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' } } }] },
60
- };
61
- const INVOICE: StripeRow = { 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 };
62
- const CUSTOMER_PAGE: CustomerDetail = { customer: CUSTOMER, paymentMethods: [CARD], subscriptions: [SUBSCRIPTION], invoices: [INVOICE], payments: PAYMENTS, products: new Map([[PRODUCT.id, PRODUCT]]), events: [] };
63
- const SUBSCRIPTION_PAGE: SubscriptionDetail = { subscription: SUBSCRIPTION, customer: CUSTOMER, invoices: [INVOICE], products: new Map([[PRODUCT.id, PRODUCT]]), events: [event('evt_s', 'customer.subscription.created', SUBSCRIPTION, AT)], paymentMethod: CARD };
64
-
65
- const BALANCE: StripeRow = { id: 'balance', object: 'balance', available: [{ amount: 16800, currency: 'usd' }], pending: [{ amount: 4200, currency: 'usd' }] };
66
- const ACCOUNT: StripeRow = {
67
- id: 'acct_twin001', object: 'account', type: 'express', country: 'US', charges_enabled: false, payouts_enabled: false, details_submitted: false,
68
- requirements: { currently_due: ['external_account', 'tos_acceptance.date'] },
69
- };
70
- const TAX_RATE: StripeRow = { id: 'txr_twin001', object: 'tax_rate', display_name: 'Sales Tax', percentage: 8.5, inclusive: false, active: true, jurisdiction: 'US', created: AT };
71
-
72
- const html = (el: Parameters<typeof renderToStaticMarkup>[0]) => renderToStaticMarkup(el);
73
- const count = (markup: string, needle: RegExp) => (markup.match(needle) ?? []).length;
74
-
75
- /** Build the structural checklist from the real rendered markup and run it. */
76
- export function stripeUiStructure(): UiStructureReport {
77
- const nav = html(createElement(SideNav, { route: ['payments'], go: noop }));
78
- const band = html(createElement(TestModeBand));
79
- const payments = html(createElement(PaymentsTable, { payments: PAYMENTS, go: noop }));
80
- const partial = html(createElement(PaymentDetailView, { p: PARTIAL, go: noop, onRefund: noop }));
81
- const declined = html(createElement(PaymentDetailView, { p: DECLINED, go: noop, onRefund: noop }));
82
- const customer = html(createElement(CustomerDetailView, { data: CUSTOMER_PAGE, go: noop }));
83
- const subscription = html(createElement(SubscriptionDetailView, { data: SUBSCRIPTION_PAGE, go: noop, onCancel: noop }));
84
- const balance = html(createElement(BalanceSummary, { row: BALANCE }));
85
- const account = html(createElement(ConnectAccountPanel, { row: ACCOUNT }));
86
- const taxRates = html(createElement(ListPane, { section: SECTIONS.find((s) => s.key === 'tax_rates')!, rows: [TAX_RATE], onSelect: noop }));
87
-
88
- const checks = [
89
- {
90
- key: 'navigation',
91
- label: "Left navigation: Home, Balances, Transactions, Customers, Product catalog, Billing's Subscriptions and Invoices, Developers — at Stripe's /test/ paths",
92
- present: ['>Home<', '>Balances<', '>Transactions<', '>Customers<', '>Product catalog<', '>Subscriptions<', '>Invoices<', '>Developers<'].every((l) => nav.includes(l))
93
- && nav.includes('href="/test/payments"') && nav.includes('href="/test/customers"') && nav.includes('href="/test/subscriptions"'),
94
- },
95
- {
96
- key: 'navActive',
97
- label: 'The navigation marks the section being viewed',
98
- present: /class="nav-item [^"]*active"[^>]*href="\/test\/payments"|href="\/test\/payments" class="nav-item [^"]*active"/.test(nav),
99
- },
100
- {
101
- key: 'testModeBand',
102
- label: "The orange test-mode band across the top",
103
- present: band.includes('class="test-band"') && band.includes('Test mode'),
104
- },
105
- {
106
- key: 'paymentsColumns',
107
- label: "Payments table carries Stripe's columns (Amount, Payment method, Description, Customer, Date, Refunded date, Decline reason)",
108
- present: ['>Amount<', '>Payment method<', '>Description<', '>Customer<', '>Date<', '>Refunded date<', '>Decline reason<'].every((c) => payments.includes(c)),
109
- },
110
- {
111
- key: 'paymentsRowPerPayment',
112
- label: 'Payments table emits one row per payment, amount with its currency',
113
- present: count(payments, /class="list-row"/g) === PAYMENTS.length && payments.includes('$300.00') && payments.includes('USD'),
114
- },
115
- {
116
- key: 'paymentsStatusPills',
117
- label: 'Status pills worded as Stripe words them (Succeeded, Refunded, Partial refund, Failed)',
118
- present: ['>Succeeded<', '>Refunded<', '>Partial refund<', '>Failed<'].every((l) => payments.includes(l)),
119
- },
120
- {
121
- key: 'paymentsDeclineReason',
122
- label: 'A failed payment shows its decline reason in the list',
123
- present: payments.includes('Insufficient funds'),
124
- },
125
- {
126
- key: 'paymentHeader',
127
- label: "A payment's page leads with its amount, currency and status, and a Refund control while refundable",
128
- present: partial.includes('$300.00') && partial.includes('Partial refund') && partial.includes('Refund</button>'),
129
- },
130
- {
131
- key: 'paymentTimeline',
132
- label: "A payment's timeline lists its events (started, succeeded, refunded)",
133
- present: partial.includes('class="timeline"') && partial.includes('Payment started') && partial.includes('Payment succeeded') && partial.includes('refunded'),
134
- },
135
- {
136
- key: 'paymentBreakdownAndRefunds',
137
- label: "A payment's breakdown (amount, refunded, net) and its refunds",
138
- present: partial.includes('Payment breakdown') && partial.includes('$200.00') && partial.includes('>Refunds<') && partial.includes('re_twin001'),
139
- },
140
- {
141
- key: 'paymentMethodBlock',
142
- label: "A payment's card: number's last four, expiry, type, CVC check",
143
- present: partial.includes('4242') && partial.includes('12 / 2034') && partial.includes('Visa credit card') && partial.includes('Passed'),
144
- },
145
- {
146
- key: 'paymentDecline',
147
- label: 'A declined payment states its error and decline code, and offers no refund',
148
- present: declined.includes('class="pay-error"') && declined.includes('Your card has insufficient funds.') && declined.includes('insufficient_funds') && !declined.includes('Refund</button>'),
149
- },
150
- {
151
- key: 'customerPage',
152
- label: "A customer's page: name, email, Details, Subscriptions, Payments, Payment methods, Invoices",
153
- present: customer.includes('Ada Lovelace') && customer.includes('ada@example.com')
154
- && ['>Details<', '>Subscriptions<', '>Payments<', '>Payment methods<', '>Invoices<'].every((h) => customer.includes(h))
155
- && customer.includes('Pro plan') && customer.includes('TWIN-0001') && customer.includes('>Default<'),
156
- },
157
- {
158
- key: 'subscriptionPage',
159
- label: "A subscription's page: customer on product, status, period, pricing items, invoices and Cancel subscription",
160
- present: subscription.includes('Ada Lovelace') && subscription.includes('Pro plan') && subscription.includes('>Trialing<')
161
- && subscription.includes('Current period') && subscription.includes('>Pricing<') && subscription.includes('$147.00')
162
- && subscription.includes('TWIN-0001') && subscription.includes('Cancel subscription'),
163
- },
164
- {
165
- key: 'balanceSummaryBuckets',
166
- label: 'The balance renders its incoming and available buckets, amounts formatted',
167
- present: balance.includes('class="balance-summary"') && balance.includes('Incoming') && balance.includes('Available') && balance.includes('$168.00') && balance.includes('$42.00'),
168
- },
169
- {
170
- key: 'connectAccountReadiness',
171
- label: "A connected account's charges/payouts/details flags and what is currently due",
172
- present: account.includes('class="connect-panel"') && count(account, /connect-flag /g) >= 3 && account.includes('Requirements currently due') && account.includes('external_account'),
173
- },
174
- {
175
- key: 'resourceListRow',
176
- label: 'A resource list emits one row per object (Tax rates: name and percentage)',
177
- present: count(taxRates, /list-row/g) === 1 && taxRates.includes('Sales Tax') && taxRates.includes('8.5'),
178
- },
179
- ];
180
-
181
- return checkUiStructure('stripe', checks);
182
- }