@mmailaender/convex-creem 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1176 -0
  3. package/dist/client/helpers.d.ts +17 -0
  4. package/dist/client/helpers.d.ts.map +1 -0
  5. package/dist/client/helpers.js +43 -0
  6. package/dist/client/helpers.js.map +1 -0
  7. package/dist/client/index.d.ts +1041 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +1068 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/client/parsers.d.ts +45 -0
  12. package/dist/client/parsers.d.ts.map +1 -0
  13. package/dist/client/parsers.js +138 -0
  14. package/dist/client/parsers.js.map +1 -0
  15. package/dist/client/polyfill.d.ts +2 -0
  16. package/dist/client/polyfill.d.ts.map +1 -0
  17. package/dist/client/polyfill.js +3 -0
  18. package/dist/client/polyfill.js.map +1 -0
  19. package/dist/component/_generated/api.d.ts +36 -0
  20. package/dist/component/_generated/api.d.ts.map +1 -0
  21. package/dist/component/_generated/api.js +31 -0
  22. package/dist/component/_generated/api.js.map +1 -0
  23. package/dist/component/_generated/component.d.ts +542 -0
  24. package/dist/component/_generated/component.d.ts.map +1 -0
  25. package/dist/component/_generated/component.js +11 -0
  26. package/dist/component/_generated/component.js.map +1 -0
  27. package/dist/component/_generated/dataModel.d.ts +46 -0
  28. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  29. package/dist/component/_generated/dataModel.js +11 -0
  30. package/dist/component/_generated/dataModel.js.map +1 -0
  31. package/dist/component/_generated/server.d.ts +121 -0
  32. package/dist/component/_generated/server.d.ts.map +1 -0
  33. package/dist/component/_generated/server.js +78 -0
  34. package/dist/component/_generated/server.js.map +1 -0
  35. package/dist/component/convex.config.d.ts +3 -0
  36. package/dist/component/convex.config.d.ts.map +1 -0
  37. package/dist/component/convex.config.js +3 -0
  38. package/dist/component/convex.config.js.map +1 -0
  39. package/dist/component/lib.d.ts +1005 -0
  40. package/dist/component/lib.d.ts.map +1 -0
  41. package/dist/component/lib.js +647 -0
  42. package/dist/component/lib.js.map +1 -0
  43. package/dist/component/schema.d.ts +191 -0
  44. package/dist/component/schema.d.ts.map +1 -0
  45. package/dist/component/schema.js +104 -0
  46. package/dist/component/schema.js.map +1 -0
  47. package/dist/component/util.d.ts +61 -0
  48. package/dist/component/util.d.ts.map +1 -0
  49. package/dist/component/util.js +142 -0
  50. package/dist/component/util.js.map +1 -0
  51. package/dist/core/catalog.d.ts +18 -0
  52. package/dist/core/catalog.d.ts.map +1 -0
  53. package/dist/core/catalog.js +82 -0
  54. package/dist/core/catalog.js.map +1 -0
  55. package/dist/core/index.d.ts +9 -0
  56. package/dist/core/index.d.ts.map +1 -0
  57. package/dist/core/index.js +9 -0
  58. package/dist/core/index.js.map +1 -0
  59. package/dist/core/markdown.d.ts +12 -0
  60. package/dist/core/markdown.d.ts.map +1 -0
  61. package/dist/core/markdown.js +26 -0
  62. package/dist/core/markdown.js.map +1 -0
  63. package/dist/core/payments.d.ts +11 -0
  64. package/dist/core/payments.d.ts.map +1 -0
  65. package/dist/core/payments.js +27 -0
  66. package/dist/core/payments.js.map +1 -0
  67. package/dist/core/pendingCheckout.d.ts +15 -0
  68. package/dist/core/pendingCheckout.d.ts.map +1 -0
  69. package/dist/core/pendingCheckout.js +40 -0
  70. package/dist/core/pendingCheckout.js.map +1 -0
  71. package/dist/core/resolver.d.ts +11 -0
  72. package/dist/core/resolver.d.ts.map +1 -0
  73. package/dist/core/resolver.js +106 -0
  74. package/dist/core/resolver.js.map +1 -0
  75. package/dist/core/selectors.d.ts +12 -0
  76. package/dist/core/selectors.d.ts.map +1 -0
  77. package/dist/core/selectors.js +18 -0
  78. package/dist/core/selectors.js.map +1 -0
  79. package/dist/core/subscriptionUpdate.d.ts +20 -0
  80. package/dist/core/subscriptionUpdate.d.ts.map +1 -0
  81. package/dist/core/subscriptionUpdate.js +64 -0
  82. package/dist/core/subscriptionUpdate.js.map +1 -0
  83. package/dist/core/types.d.ts +170 -0
  84. package/dist/core/types.d.ts.map +1 -0
  85. package/dist/core/types.js +15 -0
  86. package/dist/core/types.js.map +1 -0
  87. package/dist/design-system/colors/color-utils.d.ts +10 -0
  88. package/dist/design-system/colors/color-utils.d.ts.map +1 -0
  89. package/dist/design-system/colors/color-utils.js +91 -0
  90. package/dist/design-system/colors/color-utils.js.map +1 -0
  91. package/dist/design-system/colors/config.d.ts +33 -0
  92. package/dist/design-system/colors/config.d.ts.map +1 -0
  93. package/dist/design-system/colors/config.js +224 -0
  94. package/dist/design-system/colors/config.js.map +1 -0
  95. package/dist/design-system/colors/index.d.ts +3 -0
  96. package/dist/design-system/colors/index.d.ts.map +1 -0
  97. package/dist/design-system/colors/index.js +3 -0
  98. package/dist/design-system/colors/index.js.map +1 -0
  99. package/dist/design-system/rounded/config.d.ts +31 -0
  100. package/dist/design-system/rounded/config.d.ts.map +1 -0
  101. package/dist/design-system/rounded/config.js +76 -0
  102. package/dist/design-system/rounded/config.js.map +1 -0
  103. package/dist/design-system/rounded/index.d.ts +2 -0
  104. package/dist/design-system/rounded/index.d.ts.map +1 -0
  105. package/dist/design-system/rounded/index.js +2 -0
  106. package/dist/design-system/rounded/index.js.map +1 -0
  107. package/dist/design-system/typography/config.d.ts +55 -0
  108. package/dist/design-system/typography/config.d.ts.map +1 -0
  109. package/dist/design-system/typography/config.js +308 -0
  110. package/dist/design-system/typography/config.js.map +1 -0
  111. package/dist/design-system/typography/index.d.ts +3 -0
  112. package/dist/design-system/typography/index.d.ts.map +1 -0
  113. package/dist/design-system/typography/index.js +3 -0
  114. package/dist/design-system/typography/index.js.map +1 -0
  115. package/dist/design-system/typography/tokens.d.ts +23 -0
  116. package/dist/design-system/typography/tokens.d.ts.map +1 -0
  117. package/dist/design-system/typography/tokens.js +99 -0
  118. package/dist/design-system/typography/tokens.js.map +1 -0
  119. package/dist/react/hooks/useCheckoutSuccessParams.d.ts +2 -0
  120. package/dist/react/hooks/useCheckoutSuccessParams.d.ts.map +1 -0
  121. package/dist/react/hooks/useCheckoutSuccessParams.js +5 -0
  122. package/dist/react/hooks/useCheckoutSuccessParams.js.map +1 -0
  123. package/dist/react/index.d.ts +25 -0
  124. package/dist/react/index.d.ts.map +1 -0
  125. package/dist/react/index.js +22 -0
  126. package/dist/react/index.js.map +1 -0
  127. package/dist/react/primitives/BillingGate.d.ts +8 -0
  128. package/dist/react/primitives/BillingGate.d.ts.map +1 -0
  129. package/dist/react/primitives/BillingGate.js +13 -0
  130. package/dist/react/primitives/BillingGate.js.map +1 -0
  131. package/dist/react/primitives/BillingToggle.d.ts +8 -0
  132. package/dist/react/primitives/BillingToggle.d.ts.map +1 -0
  133. package/dist/react/primitives/BillingToggle.js +12 -0
  134. package/dist/react/primitives/BillingToggle.js.map +1 -0
  135. package/dist/react/primitives/CheckoutButton.d.ts +11 -0
  136. package/dist/react/primitives/CheckoutButton.d.ts.map +1 -0
  137. package/dist/react/primitives/CheckoutButton.js +21 -0
  138. package/dist/react/primitives/CheckoutButton.js.map +1 -0
  139. package/dist/react/primitives/CheckoutSuccessSummary.d.ts +7 -0
  140. package/dist/react/primitives/CheckoutSuccessSummary.d.ts.map +1 -0
  141. package/dist/react/primitives/CheckoutSuccessSummary.js +11 -0
  142. package/dist/react/primitives/CheckoutSuccessSummary.js.map +1 -0
  143. package/dist/react/primitives/CustomerPortalButton.d.ts +8 -0
  144. package/dist/react/primitives/CustomerPortalButton.d.ts.map +1 -0
  145. package/dist/react/primitives/CustomerPortalButton.js +21 -0
  146. package/dist/react/primitives/CustomerPortalButton.js.map +1 -0
  147. package/dist/react/primitives/NumberInput.d.ts +11 -0
  148. package/dist/react/primitives/NumberInput.d.ts.map +1 -0
  149. package/dist/react/primitives/NumberInput.js +18 -0
  150. package/dist/react/primitives/NumberInput.js.map +1 -0
  151. package/dist/react/primitives/OneTimeCheckoutButton.d.ts +11 -0
  152. package/dist/react/primitives/OneTimeCheckoutButton.d.ts.map +1 -0
  153. package/dist/react/primitives/OneTimeCheckoutButton.js +4 -0
  154. package/dist/react/primitives/OneTimeCheckoutButton.js.map +1 -0
  155. package/dist/react/primitives/OneTimePaymentStatusBadge.d.ts +6 -0
  156. package/dist/react/primitives/OneTimePaymentStatusBadge.d.ts.map +1 -0
  157. package/dist/react/primitives/OneTimePaymentStatusBadge.js +11 -0
  158. package/dist/react/primitives/OneTimePaymentStatusBadge.js.map +1 -0
  159. package/dist/react/primitives/PaymentWarningBanner.d.ts +7 -0
  160. package/dist/react/primitives/PaymentWarningBanner.d.ts.map +1 -0
  161. package/dist/react/primitives/PaymentWarningBanner.js +18 -0
  162. package/dist/react/primitives/PaymentWarningBanner.js.map +1 -0
  163. package/dist/react/primitives/PricingCard.d.ts +37 -0
  164. package/dist/react/primitives/PricingCard.d.ts.map +1 -0
  165. package/dist/react/primitives/PricingCard.js +125 -0
  166. package/dist/react/primitives/PricingCard.js.map +1 -0
  167. package/dist/react/primitives/PricingSection.d.ts +39 -0
  168. package/dist/react/primitives/PricingSection.d.ts.map +1 -0
  169. package/dist/react/primitives/PricingSection.js +24 -0
  170. package/dist/react/primitives/PricingSection.js.map +1 -0
  171. package/dist/react/primitives/ScheduledChangeBanner.d.ts +8 -0
  172. package/dist/react/primitives/ScheduledChangeBanner.d.ts.map +1 -0
  173. package/dist/react/primitives/ScheduledChangeBanner.js +13 -0
  174. package/dist/react/primitives/ScheduledChangeBanner.js.map +1 -0
  175. package/dist/react/primitives/SegmentControl.d.ts +11 -0
  176. package/dist/react/primitives/SegmentControl.d.ts.map +1 -0
  177. package/dist/react/primitives/SegmentControl.js +8 -0
  178. package/dist/react/primitives/SegmentControl.js.map +1 -0
  179. package/dist/react/primitives/SegmentGroup.d.ts +14 -0
  180. package/dist/react/primitives/SegmentGroup.d.ts.map +1 -0
  181. package/dist/react/primitives/SegmentGroup.js +11 -0
  182. package/dist/react/primitives/SegmentGroup.js.map +1 -0
  183. package/dist/react/primitives/TrialLimitBanner.d.ts +7 -0
  184. package/dist/react/primitives/TrialLimitBanner.d.ts.map +1 -0
  185. package/dist/react/primitives/TrialLimitBanner.js +14 -0
  186. package/dist/react/primitives/TrialLimitBanner.js.map +1 -0
  187. package/dist/react/shared.d.ts +28 -0
  188. package/dist/react/shared.d.ts.map +1 -0
  189. package/dist/react/shared.js +109 -0
  190. package/dist/react/shared.js.map +1 -0
  191. package/dist/react/widgets/BillingPortal.d.ts +9 -0
  192. package/dist/react/widgets/BillingPortal.d.ts.map +1 -0
  193. package/dist/react/widgets/BillingPortal.js +30 -0
  194. package/dist/react/widgets/BillingPortal.js.map +1 -0
  195. package/dist/react/widgets/ProductItem.d.ts +8 -0
  196. package/dist/react/widgets/ProductItem.d.ts.map +1 -0
  197. package/dist/react/widgets/ProductItem.js +14 -0
  198. package/dist/react/widgets/ProductItem.js.map +1 -0
  199. package/dist/react/widgets/ProductRoot.d.ts +16 -0
  200. package/dist/react/widgets/ProductRoot.d.ts.map +1 -0
  201. package/dist/react/widgets/ProductRoot.js +171 -0
  202. package/dist/react/widgets/ProductRoot.js.map +1 -0
  203. package/dist/react/widgets/SubscriptionItem.d.ts +27 -0
  204. package/dist/react/widgets/SubscriptionItem.d.ts.map +1 -0
  205. package/dist/react/widgets/SubscriptionItem.js +32 -0
  206. package/dist/react/widgets/SubscriptionItem.js.map +1 -0
  207. package/dist/react/widgets/SubscriptionRoot.d.ts +16 -0
  208. package/dist/react/widgets/SubscriptionRoot.d.ts.map +1 -0
  209. package/dist/react/widgets/SubscriptionRoot.js +405 -0
  210. package/dist/react/widgets/SubscriptionRoot.js.map +1 -0
  211. package/dist/react/widgets/index.d.ts +19 -0
  212. package/dist/react/widgets/index.d.ts.map +1 -0
  213. package/dist/react/widgets/index.js +16 -0
  214. package/dist/react/widgets/index.js.map +1 -0
  215. package/dist/react/widgets/productGroupContext.d.ts +6 -0
  216. package/dist/react/widgets/productGroupContext.d.ts.map +1 -0
  217. package/dist/react/widgets/productGroupContext.js +3 -0
  218. package/dist/react/widgets/productGroupContext.js.map +1 -0
  219. package/dist/react/widgets/subscriptionContext.d.ts +6 -0
  220. package/dist/react/widgets/subscriptionContext.d.ts.map +1 -0
  221. package/dist/react/widgets/subscriptionContext.js +3 -0
  222. package/dist/react/widgets/subscriptionContext.js.map +1 -0
  223. package/dist/react/widgets/types.d.ts +171 -0
  224. package/dist/react/widgets/types.d.ts.map +1 -0
  225. package/dist/react/widgets/types.js +2 -0
  226. package/dist/react/widgets/types.js.map +1 -0
  227. package/dist/svelte/index.d.ts +22 -0
  228. package/dist/svelte/index.d.ts.map +1 -0
  229. package/dist/svelte/index.js +20 -0
  230. package/dist/svelte/index.js.map +1 -0
  231. package/dist/svelte/primitives/BillingGate.svelte +28 -0
  232. package/dist/svelte/primitives/BillingToggle.svelte +27 -0
  233. package/dist/svelte/primitives/CheckoutButton.svelte +60 -0
  234. package/dist/svelte/primitives/CheckoutSuccessSummary.svelte +34 -0
  235. package/dist/svelte/primitives/CustomerPortalButton.svelte +60 -0
  236. package/dist/svelte/primitives/NumberInput.svelte +71 -0
  237. package/dist/svelte/primitives/OneTimeCheckoutButton.svelte +37 -0
  238. package/dist/svelte/primitives/OneTimePaymentStatusBadge.svelte +20 -0
  239. package/dist/svelte/primitives/PaymentWarningBanner.svelte +30 -0
  240. package/dist/svelte/primitives/PricingCard.svelte +356 -0
  241. package/dist/svelte/primitives/PricingSection.svelte +121 -0
  242. package/dist/svelte/primitives/ScheduledChangeBanner.svelte +46 -0
  243. package/dist/svelte/primitives/SegmentControl.svelte +38 -0
  244. package/dist/svelte/primitives/SegmentGroup.svelte +52 -0
  245. package/dist/svelte/primitives/TrialLimitBanner.svelte +32 -0
  246. package/dist/svelte/primitives/shared.d.ts +13 -0
  247. package/dist/svelte/primitives/shared.d.ts.map +1 -0
  248. package/dist/svelte/primitives/shared.js +87 -0
  249. package/dist/svelte/primitives/shared.js.map +1 -0
  250. package/dist/svelte/widgets/BillingPortal.svelte +55 -0
  251. package/dist/svelte/widgets/Product.svelte +35 -0
  252. package/dist/svelte/widgets/ProductRoot.svelte +428 -0
  253. package/dist/svelte/widgets/Subscription.svelte +52 -0
  254. package/dist/svelte/widgets/SubscriptionRoot.svelte +690 -0
  255. package/dist/svelte/widgets/index.d.ts +19 -0
  256. package/dist/svelte/widgets/index.d.ts.map +1 -0
  257. package/dist/svelte/widgets/index.js +16 -0
  258. package/dist/svelte/widgets/index.js.map +1 -0
  259. package/dist/svelte/widgets/productGroupContext.d.ts +6 -0
  260. package/dist/svelte/widgets/productGroupContext.d.ts.map +1 -0
  261. package/dist/svelte/widgets/productGroupContext.js +2 -0
  262. package/dist/svelte/widgets/productGroupContext.js.map +1 -0
  263. package/dist/svelte/widgets/subscriptionContext.d.ts +6 -0
  264. package/dist/svelte/widgets/subscriptionContext.d.ts.map +1 -0
  265. package/dist/svelte/widgets/subscriptionContext.js +2 -0
  266. package/dist/svelte/widgets/subscriptionContext.js.map +1 -0
  267. package/dist/svelte/widgets/types.d.ts +171 -0
  268. package/dist/svelte/widgets/types.d.ts.map +1 -0
  269. package/dist/svelte/widgets/types.js +2 -0
  270. package/dist/svelte/widgets/types.js.map +1 -0
  271. package/package.json +182 -0
  272. package/src/client/helpers.test.ts +139 -0
  273. package/src/client/helpers.ts +51 -0
  274. package/src/client/index.test.ts +1554 -0
  275. package/src/client/index.ts +1504 -0
  276. package/src/client/parsers.test.ts +1017 -0
  277. package/src/client/parsers.ts +182 -0
  278. package/src/client/polyfill.ts +2 -0
  279. package/src/component/_generated/api.ts +52 -0
  280. package/src/component/_generated/component.ts +619 -0
  281. package/src/component/_generated/dataModel.ts +60 -0
  282. package/src/component/_generated/server.ts +156 -0
  283. package/src/component/convex.config.ts +3 -0
  284. package/src/component/lib.test.ts +1359 -0
  285. package/src/component/lib.ts +726 -0
  286. package/src/component/schema.ts +112 -0
  287. package/src/component/util.test.ts +281 -0
  288. package/src/component/util.ts +228 -0
  289. package/src/core/catalog.test.ts +212 -0
  290. package/src/core/catalog.ts +119 -0
  291. package/src/core/index.ts +8 -0
  292. package/src/core/markdown.test.ts +43 -0
  293. package/src/core/markdown.ts +26 -0
  294. package/src/core/payments.test.ts +69 -0
  295. package/src/core/payments.ts +33 -0
  296. package/src/core/pendingCheckout.test.ts +44 -0
  297. package/src/core/pendingCheckout.ts +40 -0
  298. package/src/core/resolver.test.ts +283 -0
  299. package/src/core/resolver.ts +160 -0
  300. package/src/core/selectors.test.ts +119 -0
  301. package/src/core/selectors.ts +35 -0
  302. package/src/core/subscriptionUpdate.test.ts +164 -0
  303. package/src/core/subscriptionUpdate.ts +102 -0
  304. package/src/core/types.ts +220 -0
  305. package/src/design-system/README.md +40 -0
  306. package/src/design-system/base.css +27 -0
  307. package/src/design-system/colors/color-utils.ts +110 -0
  308. package/src/design-system/colors/config.ts +282 -0
  309. package/src/design-system/colors/index.ts +2 -0
  310. package/src/design-system/colors/utilities.css +2328 -0
  311. package/src/design-system/components/badges.css +65 -0
  312. package/src/design-system/components/buttons.css +256 -0
  313. package/src/design-system/components/dialog.css +218 -0
  314. package/src/design-system/components/icon-buttons.css +115 -0
  315. package/src/design-system/components/inputs.css +94 -0
  316. package/src/design-system/components/links.css +53 -0
  317. package/src/design-system/components/prose.css +67 -0
  318. package/src/design-system/components/segment-control.css +303 -0
  319. package/src/design-system/index.css +21 -0
  320. package/src/design-system/rounded/config.ts +91 -0
  321. package/src/design-system/rounded/index.ts +1 -0
  322. package/src/design-system/rounded/utilities.css +37 -0
  323. package/src/design-system/typography/config.ts +340 -0
  324. package/src/design-system/typography/index.ts +2 -0
  325. package/src/design-system/typography/tokens.ts +148 -0
  326. package/src/design-system/typography/utilities.css +728 -0
  327. package/src/library.css +20 -0
  328. package/src/react/hooks/useCheckoutSuccessParams.ts +7 -0
  329. package/src/react/index.tsx +47 -0
  330. package/src/react/primitives/BillingGate.tsx +26 -0
  331. package/src/react/primitives/BillingToggle.tsx +29 -0
  332. package/src/react/primitives/CheckoutButton.tsx +47 -0
  333. package/src/react/primitives/CheckoutSuccessSummary.tsx +36 -0
  334. package/src/react/primitives/CustomerPortalButton.tsx +50 -0
  335. package/src/react/primitives/NumberInput.tsx +83 -0
  336. package/src/react/primitives/OneTimeCheckoutButton.tsx +27 -0
  337. package/src/react/primitives/OneTimePaymentStatusBadge.tsx +18 -0
  338. package/src/react/primitives/PaymentWarningBanner.tsx +33 -0
  339. package/src/react/primitives/PricingCard.tsx +421 -0
  340. package/src/react/primitives/PricingSection.tsx +129 -0
  341. package/src/react/primitives/ScheduledChangeBanner.tsx +52 -0
  342. package/src/react/primitives/SegmentControl.tsx +32 -0
  343. package/src/react/primitives/SegmentGroup.tsx +53 -0
  344. package/src/react/primitives/TrialLimitBanner.tsx +32 -0
  345. package/src/react/shared.ts +138 -0
  346. package/src/react/widgets/BillingPortal.tsx +56 -0
  347. package/src/react/widgets/ProductItem.tsx +26 -0
  348. package/src/react/widgets/ProductRoot.tsx +441 -0
  349. package/src/react/widgets/SubscriptionItem.tsx +71 -0
  350. package/src/react/widgets/SubscriptionRoot.tsx +759 -0
  351. package/src/react/widgets/index.ts +36 -0
  352. package/src/react/widgets/productGroupContext.ts +10 -0
  353. package/src/react/widgets/subscriptionContext.ts +10 -0
  354. package/src/react/widgets/types.ts +179 -0
  355. package/src/svelte/index.ts +43 -0
  356. package/src/svelte/primitives/BillingGate.svelte +28 -0
  357. package/src/svelte/primitives/BillingToggle.svelte +27 -0
  358. package/src/svelte/primitives/CheckoutButton.svelte +60 -0
  359. package/src/svelte/primitives/CheckoutSuccessSummary.svelte +34 -0
  360. package/src/svelte/primitives/CustomerPortalButton.svelte +60 -0
  361. package/src/svelte/primitives/NumberInput.svelte +71 -0
  362. package/src/svelte/primitives/OneTimeCheckoutButton.svelte +37 -0
  363. package/src/svelte/primitives/OneTimePaymentStatusBadge.svelte +20 -0
  364. package/src/svelte/primitives/PaymentWarningBanner.svelte +30 -0
  365. package/src/svelte/primitives/PricingCard.svelte +356 -0
  366. package/src/svelte/primitives/PricingSection.svelte +121 -0
  367. package/src/svelte/primitives/ScheduledChangeBanner.svelte +46 -0
  368. package/src/svelte/primitives/SegmentControl.svelte +38 -0
  369. package/src/svelte/primitives/SegmentGroup.svelte +52 -0
  370. package/src/svelte/primitives/TrialLimitBanner.svelte +32 -0
  371. package/src/svelte/primitives/shared.ts +113 -0
  372. package/src/svelte/svelte.d.ts +6 -0
  373. package/src/svelte/widgets/BillingPortal.svelte +55 -0
  374. package/src/svelte/widgets/Product.svelte +35 -0
  375. package/src/svelte/widgets/ProductRoot.svelte +428 -0
  376. package/src/svelte/widgets/Subscription.svelte +52 -0
  377. package/src/svelte/widgets/SubscriptionRoot.svelte +690 -0
  378. package/src/svelte/widgets/index.ts +36 -0
  379. package/src/svelte/widgets/productGroupContext.ts +7 -0
  380. package/src/svelte/widgets/subscriptionContext.ts +7 -0
  381. package/src/svelte/widgets/types.ts +179 -0
  382. package/src/tailwind.css +6 -0
  383. package/src/test.ts +18 -0
