@carlonicora/nextjs-jsonapi 1.15.0 → 1.17.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 (321) hide show
  1. package/dist/ApiData-DPKNfY-9.d.mts +10 -0
  2. package/dist/ApiData-DPKNfY-9.d.ts +10 -0
  3. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.mts +40 -0
  4. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.ts +40 -0
  5. package/dist/{ApiResponseInterface-QLDnxLA9.d.ts → ApiResponseInterface-BKyod24U.d.ts} +3 -11
  6. package/dist/{ApiResponseInterface-B4QdWh-y.d.mts → ApiResponseInterface-Dqvu09tz.d.mts} +3 -11
  7. package/dist/{BlockNoteEditor-FGXYUAWI.js → BlockNoteEditor-34T5CY27.js} +17 -16
  8. package/dist/BlockNoteEditor-34T5CY27.js.map +1 -0
  9. package/dist/{BlockNoteEditor-ITJLAOXC.mjs → BlockNoteEditor-4Z6TZBJE.mjs} +7 -6
  10. package/dist/{BlockNoteEditor-ITJLAOXC.mjs.map → BlockNoteEditor-4Z6TZBJE.mjs.map} +1 -1
  11. package/dist/JsonApiContext-Bsm_Q2oe.d.mts +41 -0
  12. package/dist/JsonApiContext-Bsm_Q2oe.d.ts +41 -0
  13. package/dist/JsonApiRequest-54ZBO7WQ.js +24 -0
  14. package/dist/{JsonApiRequest-FXZCYIER.js.map → JsonApiRequest-54ZBO7WQ.js.map} +1 -1
  15. package/dist/{JsonApiRequest-HFWXMKMA.mjs → JsonApiRequest-XWQWTFEQ.mjs} +2 -2
  16. package/dist/chunk-3EPNHTMH.js +26 -0
  17. package/dist/chunk-3EPNHTMH.js.map +1 -0
  18. package/dist/{chunk-TGBXBUWM.mjs → chunk-3VM3WAOV.mjs} +8 -1
  19. package/dist/chunk-3VM3WAOV.mjs.map +1 -0
  20. package/dist/{chunk-6YD42BP6.js → chunk-7DTKRMYW.js} +31 -19
  21. package/dist/chunk-7DTKRMYW.js.map +1 -0
  22. package/dist/{chunk-PK5DRSUD.js → chunk-D7H7SRWB.js} +4104 -793
  23. package/dist/chunk-D7H7SRWB.js.map +1 -0
  24. package/dist/{chunk-JGVXZS7M.mjs → chunk-KUFWHMMY.mjs} +1592 -133
  25. package/dist/chunk-KUFWHMMY.mjs.map +1 -0
  26. package/dist/{chunk-SJIVGCNM.mjs → chunk-KX7YG6LY.mjs} +27 -15
  27. package/dist/chunk-KX7YG6LY.mjs.map +1 -0
  28. package/dist/{chunk-FPZPD4JI.js → chunk-LI6CPNJI.js} +17 -10
  29. package/dist/chunk-LI6CPNJI.js.map +1 -0
  30. package/dist/{chunk-WAFOKMKT.mjs → chunk-SXPXC2TY.mjs} +3729 -418
  31. package/dist/chunk-SXPXC2TY.mjs.map +1 -0
  32. package/dist/{chunk-C6QXZGL7.js → chunk-UYY34W7R.js} +1622 -163
  33. package/dist/chunk-UYY34W7R.js.map +1 -0
  34. package/dist/chunk-VOXD3ZLY.mjs +26 -0
  35. package/dist/chunk-VOXD3ZLY.mjs.map +1 -0
  36. package/dist/client/index.d.mts +11 -45
  37. package/dist/client/index.d.ts +11 -45
  38. package/dist/client/index.js +10 -6
  39. package/dist/client/index.js.map +1 -1
  40. package/dist/client/index.mjs +13 -9
  41. package/dist/components/index.d.mts +254 -9
  42. package/dist/components/index.d.ts +254 -9
  43. package/dist/components/index.js +85 -6
  44. package/dist/components/index.js.map +1 -1
  45. package/dist/components/index.mjs +84 -5
  46. package/dist/{config-C5tGGrYf.d.mts → config--nwiW74Z.d.ts} +7 -2
  47. package/dist/{config-eceYM5kN.d.ts → config-BKSQmUWU.d.mts} +7 -2
  48. package/dist/{content.interface-CxBBC7ec.d.mts → content.interface-4VICFRA0.d.ts} +2 -1
  49. package/dist/{content.interface-TB2MfJGs.d.ts → content.interface-CFc97-Cj.d.mts} +2 -1
  50. package/dist/contexts/index.d.mts +3 -2
  51. package/dist/contexts/index.d.ts +3 -2
  52. package/dist/contexts/index.js +7 -6
  53. package/dist/contexts/index.js.map +1 -1
  54. package/dist/contexts/index.mjs +6 -5
  55. package/dist/core/index.d.mts +524 -18
  56. package/dist/core/index.d.ts +524 -18
  57. package/dist/core/index.js +54 -4
  58. package/dist/core/index.js.map +1 -1
  59. package/dist/core/index.mjs +53 -3
  60. package/dist/index.d.mts +16 -12
  61. package/dist/index.d.ts +16 -12
  62. package/dist/index.js +57 -5
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +58 -6
  65. package/dist/{notification.interface-lG6UpTpt.d.mts → notification.interface-BGaPiCUM.d.mts} +3 -42
  66. package/dist/{notification.interface-lG6UpTpt.d.ts → notification.interface-CqwaOIgM.d.ts} +3 -42
  67. package/dist/{s3.service-DP_hsssD.d.mts → s3.service-BYs88XEE.d.ts} +21 -2
  68. package/dist/{s3.service-Dq-PTUNa.d.ts → s3.service-C0BjOdvn.d.mts} +21 -2
  69. package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
  70. package/dist/scripts/generate-web-module/generator.js +66 -0
  71. package/dist/scripts/generate-web-module/generator.js.map +1 -1
  72. package/dist/scripts/generate-web-module/templates/index.d.ts +8 -0
  73. package/dist/scripts/generate-web-module/templates/index.d.ts.map +1 -1
  74. package/dist/scripts/generate-web-module/templates/index.js +18 -1
  75. package/dist/scripts/generate-web-module/templates/index.js.map +1 -1
  76. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts +7 -0
  77. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.d.ts.map +1 -0
  78. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js +141 -0
  79. package/dist/scripts/generate-web-module/templates/project/bootstrapper.template.js.map +1 -0
  80. package/dist/scripts/generate-web-module/templates/project/env.template.d.ts +7 -0
  81. package/dist/scripts/generate-web-module/templates/project/env.template.d.ts.map +1 -0
  82. package/dist/scripts/generate-web-module/templates/project/env.template.js +110 -0
  83. package/dist/scripts/generate-web-module/templates/project/env.template.js.map +1 -0
  84. package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts +7 -0
  85. package/dist/scripts/generate-web-module/templates/project/main-layout.template.d.ts.map +1 -0
  86. package/dist/scripts/generate-web-module/templates/project/main-layout.template.js +101 -0
  87. package/dist/scripts/generate-web-module/templates/project/main-layout.template.js.map +1 -0
  88. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts +7 -0
  89. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.d.ts.map +1 -0
  90. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js +66 -0
  91. package/dist/scripts/generate-web-module/templates/project/middleware-env.template.js.map +1 -0
  92. package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts +7 -0
  93. package/dist/scripts/generate-web-module/templates/project/settings-container.template.d.ts.map +1 -0
  94. package/dist/scripts/generate-web-module/templates/project/settings-container.template.js +257 -0
  95. package/dist/scripts/generate-web-module/templates/project/settings-container.template.js.map +1 -0
  96. package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts +7 -0
  97. package/dist/scripts/generate-web-module/templates/project/settings-context.template.d.ts.map +1 -0
  98. package/dist/scripts/generate-web-module/templates/project/settings-context.template.js +124 -0
  99. package/dist/scripts/generate-web-module/templates/project/settings-context.template.js.map +1 -0
  100. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts +7 -0
  101. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.d.ts.map +1 -0
  102. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js +78 -0
  103. package/dist/scripts/generate-web-module/templates/project/settings-module-page.template.js.map +1 -0
  104. package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts +7 -0
  105. package/dist/scripts/generate-web-module/templates/project/settings-page.template.d.ts.map +1 -0
  106. package/dist/scripts/generate-web-module/templates/project/settings-page.template.js +75 -0
  107. package/dist/scripts/generate-web-module/templates/project/settings-page.template.js.map +1 -0
  108. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +1 -1
  109. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
  110. package/dist/server/index.d.mts +6 -4
  111. package/dist/server/index.d.ts +6 -4
  112. package/dist/server/index.js +13 -13
  113. package/dist/server/index.js.map +1 -1
  114. package/dist/server/index.mjs +3 -3
  115. package/dist/stripe-subscription.interface-B-TM40Io.d.ts +226 -0
  116. package/dist/stripe-subscription.interface-DDxnpj0F.d.mts +226 -0
  117. package/dist/testing/index.d.mts +338 -0
  118. package/dist/testing/index.d.ts +338 -0
  119. package/dist/testing/index.js +323 -0
  120. package/dist/testing/index.js.map +1 -0
  121. package/dist/testing/index.mjs +323 -0
  122. package/dist/testing/index.mjs.map +1 -0
  123. package/dist/{useSocket-Bua6MwLi.d.mts → useSocket-BNj9PrRw.d.mts} +1 -1
  124. package/dist/{useSocket-D5dhUp4m.d.ts → useSocket-Dwt8cz1x.d.ts} +1 -1
  125. package/package.json +29 -3
  126. package/scripts/generate-web-module/generator.ts +83 -0
  127. package/scripts/generate-web-module/templates/index.ts +10 -0
  128. package/scripts/generate-web-module/templates/project/bootstrapper.template.ts +108 -0
  129. package/scripts/generate-web-module/templates/project/env.template.ts +77 -0
  130. package/scripts/generate-web-module/templates/project/main-layout.template.tsx +68 -0
  131. package/scripts/generate-web-module/templates/project/middleware-env.template.ts +33 -0
  132. package/scripts/generate-web-module/templates/project/settings-container.template.tsx +224 -0
  133. package/scripts/generate-web-module/templates/project/settings-context.template.tsx +91 -0
  134. package/scripts/generate-web-module/templates/project/settings-module-page.template.tsx +45 -0
  135. package/scripts/generate-web-module/templates/project/settings-page.template.tsx +42 -0
  136. package/scripts/generate-web-module/types/template-data.interface.ts +1 -1
  137. package/src/client/config.ts +9 -0
  138. package/src/client/hooks/__tests__/useJsonApiGet.test.tsx +229 -0
  139. package/src/client/hooks/__tests__/useJsonApiMutation.test.tsx +348 -0
  140. package/src/client/hooks/__tests__/useRehydration.test.ts +188 -0
  141. package/src/components/forms/__tests__/FormCheckbox.test.tsx +238 -0
  142. package/src/components/forms/__tests__/FormDate.test.tsx +212 -0
  143. package/src/components/forms/__tests__/FormInput.test.tsx +292 -0
  144. package/src/components/forms/__tests__/FormSelect.test.tsx +173 -0
  145. package/src/components/index.ts +7 -0
  146. package/src/components/tables/__tests__/ContentListTable.test.tsx +411 -0
  147. package/src/core/abstracts/AbstractService.ts +104 -0
  148. package/src/core/endpoint/EndpointCreator.ts +7 -4
  149. package/src/core/endpoint/__tests__/EndpointCreator.test.ts +168 -0
  150. package/src/core/factories/__tests__/JsonApiDataFactory.test.ts +109 -0
  151. package/src/core/factories/__tests__/RehydrationFactory.test.ts +151 -0
  152. package/src/core/index.ts +12 -4
  153. package/src/core/interfaces/ApiResponseInterface.ts +1 -0
  154. package/src/core/registry/ModuleRegistry.ts +11 -2
  155. package/src/core/registry/__tests__/DataClassRegistry.test.ts +136 -0
  156. package/src/core/registry/__tests__/ModuleRegistrar.test.ts +159 -0
  157. package/src/core/utils/translateResponse.ts +17 -0
  158. package/src/features/auth/components/details/LandingComponent.tsx +14 -12
  159. package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +97 -0
  160. package/src/features/billing/components/cards/CustomerInfoCard.tsx +112 -0
  161. package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +114 -0
  162. package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +119 -0
  163. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +146 -0
  164. package/src/features/billing/components/cards/index.ts +5 -0
  165. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +427 -0
  166. package/src/features/billing/components/containers/index.ts +1 -0
  167. package/src/features/billing/components/index.ts +6 -0
  168. package/src/features/billing/components/modals/BillingDetailModal.tsx +36 -0
  169. package/src/features/billing/components/modals/index.ts +1 -0
  170. package/src/features/billing/components/providers/StripeProvider.tsx +48 -0
  171. package/src/features/billing/components/providers/index.ts +1 -0
  172. package/src/features/billing/components/utils/currency.ts +49 -0
  173. package/src/features/billing/components/utils/date.ts +21 -0
  174. package/src/features/billing/components/utils/index.ts +2 -0
  175. package/src/features/billing/components/widgets/BillingAlertBanner.tsx +63 -0
  176. package/src/features/billing/components/widgets/index.ts +1 -0
  177. package/src/features/billing/data/Billing.ts +17 -0
  178. package/src/features/billing/data/billing.service.ts +58 -0
  179. package/src/features/billing/data/index.ts +5 -0
  180. package/src/features/billing/index.ts +3 -0
  181. package/src/features/billing/modules/billing.module.ts +9 -0
  182. package/src/features/billing/modules/index.ts +1 -0
  183. package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +79 -0
  184. package/src/features/billing/stripe-customer/components/containers/index.ts +1 -0
  185. package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +151 -0
  186. package/src/features/billing/stripe-customer/components/details/index.ts +1 -0
  187. package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +186 -0
  188. package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
  189. package/src/features/billing/stripe-customer/components/index.ts +4 -0
  190. package/src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx +19 -0
  191. package/src/features/billing/stripe-customer/components/lists/index.ts +1 -0
  192. package/src/features/billing/stripe-customer/data/index.ts +5 -0
  193. package/src/features/billing/stripe-customer/data/payment-method.interface.ts +27 -0
  194. package/src/features/billing/stripe-customer/data/payment-method.ts +119 -0
  195. package/src/features/billing/stripe-customer/data/stripe-customer.interface.ts +16 -0
  196. package/src/features/billing/stripe-customer/data/stripe-customer.service.ts +128 -0
  197. package/src/features/billing/stripe-customer/data/stripe-customer.ts +71 -0
  198. package/src/features/billing/stripe-customer/index.ts +3 -0
  199. package/src/features/billing/stripe-customer/stripe-customer.module.ts +9 -0
  200. package/src/features/billing/stripe-customer/stripe-payment-method.module.ts +9 -0
  201. package/src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx +66 -0
  202. package/src/features/billing/stripe-invoice/components/containers/index.ts +1 -0
  203. package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +172 -0
  204. package/src/features/billing/stripe-invoice/components/details/index.ts +1 -0
  205. package/src/features/billing/stripe-invoice/components/index.ts +4 -0
  206. package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +84 -0
  207. package/src/features/billing/stripe-invoice/components/lists/index.ts +1 -0
  208. package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +41 -0
  209. package/src/features/billing/stripe-invoice/components/widgets/index.ts +1 -0
  210. package/src/features/billing/stripe-invoice/data/index.ts +3 -0
  211. package/src/features/billing/stripe-invoice/data/stripe-invoice.interface.ts +65 -0
  212. package/src/features/billing/stripe-invoice/data/stripe-invoice.service.ts +64 -0
  213. package/src/features/billing/stripe-invoice/data/stripe-invoice.ts +177 -0
  214. package/src/features/billing/stripe-invoice/index.ts +2 -0
  215. package/src/features/billing/stripe-invoice/stripe-invoice.module.ts +9 -0
  216. package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +304 -0
  217. package/src/features/billing/stripe-price/components/forms/index.ts +1 -0
  218. package/src/features/billing/stripe-price/components/index.ts +2 -0
  219. package/src/features/billing/stripe-price/components/lists/PricesList.tsx +283 -0
  220. package/src/features/billing/stripe-price/components/lists/index.ts +1 -0
  221. package/src/features/billing/stripe-price/data/index.ts +3 -0
  222. package/src/features/billing/stripe-price/data/stripe-price.interface.ts +48 -0
  223. package/src/features/billing/stripe-price/data/stripe-price.service.ts +123 -0
  224. package/src/features/billing/stripe-price/data/stripe-price.ts +156 -0
  225. package/src/features/billing/stripe-price/index.ts +2 -0
  226. package/src/features/billing/stripe-price/stripe-price.module.ts +9 -0
  227. package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +86 -0
  228. package/src/features/billing/stripe-product/components/containers/index.ts +1 -0
  229. package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +100 -0
  230. package/src/features/billing/stripe-product/components/forms/index.ts +1 -0
  231. package/src/features/billing/stripe-product/components/index.ts +3 -0
  232. package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +206 -0
  233. package/src/features/billing/stripe-product/components/lists/index.ts +1 -0
  234. package/src/features/billing/stripe-product/data/index.ts +3 -0
  235. package/src/features/billing/stripe-product/data/stripe-product.interface.ts +18 -0
  236. package/src/features/billing/stripe-product/data/stripe-product.service.ts +112 -0
  237. package/src/features/billing/stripe-product/data/stripe-product.ts +74 -0
  238. package/src/features/billing/stripe-product/index.ts +2 -0
  239. package/src/features/billing/stripe-product/stripe-product.module.ts +9 -0
  240. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +304 -0
  241. package/src/features/billing/stripe-subscription/components/containers/index.ts +1 -0
  242. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +223 -0
  243. package/src/features/billing/stripe-subscription/components/details/index.ts +1 -0
  244. package/src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx +116 -0
  245. package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +331 -0
  246. package/src/features/billing/stripe-subscription/components/forms/index.ts +2 -0
  247. package/src/features/billing/stripe-subscription/components/index.ts +5 -0
  248. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +104 -0
  249. package/src/features/billing/stripe-subscription/components/lists/index.ts +1 -0
  250. package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +95 -0
  251. package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +110 -0
  252. package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +41 -0
  253. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +60 -0
  254. package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -0
  255. package/src/features/billing/stripe-subscription/data/index.ts +3 -0
  256. package/src/features/billing/stripe-subscription/data/stripe-subscription.interface.ts +66 -0
  257. package/src/features/billing/stripe-subscription/data/stripe-subscription.service.ts +193 -0
  258. package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +135 -0
  259. package/src/features/billing/stripe-subscription/hooks/index.ts +1 -0
  260. package/src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts +111 -0
  261. package/src/features/billing/stripe-subscription/index.ts +5 -0
  262. package/src/features/billing/stripe-subscription/stripe-subscription.module.ts +9 -0
  263. package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +109 -0
  264. package/src/features/billing/stripe-usage/components/containers/index.ts +1 -0
  265. package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +90 -0
  266. package/src/features/billing/stripe-usage/components/details/index.ts +1 -0
  267. package/src/features/billing/stripe-usage/components/index.ts +4 -0
  268. package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +72 -0
  269. package/src/features/billing/stripe-usage/components/lists/index.ts +1 -0
  270. package/src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx +19 -0
  271. package/src/features/billing/stripe-usage/components/widgets/index.ts +1 -0
  272. package/src/features/billing/stripe-usage/data/index.ts +3 -0
  273. package/src/features/billing/stripe-usage/data/stripe-usage.interface.ts +55 -0
  274. package/src/features/billing/stripe-usage/data/stripe-usage.service.ts +129 -0
  275. package/src/features/billing/stripe-usage/data/stripe-usage.ts +70 -0
  276. package/src/features/billing/stripe-usage/index.ts +2 -0
  277. package/src/features/billing/stripe-usage/stripe-usage.module.ts +9 -0
  278. package/src/features/company/components/forms/CompanyEditor.tsx +2 -2
  279. package/src/features/company/contexts/CompanyContext.tsx +2 -2
  280. package/src/features/feature/components/forms/FormFeatures.tsx +13 -106
  281. package/src/features/feature/data/feature.interface.ts +1 -1
  282. package/src/features/feature/data/feature.ts +4 -4
  283. package/src/features/index.ts +7 -0
  284. package/src/features/module/data/module.interface.ts +0 -1
  285. package/src/features/module/data/module.ts +0 -6
  286. package/src/features/user/components/lists/ContributorsList.tsx +2 -2
  287. package/src/features/user/components/widgets/UserAvatar.tsx +1 -1
  288. package/src/hooks/__tests__/useDataListRetriever.test.ts +321 -0
  289. package/src/hooks/__tests__/useDebounce.test.ts +170 -0
  290. package/src/index.ts +5 -2
  291. package/src/login/config.ts +27 -0
  292. package/src/login/index.ts +2 -0
  293. package/src/shadcnui/custom/link.tsx +16 -6
  294. package/src/testing/factories/createMockApiData.ts +143 -0
  295. package/src/testing/factories/createMockModule.ts +32 -0
  296. package/src/testing/factories/createMockResponse.ts +93 -0
  297. package/src/testing/factories/createMockService.ts +79 -0
  298. package/src/testing/index.ts +70 -0
  299. package/src/testing/matchers/jsonApiMatchers.ts +174 -0
  300. package/src/testing/providers/MockJsonApiProvider.tsx +58 -0
  301. package/src/testing/utils/renderWithProviders.tsx +76 -0
  302. package/src/utils/__tests__/date-formatter.test.ts +161 -0
  303. package/src/utils/__tests__/exists.test.ts +100 -0
  304. package/src/utils/blocknote-diff.util.ts +2 -1
  305. package/src/utils/blocknote-word-diff-renderer.util.ts +8 -7
  306. package/src/utils/cn.test.ts +44 -0
  307. package/dist/AuthComponent-hxOPs9o8.d.mts +0 -11
  308. package/dist/AuthComponent-hxOPs9o8.d.ts +0 -11
  309. package/dist/BlockNoteEditor-FGXYUAWI.js.map +0 -1
  310. package/dist/JsonApiRequest-FXZCYIER.js +0 -24
  311. package/dist/chunk-6YD42BP6.js.map +0 -1
  312. package/dist/chunk-C6QXZGL7.js.map +0 -1
  313. package/dist/chunk-FPZPD4JI.js.map +0 -1
  314. package/dist/chunk-JGVXZS7M.mjs.map +0 -1
  315. package/dist/chunk-PK5DRSUD.js.map +0 -1
  316. package/dist/chunk-SJIVGCNM.mjs.map +0 -1
  317. package/dist/chunk-TGBXBUWM.mjs.map +0 -1
  318. package/dist/chunk-WAFOKMKT.mjs.map +0 -1
  319. package/src/discord/config.ts +0 -15
  320. package/src/discord/index.ts +0 -1
  321. /package/dist/{JsonApiRequest-HFWXMKMA.mjs.map → JsonApiRequest-XWQWTFEQ.mjs.map} +0 -0