@@ -0,0 +1,283 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { resolveBillingSnapshot } from "./resolver.js";
3
+
4
+ describe("resolveBillingSnapshot", () => {
5
+ it("maps recurring subscription intervals and seat actions", () => {
6
+ const snapshot = resolveBillingSnapshot({
7
+ catalog: {
8
+ version: "1",
9
+ plans: [
10
+ {
11
+ planId: "pro",
12
+ category: "paid",
13
+ billingType: "recurring",
14
+ billingCycles: ["every-month", "every-year"],
15
+ pricingModel: "seat",
16
+ creemProductIds: {
17
+ monthly: "prod_monthly",
18
+ yearly: "prod_yearly",
19
+ },
20
+ },
21
+ ],
22
+ },
23
+ currentSubscription: {
24
+ productId: "prod_monthly",
25
+ status: "active",
26
+ recurringInterval: "every-month",
27
+ seats: 5,
28
+ },
29
+ });
30
+
31
+ expect(snapshot.activePlanId).toBe("pro");
32
+ expect(snapshot.recurringCycle).toBe("every-month");
33
+ expect(snapshot.availableActions).toContain("switch_interval");
34
+ expect(snapshot.availableActions).toContain("update_seats");
35
+ });
36
+
37
+ it("supports one-time payments", () => {
38
+ const snapshot = resolveBillingSnapshot({
39
+ catalog: {
40
+ version: "1",
41
+ plans: [
42
+ {
43
+ planId: "credits",
44
+ category: "paid",
45
+ billingType: "onetime",
46
+ creemProductIds: { default: "prod_credits" },
47
+ },
48
+ ],
49
+ },
50
+ payment: {
51
+ status: "pending",
52
+ productId: "prod_credits",
53
+ },
54
+ });
55
+
56
+ expect(snapshot.billingType).toBe("onetime");
57
+ expect(snapshot.payment?.status).toBe("pending");
58
+ expect(snapshot.availableActions).toEqual(["checkout"]);
59
+ });
60
+
61
+ it("maps trialing subscription to trial category with trialEnd in metadata", () => {
62
+ const snapshot = resolveBillingSnapshot({
63
+ catalog: {
64
+ version: "1",
65
+ plans: [
66
+ {
67
+ planId: "basic",
68
+ category: "paid",
69
+ billingType: "recurring",
70
+ creemProductIds: { "every-month": "prod_basic" },
71
+ },
72
+ ],
73
+ },
74
+ currentSubscription: {
75
+ productId: "prod_basic",
76
+ status: "trialing",
77
+ recurringInterval: "every-month",
78
+ trialEnd: "2026-03-04T08:23:39.000Z",
79
+ },
80
+ });
81
+
82
+ expect(snapshot.activeCategory).toBe("trial");
83
+ expect(snapshot.subscriptionState).toBe("trialing");
84
+ expect(snapshot.metadata?.trialEnd).toBe("2026-03-04T08:23:39.000Z");
85
+ expect(snapshot.availableActions).toContain("cancel");
86
+ });
87
+
88
+ it("falls back to custom category when no catalog mapping exists", () => {
89
+ const snapshot = resolveBillingSnapshot({
90
+ currentSubscription: {
91
+ status: "unpaid",
92
+ },
93
+ });
94
+
95
+ expect(snapshot.activeCategory).toBe("custom");
96
+ expect(snapshot.availableActions).toEqual(["portal"]);
97
+ });
98
+
99
+ it("maps scheduled_cancel to paid with cancel + reactivate actions", () => {
100
+ const snapshot = resolveBillingSnapshot({
101
+ catalog: {
102
+ version: "1",
103
+ plans: [
104
+ {
105
+ planId: "pro",
106
+ category: "paid",
107
+ billingType: "recurring",
108
+ creemProductIds: { "every-month": "prod_1" },
109
+ },
110
+ ],
111
+ },
112
+ currentSubscription: {
113
+ productId: "prod_1",
114
+ status: "scheduled_cancel",
115
+ recurringInterval: "every-month",
116
+ cancelAtPeriodEnd: true,
117
+ currentPeriodEnd: "2026-03-01T00:00:00.000Z",
118
+ },
119
+ });
120
+
121
+ expect(snapshot.activeCategory).toBe("paid");
122
+ expect(snapshot.subscriptionState).toBe("scheduled_cancel");
123
+ expect(snapshot.availableActions).toContain("cancel");
124
+ expect(snapshot.availableActions).toContain("reactivate");
125
+ expect(snapshot.availableActions).toContain("portal");
126
+ expect(snapshot.metadata?.cancelAtPeriodEnd).toBe(true);
127
+ });
128
+
129
+ it("maps past_due subscription to paid category", () => {
130
+ const snapshot = resolveBillingSnapshot({
131
+ catalog: {
132
+ version: "1",
133
+ plans: [
134
+ {
135
+ planId: "basic",
136
+ category: "paid",
137
+ billingType: "recurring",
138
+ creemProductIds: { "every-month": "prod_basic" },
139
+ },
140
+ ],
141
+ },
142
+ currentSubscription: {
143
+ productId: "prod_basic",
144
+ status: "past_due",
145
+ recurringInterval: "every-month",
146
+ },
147
+ });
148
+
149
+ expect(snapshot.activeCategory).toBe("paid");
150
+ expect(snapshot.subscriptionState).toBe("past_due");
151
+ expect(snapshot.availableActions).toContain("portal");
152
+ });
153
+
154
+ it("maps enterprise plan to contact_sales action only", () => {
155
+ const snapshot = resolveBillingSnapshot({
156
+ catalog: {
157
+ version: "1",
158
+ plans: [
159
+ {
160
+ planId: "enterprise",
161
+ category: "enterprise",
162
+ billingType: "custom",
163
+ creemProductIds: { default: "prod_ent" },
164
+ },
165
+ ],
166
+ },
167
+ currentSubscription: {
168
+ productId: "prod_ent",
169
+ status: "active",
170
+ recurringInterval: "every-month",
171
+ },
172
+ });
173
+
174
+ expect(snapshot.activeCategory).toBe("enterprise");
175
+ expect(snapshot.availableActions).toEqual(["contact_sales"]);
176
+ });
177
+
178
+ it("returns checkout action when no subscription exists", () => {
179
+ const snapshot = resolveBillingSnapshot({
180
+ catalog: {
181
+ version: "1",
182
+ plans: [
183
+ {
184
+ planId: "pro",
185
+ category: "paid",
186
+ billingType: "recurring",
187
+ creemProductIds: { "every-month": "prod_1" },
188
+ },
189
+ ],
190
+ },
191
+ });
192
+
193
+ expect(snapshot.availableActions).toEqual(["checkout"]);
194
+ expect(snapshot.activePlanId).toBeNull();
195
+ });
196
+
197
+ it("maps canceled subscription to paid with reactivate action", () => {
198
+ const snapshot = resolveBillingSnapshot({
199
+ catalog: {
200
+ version: "1",
201
+ plans: [
202
+ {
203
+ planId: "pro",
204
+ category: "paid",
205
+ billingType: "recurring",
206
+ creemProductIds: { "every-month": "prod_1" },
207
+ },
208
+ ],
209
+ },
210
+ currentSubscription: {
211
+ productId: "prod_1",
212
+ status: "canceled",
213
+ recurringInterval: "every-month",
214
+ },
215
+ });
216
+
217
+ expect(snapshot.activeCategory).toBe("paid");
218
+ expect(snapshot.availableActions).toContain("reactivate");
219
+ expect(snapshot.availableActions).toContain("portal");
220
+ });
221
+
222
+ it("uses defaultPlanId as fallback when no subscription product matches", () => {
223
+ const snapshot = resolveBillingSnapshot({
224
+ catalog: {
225
+ version: "1",
226
+ defaultPlanId: "free",
227
+ plans: [
228
+ {
229
+ planId: "free",
230
+ category: "free",
231
+ billingType: "custom",
232
+ },
233
+ {
234
+ planId: "pro",
235
+ category: "paid",
236
+ billingType: "recurring",
237
+ creemProductIds: { "every-month": "prod_1" },
238
+ },
239
+ ],
240
+ },
241
+ });
242
+
243
+ expect(snapshot.activePlanId).toBe("free");
244
+ expect(snapshot.activeCategory).toBe("free");
245
+ });
246
+
247
+ it("infers onetime billing type from payment when no plan exists", () => {
248
+ const snapshot = resolveBillingSnapshot({
249
+ payment: {
250
+ status: "pending",
251
+ productId: "prod_unknown",
252
+ },
253
+ });
254
+
255
+ expect(snapshot.billingType).toBe("onetime");
256
+ expect(snapshot.activePlanId).toBeNull();
257
+ expect(snapshot.availableActions).toEqual(["checkout"]);
258
+ });
259
+
260
+ it("infers recurring billing type from subscription when no plan exists", () => {
261
+ const snapshot = resolveBillingSnapshot({
262
+ currentSubscription: {
263
+ status: "active",
264
+ recurringInterval: "every-year",
265
+ },
266
+ });
267
+
268
+ expect(snapshot.billingType).toBe("recurring");
269
+ expect(snapshot.recurringCycle).toBe("every-year");
270
+ expect(snapshot.availableBillingCycles).toEqual(["every-year"]);
271
+ });
272
+
273
+ it("normalizes unknown recurring interval to custom", () => {
274
+ const snapshot = resolveBillingSnapshot({
275
+ currentSubscription: {
276
+ status: "active",
277
+ recurringInterval: "every-two-weeks",
278
+ },
279
+ });
280
+
281
+ expect(snapshot.recurringCycle).toBe("custom");
282
+ });
283
+ });
@@ -0,0 +1,160 @@
1
+ import {
2
+ findPlanById,
3
+ findPlanByProductId,
4
+ normalizePlanCatalog,
5
+ normalizeRecurringCycle,
6
+ } from "./catalog.js";
7
+ import type {
8
+ AvailableAction,
9
+ BillingResolverInput,
10
+ BillingSnapshot,
11
+ BillingType,
12
+ PlanCategory,
13
+ PlanCatalogEntry,
14
+ SubscriptionSnapshot,
15
+ } from "./types.js";
16
+
17
+ const toCategoryFromSubscription = (
18
+ subscription: SubscriptionSnapshot | null | undefined,
19
+ ): PlanCategory => {
20
+ const status = subscription?.status;
21
+ if (status === "trialing") {
22
+ return "trial";
23
+ }
24
+ if (
25
+ status === "active" ||
26
+ status === "scheduled_cancel" ||
27
+ status === "past_due" ||
28
+ status === "canceled"
29
+ ) {
30
+ return "paid";
31
+ }
32
+ return "custom";
33
+ };
34
+
35
+ const toBillingType = (
36
+ plan: PlanCatalogEntry | undefined,
37
+ input: BillingResolverInput,
38
+ ): BillingType => {
39
+ if (plan?.billingType) {
40
+ return plan.billingType;
41
+ }
42
+ if (input.payment) {
43
+ return "onetime";
44
+ }
45
+ if (input.currentSubscription) {
46
+ return "recurring";
47
+ }
48
+ return "custom";
49
+ };
50
+
51
+ const buildActions = (
52
+ input: BillingResolverInput,
53
+ plan: PlanCatalogEntry | undefined,
54
+ billingType: BillingType,
55
+ ): AvailableAction[] => {
56
+ const actions = new Set<AvailableAction>();
57
+ const subscription = input.currentSubscription;
58
+
59
+ if (plan?.category === "enterprise") {
60
+ actions.add("contact_sales");
61
+ return Array.from(actions);
62
+ }
63
+
64
+ if (billingType === "onetime") {
65
+ actions.add("checkout");
66
+ return Array.from(actions);
67
+ }
68
+
69
+ if (!subscription) {
70
+ actions.add("checkout");
71
+ return Array.from(actions);
72
+ }
73
+
74
+ actions.add("portal");
75
+
76
+ if (
77
+ subscription.status === "active" ||
78
+ subscription.status === "trialing" ||
79
+ subscription.status === "scheduled_cancel"
80
+ ) {
81
+ actions.add("cancel");
82
+ }
83
+
84
+ if (
85
+ subscription.status === "canceled" ||
86
+ subscription.status === "scheduled_cancel"
87
+ ) {
88
+ actions.add("reactivate");
89
+ }
90
+
91
+ if ((plan?.billingCycles?.length ?? 0) > 1) {
92
+ actions.add("switch_interval");
93
+ }
94
+
95
+ if (
96
+ (plan?.pricingModel === "seat" || subscription.seats != null) &&
97
+ billingType === "recurring"
98
+ ) {
99
+ actions.add("update_seats");
100
+ }
101
+
102
+ return Array.from(actions);
103
+ };
104
+
105
+ /**
106
+ * Resolve a `BillingSnapshot` from subscription, catalog, and payment data.
107
+ * This is the core billing state resolver — determines the active plan, category,
108
+ * available actions, and metadata based on the current subscription state.
109
+ *
110
+ * Used internally by `creem.getBillingSnapshot()`. Can also be called directly
111
+ * for custom billing UIs that don't use the Creem class.
112
+ */
113
+ export const resolveBillingSnapshot = (
114
+ input: BillingResolverInput,
115
+ ): BillingSnapshot => {
116
+ const catalog = normalizePlanCatalog(input.catalog);
117
+ const subscription = input.currentSubscription ?? null;
118
+ const planFromSubscription = findPlanByProductId(
119
+ catalog,
120
+ subscription?.productId,
121
+ );
122
+ const fallbackPlan = catalog?.defaultPlanId
123
+ ? findPlanById(catalog, catalog.defaultPlanId)
124
+ : undefined;
125
+ const activePlan = planFromSubscription ?? fallbackPlan;
126
+
127
+ const billingType = toBillingType(activePlan, input);
128
+ const recurringCycle = normalizeRecurringCycle(
129
+ subscription?.recurringInterval,
130
+ );
131
+ const availableBillingCycles =
132
+ activePlan?.billingCycles && activePlan.billingCycles.length > 0
133
+ ? activePlan.billingCycles
134
+ : recurringCycle
135
+ ? [recurringCycle]
136
+ : [];
137
+
138
+ return {
139
+ resolvedAt: input.now ?? new Date().toISOString(),
140
+ catalogVersion: catalog?.version,
141
+ activePlanId: activePlan?.planId ?? null,
142
+ activeCategory:
143
+ subscription?.status === "trialing"
144
+ ? "trial"
145
+ : (activePlan?.category ?? toCategoryFromSubscription(subscription)),
146
+ billingType,
147
+ recurringCycle,
148
+ availableBillingCycles,
149
+ subscriptionState: subscription?.status,
150
+ seats: subscription?.seats ?? undefined,
151
+ payment: input.payment ?? null,
152
+ availableActions: buildActions(input, activePlan, billingType),
153
+ metadata: {
154
+ cancelAtPeriodEnd: subscription?.cancelAtPeriodEnd ?? false,
155
+ currentPeriodEnd: subscription?.currentPeriodEnd ?? null,
156
+ trialEnd: subscription?.trialEnd ?? null,
157
+ userContext: input.userContext ?? {},
158
+ },
159
+ };
160
+ };
@@ -0,0 +1,119 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ hasBillingAction,
4
+ isOneTimeBilling,
5
+ isEnterpriseBilling,
6
+ shouldShowBillingCycleToggle,
7
+ isTerminalPaymentStatus,
8
+ } from "./selectors.js";
9
+ import type { BillingSnapshot } from "./types.js";
10
+
11
+ const makeSnapshot = (
12
+ overrides: Partial<BillingSnapshot> = {},
13
+ ): BillingSnapshot => ({
14
+ resolvedAt: new Date().toISOString(),
15
+ activePlanId: null,
16
+ activeCategory: "paid",
17
+ billingType: "recurring",
18
+ availableBillingCycles: [],
19
+ payment: null,
20
+ availableActions: [],
21
+ ...overrides,
22
+ });
23
+
24
+ describe("hasBillingAction", () => {
25
+ it("returns true when action is present", () => {
26
+ const snapshot = makeSnapshot({ availableActions: ["checkout", "portal"] });
27
+ expect(hasBillingAction(snapshot, "checkout")).toBe(true);
28
+ expect(hasBillingAction(snapshot, "portal")).toBe(true);
29
+ });
30
+
31
+ it("returns false when action is absent", () => {
32
+ const snapshot = makeSnapshot({ availableActions: ["checkout"] });
33
+ expect(hasBillingAction(snapshot, "cancel")).toBe(false);
34
+ });
35
+ });
36
+
37
+ describe("isOneTimeBilling", () => {
38
+ it("returns true for onetime billing type", () => {
39
+ expect(isOneTimeBilling(makeSnapshot({ billingType: "onetime" }))).toBe(
40
+ true,
41
+ );
42
+ });
43
+
44
+ it("returns false for recurring billing type", () => {
45
+ expect(isOneTimeBilling(makeSnapshot({ billingType: "recurring" }))).toBe(
46
+ false,
47
+ );
48
+ });
49
+ });
50
+
51
+ describe("isEnterpriseBilling", () => {
52
+ it("returns true for enterprise category", () => {
53
+ expect(
54
+ isEnterpriseBilling(makeSnapshot({ activeCategory: "enterprise" })),
55
+ ).toBe(true);
56
+ });
57
+
58
+ it("returns false for paid category", () => {
59
+ expect(isEnterpriseBilling(makeSnapshot({ activeCategory: "paid" }))).toBe(
60
+ false,
61
+ );
62
+ });
63
+ });
64
+
65
+ describe("shouldShowBillingCycleToggle", () => {
66
+ it("returns true when recurring with multiple cycles and switch_interval action", () => {
67
+ const snapshot = makeSnapshot({
68
+ billingType: "recurring",
69
+ availableBillingCycles: ["every-month", "every-year"],
70
+ availableActions: ["switch_interval", "portal"],
71
+ });
72
+ expect(shouldShowBillingCycleToggle(snapshot)).toBe(true);
73
+ });
74
+
75
+ it("returns false when only one cycle available", () => {
76
+ const snapshot = makeSnapshot({
77
+ billingType: "recurring",
78
+ availableBillingCycles: ["every-month"],
79
+ availableActions: ["switch_interval"],
80
+ });
81
+ expect(shouldShowBillingCycleToggle(snapshot)).toBe(false);
82
+ });
83
+
84
+ it("returns false when onetime billing type", () => {
85
+ const snapshot = makeSnapshot({
86
+ billingType: "onetime",
87
+ availableBillingCycles: ["every-month", "every-year"],
88
+ availableActions: ["switch_interval"],
89
+ });
90
+ expect(shouldShowBillingCycleToggle(snapshot)).toBe(false);
91
+ });
92
+
93
+ it("returns false when switch_interval action is not available", () => {
94
+ const snapshot = makeSnapshot({
95
+ billingType: "recurring",
96
+ availableBillingCycles: ["every-month", "every-year"],
97
+ availableActions: ["portal"],
98
+ });
99
+ expect(shouldShowBillingCycleToggle(snapshot)).toBe(false);
100
+ });
101
+ });
102
+
103
+ describe("isTerminalPaymentStatus", () => {
104
+ it("returns true for paid", () => {
105
+ expect(isTerminalPaymentStatus("paid")).toBe(true);
106
+ });
107
+
108
+ it("returns true for refunded", () => {
109
+ expect(isTerminalPaymentStatus("refunded")).toBe(true);
110
+ });
111
+
112
+ it("returns true for partially_refunded", () => {
113
+ expect(isTerminalPaymentStatus("partially_refunded")).toBe(true);
114
+ });
115
+
116
+ it("returns false for pending", () => {
117
+ expect(isTerminalPaymentStatus("pending")).toBe(false);
118
+ });
119
+ });
@@ -0,0 +1,35 @@
1
+ import type {
2
+ AvailableAction,
3
+ BillingSnapshot,
4
+ OneTimePaymentStatus,
5
+ } from "./types.js";
6
+
7
+ const TERMINAL_PAYMENT_STATUSES = new Set<OneTimePaymentStatus>([
8
+ "paid",
9
+ "refunded",
10
+ "partially_refunded",
11
+ ]);
12
+
13
+ /** Check whether a specific action is available in the given billing snapshot. */
14
+ export const hasBillingAction = (
15
+ snapshot: BillingSnapshot,
16
+ action: AvailableAction,
17
+ ) => snapshot.availableActions.includes(action);
18
+
19
+ /** Check whether the billing snapshot represents a one-time purchase (not a subscription). */
20
+ export const isOneTimeBilling = (snapshot: BillingSnapshot) =>
21
+ snapshot.billingType === "onetime";
22
+
23
+ /** Check whether the billing snapshot represents an enterprise plan. */
24
+ export const isEnterpriseBilling = (snapshot: BillingSnapshot) =>
25
+ snapshot.activeCategory === "enterprise";
26
+
27
+ /** Whether the billing cycle toggle (e.g. Monthly/Yearly) should be shown in the UI. */
28
+ export const shouldShowBillingCycleToggle = (snapshot: BillingSnapshot) =>
29
+ snapshot.billingType === "recurring" &&
30
+ snapshot.availableBillingCycles.length > 1 &&
31
+ hasBillingAction(snapshot, "switch_interval");
32
+
33
+ /** Whether the payment status is terminal (paid, refunded, or partially refunded). */
34
+ export const isTerminalPaymentStatus = (status: OneTimePaymentStatus) =>
35
+ TERMINAL_PAYMENT_STATUSES.has(status);