@@ -0,0 +1,123 @@
1
+ import { AbstractService, EndpointCreator, HttpMethod, Modules, NextRef, PreviousRef } from "../../../../core";
2
+ import { StripePriceInput, StripePriceInterface } from "./stripe-price.interface";
3
+
4
+ /**
5
+ * Admin billing service for managing products and prices
6
+ */
7
+ export class StripePriceService extends AbstractService {
8
+ /**
9
+ * List all prices (admin)
10
+ */
11
+ static async listPrices(params?: {
12
+ productId?: string;
13
+ active?: boolean;
14
+ next?: NextRef;
15
+ prev?: PreviousRef;
16
+ }): Promise<StripePriceInterface[]> {
17
+ const endpoint = new EndpointCreator({
18
+ endpoint: Modules.StripePrice,
19
+ });
20
+
21
+ if (params?.productId) {
22
+ endpoint.addAdditionalParam("productId", params.productId);
23
+ }
24
+ if (params?.active !== undefined) {
25
+ endpoint.addAdditionalParam("active", params.active.toString());
26
+ }
27
+
28
+ return this.callApi({
29
+ type: Modules.StripePrice,
30
+ method: HttpMethod.GET,
31
+ endpoint: endpoint.generate(),
32
+ next: params?.next,
33
+ previous: params?.prev,
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Get a specific price by ID (admin)
39
+ */
40
+ static async getPrice(params: { id: string }): Promise<StripePriceInterface> {
41
+ const endpoint = new EndpointCreator({
42
+ endpoint: Modules.StripePrice,
43
+ id: params.id,
44
+ });
45
+
46
+ return this.callApi<StripePriceInterface>({
47
+ type: Modules.StripePrice,
48
+ method: HttpMethod.GET,
49
+ endpoint: endpoint.generate(),
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Create a new price (admin)
55
+ */
56
+ static async createPrice(params: StripePriceInput): Promise<StripePriceInterface> {
57
+ const endpoint = new EndpointCreator({
58
+ endpoint: Modules.StripePrice,
59
+ });
60
+
61
+ return this.callApi<StripePriceInterface>({
62
+ type: Modules.StripePrice,
63
+ method: HttpMethod.POST,
64
+ endpoint: endpoint.generate(),
65
+ input: params,
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Update an existing price (admin)
71
+ */
72
+ static async updatePrice(params: StripePriceInput): Promise<StripePriceInterface> {
73
+ const endpoint = new EndpointCreator({
74
+ endpoint: Modules.StripePrice,
75
+ id: params.id,
76
+ });
77
+
78
+ return this.callApi<StripePriceInterface>({
79
+ type: Modules.StripePrice,
80
+ method: HttpMethod.PUT,
81
+ endpoint: endpoint.generate(),
82
+ input: params,
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Archive a price (admin)
88
+ *
89
+ * Sets the price as inactive. Archived prices cannot be used for new subscriptions.
90
+ */
91
+ static async archivePrice(params: { id: string }): Promise<void> {
92
+ const endpoint = new EndpointCreator({
93
+ endpoint: Modules.StripePrice,
94
+ id: params.id,
95
+ childEndpoint: "archive",
96
+ });
97
+
98
+ await this.callApi({
99
+ type: Modules.StripePrice,
100
+ method: HttpMethod.POST,
101
+ endpoint: endpoint.generate(),
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Reactivate a price (admin)
107
+ *
108
+ * Sets the price as active. Active prices can be used for new subscriptions.
109
+ */
110
+ static async reactivatePrice(params: { id: string }): Promise<void> {
111
+ const endpoint = new EndpointCreator({
112
+ endpoint: Modules.StripePrice,
113
+ id: params.id,
114
+ childEndpoint: "archive",
115
+ });
116
+
117
+ await this.callApi({
118
+ type: Modules.StripePrice,
119
+ method: HttpMethod.DELETE,
120
+ endpoint: endpoint.generate(),
121
+ });
122
+ }
123
+ }
@@ -0,0 +1,156 @@
1
+ import { AbstractApiData, JsonApiHydratedDataInterface, Modules } from "../../../../core";
2
+ import { StripeProductInterface } from "../../stripe-product";
3
+ import { PriceRecurring, StripePriceInput, StripePriceInterface } from "./stripe-price.interface";
4
+
5
+ export class StripePrice extends AbstractApiData implements StripePriceInterface {
6
+ private _stripePriceId?: string;
7
+ private _productId?: string;
8
+ private _product?: StripeProductInterface;
9
+ private _active: boolean = true;
10
+ private _currency?: string;
11
+ private _unitAmount?: number;
12
+ private _recurring?: PriceRecurring;
13
+ private _priceType?: "one_time" | "recurring";
14
+ private _nickname?: string;
15
+ private _lookupKey?: string;
16
+ private _metadata?: Record<string, any>;
17
+ private _description?: string;
18
+ private _features?: string[];
19
+
20
+ get stripePriceId(): string {
21
+ if (!this._stripePriceId) throw new Error("stripePriceId is not defined");
22
+ return this._stripePriceId;
23
+ }
24
+
25
+ get productId(): string {
26
+ if (!this._productId) throw new Error("productId is not defined");
27
+ return this._productId;
28
+ }
29
+
30
+ get product(): StripeProductInterface | undefined {
31
+ return this._product;
32
+ }
33
+
34
+ get active(): boolean {
35
+ return this._active;
36
+ }
37
+
38
+ get currency(): string {
39
+ if (!this._currency) throw new Error("currency is not defined");
40
+ return this._currency;
41
+ }
42
+
43
+ get unitAmount(): number | undefined {
44
+ return this._unitAmount;
45
+ }
46
+
47
+ get recurring(): PriceRecurring | undefined {
48
+ return this._recurring;
49
+ }
50
+
51
+ get priceType(): "one_time" | "recurring" {
52
+ if (!this._priceType) throw new Error("priceType is not defined");
53
+ return this._priceType;
54
+ }
55
+
56
+ get nickname(): string | undefined {
57
+ return this._nickname;
58
+ }
59
+
60
+ get lookupKey(): string | undefined {
61
+ return this._lookupKey;
62
+ }
63
+
64
+ get metadata(): Record<string, any> | undefined {
65
+ return this._metadata;
66
+ }
67
+
68
+ get description(): string | undefined {
69
+ return this._description;
70
+ }
71
+
72
+ get features(): string[] | undefined {
73
+ return this._features;
74
+ }
75
+
76
+ rehydrate(data: JsonApiHydratedDataInterface): this {
77
+ super.rehydrate(data);
78
+
79
+ this._stripePriceId = data.jsonApi.attributes.stripePriceId;
80
+ this._productId = data.jsonApi.attributes.productId;
81
+ this._active = data.jsonApi.attributes.active ?? true;
82
+ this._currency = data.jsonApi.attributes.currency;
83
+ this._unitAmount = data.jsonApi.attributes.unitAmount;
84
+ this._priceType = data.jsonApi.attributes.priceType;
85
+
86
+ // Construct recurring object from flat attributes
87
+ if (data.jsonApi.attributes.recurringInterval) {
88
+ this._recurring = {
89
+ interval: data.jsonApi.attributes.recurringInterval,
90
+ intervalCount: data.jsonApi.attributes.recurringIntervalCount ?? 1,
91
+ usageType: data.jsonApi.attributes.recurringUsageType,
92
+ };
93
+ }
94
+
95
+ this._nickname = data.jsonApi.attributes.nickname;
96
+ this._lookupKey = data.jsonApi.attributes.lookupKey;
97
+
98
+ this._metadata = data.jsonApi.attributes.metadata
99
+ ? typeof data.jsonApi.attributes.metadata === "string"
100
+ ? JSON.parse(data.jsonApi.attributes.metadata)
101
+ : data.jsonApi.attributes.metadata
102
+ : undefined;
103
+
104
+ this._description = data.jsonApi.attributes.description;
105
+ this._features = data.jsonApi.attributes.features
106
+ ? typeof data.jsonApi.attributes.features === "string"
107
+ ? JSON.parse(data.jsonApi.attributes.features)
108
+ : data.jsonApi.attributes.features
109
+ : undefined;
110
+
111
+ // Hydrate product relationship
112
+ this._product = this._readIncluded(data, "product", Modules.StripeProduct) as StripeProductInterface;
113
+
114
+ return this;
115
+ }
116
+
117
+ createJsonApi(data: StripePriceInput): any {
118
+ const response: any = {
119
+ data: {
120
+ type: Modules.StripePrice.name,
121
+ id: data.id,
122
+ attributes: {},
123
+ },
124
+ };
125
+
126
+ if ("productId" in data && data.productId) {
127
+ response.data.attributes.productId = data.productId;
128
+ }
129
+ if ("currency" in data && data.currency) {
130
+ response.data.attributes.currency = data.currency;
131
+ }
132
+ if ("unitAmount" in data && data.unitAmount !== undefined) {
133
+ response.data.attributes.unitAmount = data.unitAmount;
134
+ }
135
+ if ("active" in data && data.active !== undefined) {
136
+ response.data.attributes.active = data.active;
137
+ }
138
+ if ("nickname" in data && data.nickname !== undefined) {
139
+ response.data.attributes.nickname = data.nickname;
140
+ }
141
+ if ("metadata" in data && data.metadata) {
142
+ response.data.attributes.metadata = data.metadata;
143
+ }
144
+ if ("recurring" in data && data.recurring) {
145
+ response.data.attributes.recurring = data.recurring;
146
+ }
147
+ if ("description" in data && data.description !== undefined) {
148
+ response.data.attributes.description = data.description;
149
+ }
150
+ if ("features" in data && data.features !== undefined) {
151
+ response.data.attributes.features = JSON.stringify(data.features);
152
+ }
153
+
154
+ return response;
155
+ }
156
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./data";
2
+ export * from "./stripe-price.module";
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../../permissions";
2
+ import { StripePrice } from "./data/stripe-price";
3
+
4
+ export const StripePriceModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "stripe-prices",
7
+ model: StripePrice,
8
+ moduleId: "a7d3e5f1-8c9b-4a2e-b6d7-3f1c8e9a4b5d",
9
+ });
@@ -0,0 +1,86 @@
1
+ "use client";
2
+
3
+ import { Package } from "lucide-react";
4
+ import { useEffect, useState } from "react";
5
+ import { getRoleId } from "../../../../../roles";
6
+ import { Button } from "../../../../../shadcnui";
7
+ import { useCurrentUserContext } from "../../../../user/contexts";
8
+ import { StripeProductInterface } from "../../data/stripe-product.interface";
9
+ import { StripeProductService } from "../../data/stripe-product.service";
10
+ import { ProductEditor } from "../forms/ProductEditor";
11
+ import { ProductsList } from "../lists/ProductsList";
12
+
13
+ export function ProductsAdminContainer() {
14
+ const { hasRole } = useCurrentUserContext();
15
+ const [products, setProducts] = useState<StripeProductInterface[]>([]);
16
+ const [loading, setLoading] = useState<boolean>(true);
17
+ const [showCreateProduct, setShowCreateProduct] = useState<boolean>(false);
18
+
19
+ // Check if user has Administrator role
20
+ if (!hasRole(getRoleId().Administrator)) {
21
+ return (
22
+ <div className="flex h-64 items-center justify-center">
23
+ <p className="text-red-600 font-semibold">Permission denied. Administrator access required.</p>
24
+ </div>
25
+ );
26
+ }
27
+
28
+ const loadProducts = async () => {
29
+ setLoading(true);
30
+ try {
31
+ const fetchedProducts = await StripeProductService.listProducts();
32
+ setProducts(fetchedProducts);
33
+ } catch (error) {
34
+ console.error("[ProductsAdminContainer] Failed to load products:", error);
35
+ } finally {
36
+ setLoading(false);
37
+ }
38
+ };
39
+
40
+ useEffect(() => {
41
+ loadProducts();
42
+ }, []);
43
+
44
+ if (loading) {
45
+ return (
46
+ <div className="flex h-64 items-center justify-center">
47
+ <p className="text-muted-foreground">Loading products...</p>
48
+ </div>
49
+ );
50
+ }
51
+
52
+ return (
53
+ <div className="flex w-full flex-col gap-y-6">
54
+ {/* Header */}
55
+ <div className="flex items-center justify-between">
56
+ <div className="flex items-center gap-x-3">
57
+ <Package className="h-8 w-8" />
58
+ <h1 className="text-3xl font-bold">Product & Price Management</h1>
59
+ </div>
60
+ <Button onClick={() => setShowCreateProduct(true)}>Create Product</Button>
61
+ </div>
62
+
63
+ {/* Empty State */}
64
+ {products.length === 0 && (
65
+ <div className="bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12">
66
+ <Package className="text-muted-foreground h-16 w-16" />
67
+ <div className="text-center">
68
+ <h3 className="mb-2 text-xl font-semibold">No products yet</h3>
69
+ <p className="text-muted-foreground mb-4">
70
+ Create your first product to start offering subscriptions to your customers.
71
+ </p>
72
+ <Button onClick={() => setShowCreateProduct(true)}>Create Your First Product</Button>
73
+ </div>
74
+ </div>
75
+ )}
76
+
77
+ {/* Products List */}
78
+ {products.length > 0 && <ProductsList products={products} onProductsChange={loadProducts} />}
79
+
80
+ {/* Create Product Modal */}
81
+ {showCreateProduct && (
82
+ <ProductEditor open={showCreateProduct} onOpenChange={setShowCreateProduct} onSuccess={loadProducts} />
83
+ )}
84
+ </div>
85
+ );
86
+ }
@@ -0,0 +1 @@
1
+ export * from "./ProductsAdminContainer";
@@ -0,0 +1,100 @@
1
+ "use client";
2
+
3
+ import { zodResolver } from "@hookform/resolvers/zod";
4
+ import { useState } from "react";
5
+ import { SubmitHandler, useForm } from "react-hook-form";
6
+ import { v4 } from "uuid";
7
+ import { z } from "zod";
8
+ import { FormCheckbox, FormInput, FormTextarea } from "../../../../../components";
9
+ import { CommonEditorButtons } from "../../../../../components/forms/CommonEditorButtons";
10
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Form } from "../../../../../shadcnui";
11
+ import { StripeProductInterface } from "../../data/stripe-product.interface";
12
+ import { StripeProductService } from "../../data/stripe-product.service";
13
+
14
+ type ProductEditorProps = {
15
+ product?: StripeProductInterface;
16
+ open: boolean;
17
+ onOpenChange: (open: boolean) => void;
18
+ onSuccess: () => void;
19
+ };
20
+
21
+ export function ProductEditor({ product, open, onOpenChange, onSuccess }: ProductEditorProps) {
22
+ const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
23
+
24
+ const formSchema = z.object({
25
+ name: z.string().min(1, { message: "Product name is required" }),
26
+ description: z.string().optional(),
27
+ active: z.boolean(),
28
+ });
29
+
30
+ const form = useForm<z.infer<typeof formSchema>>({
31
+ resolver: zodResolver(formSchema),
32
+ defaultValues: {
33
+ name: product?.name || "",
34
+ description: product?.description || "",
35
+ active: product?.active ?? true,
36
+ },
37
+ });
38
+
39
+ const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values) => {
40
+ setIsSubmitting(true);
41
+
42
+ try {
43
+ if (product) {
44
+ // Update existing product
45
+ await StripeProductService.updateProduct({
46
+ id: product.id,
47
+ name: values.name,
48
+ description: values.description,
49
+ active: values.active,
50
+ });
51
+ } else {
52
+ // Create new product
53
+ await StripeProductService.createProduct({
54
+ id: v4(),
55
+ name: values.name,
56
+ description: values.description,
57
+ active: values.active,
58
+ });
59
+ }
60
+
61
+ onSuccess();
62
+ onOpenChange(false);
63
+ } catch (error) {
64
+ console.error("[ProductEditor] Failed to save product:", error);
65
+ } finally {
66
+ setIsSubmitting(false);
67
+ }
68
+ };
69
+
70
+ return (
71
+ <Dialog open={open} onOpenChange={onOpenChange}>
72
+ <DialogContent className="max-w-2xl">
73
+ <DialogHeader>
74
+ <DialogTitle>{product ? "Edit Product" : "Create Product"}</DialogTitle>
75
+ <DialogDescription>
76
+ {product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers"}
77
+ </DialogDescription>
78
+ </DialogHeader>
79
+
80
+ <Form {...form}>
81
+ <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-y-4">
82
+ <FormInput form={form} id="name" name="Product Name" placeholder="Enter product name" isRequired />
83
+
84
+ <FormTextarea
85
+ form={form}
86
+ id="description"
87
+ name="Description"
88
+ placeholder="Enter product description (optional)"
89
+ className="min-h-32"
90
+ />
91
+
92
+ <FormCheckbox form={form} id="active" name="Active" />
93
+
94
+ <CommonEditorButtons isEdit={!!product} form={form} disabled={isSubmitting} setOpen={onOpenChange} />
95
+ </form>
96
+ </Form>
97
+ </DialogContent>
98
+ </Dialog>
99
+ );
100
+ }
@@ -0,0 +1 @@
1
+ export * from "./ProductEditor";
@@ -0,0 +1,3 @@
1
+ export * from "./containers";
2
+ export * from "./forms";
3
+ export * from "./lists";