@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
@@ -170,5 +170,5 @@ export interface GenerateWebModuleOptions {
170
170
  export interface GeneratedFile {
171
171
  path: string;
172
172
  content: string;
173
- type: "data" | "component" | "context" | "hook" | "module" | "page";
173
+ type: "data" | "component" | "context" | "hook" | "module" | "page" | "project-setup";
174
174
  }
@@ -10,6 +10,7 @@ let _clientConfig: {
10
10
  trackablePages?: ModuleWithPermissions[];
11
11
  bootstrapper?: () => void;
12
12
  additionalHeaders?: Record<string, string>;
13
+ stripePublishableKey?: string;
13
14
  } | null = null;
14
15
 
15
16
  /**
@@ -22,6 +23,7 @@ export function configureJsonApi(config: {
22
23
  trackablePages?: ModuleWithPermissions[];
23
24
  bootstrapper?: () => void;
24
25
  additionalHeaders?: Record<string, string>;
26
+ stripePublishableKey?: string;
25
27
  }): void {
26
28
  _clientConfig = config;
27
29
  // Register and call bootstrapper to register all modules
@@ -78,3 +80,10 @@ export function getAppUrl(): string {
78
80
  export function getTrackablePages(): ModuleWithPermissions[] {
79
81
  return _clientConfig?.trackablePages ?? [];
80
82
  }
83
+
84
+ /**
85
+ * Get the configured Stripe publishable key.
86
+ */
87
+ export function getStripePublishableKey(): string | undefined {
88
+ return _clientConfig?.stripePublishableKey;
89
+ }
@@ -0,0 +1,229 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { renderHook, waitFor, act } from "@testing-library/react";
3
+ import React from "react";
4
+ import { useJsonApiGet } from "../useJsonApiGet";
5
+ import { MockJsonApiProvider } from "../../../testing/providers/MockJsonApiProvider";
6
+ import { createMockModule, createMockResponse, createMockApiData } from "../../../testing";
7
+
8
+ // Mock the JsonApiRequest module
9
+ vi.mock("../../../unified/JsonApiRequest", () => ({
10
+ JsonApiGet: vi.fn(),
11
+ }));
12
+
13
+ describe("useJsonApiGet", () => {
14
+ const mockModule = createMockModule({ name: "articles" });
15
+ const mockData = createMockApiData({ type: "articles", id: "1", attributes: { title: "Test Article" } });
16
+
17
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
18
+ <MockJsonApiProvider>{children}</MockJsonApiProvider>
19
+ );
20
+
21
+ beforeEach(() => {
22
+ vi.clearAllMocks();
23
+ });
24
+
25
+ afterEach(() => {
26
+ vi.resetModules();
27
+ });
28
+
29
+ it("should initialize with loading state", async () => {
30
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
31
+ (JsonApiGet as any).mockImplementation(() => new Promise(() => {})); // Never resolves
32
+
33
+ const { result } = renderHook(
34
+ () =>
35
+ useJsonApiGet({
36
+ classKey: mockModule,
37
+ endpoint: "/articles/1",
38
+ }),
39
+ { wrapper }
40
+ );
41
+
42
+ expect(result.current.loading).toBe(true);
43
+ expect(result.current.data).toBeNull();
44
+ expect(result.current.error).toBeNull();
45
+ });
46
+
47
+ it("should fetch data on mount", async () => {
48
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
49
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
50
+ (JsonApiGet as any).mockResolvedValue(mockResponse);
51
+
52
+ const { result } = renderHook(
53
+ () =>
54
+ useJsonApiGet({
55
+ classKey: mockModule,
56
+ endpoint: "/articles/1",
57
+ }),
58
+ { wrapper }
59
+ );
60
+
61
+ await waitFor(() => {
62
+ expect(result.current.loading).toBe(false);
63
+ });
64
+
65
+ expect(result.current.data).toBe(mockData);
66
+ expect(result.current.error).toBeNull();
67
+ expect(result.current.response).toBe(mockResponse);
68
+ });
69
+
70
+ it("should not fetch when enabled is false", async () => {
71
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
72
+ (JsonApiGet as any).mockResolvedValue(createMockResponse({ data: mockData, ok: true }));
73
+
74
+ const { result } = renderHook(
75
+ () =>
76
+ useJsonApiGet({
77
+ classKey: mockModule,
78
+ endpoint: "/articles/1",
79
+ options: { enabled: false },
80
+ }),
81
+ { wrapper }
82
+ );
83
+
84
+ // Wait a bit to ensure no fetch happens
85
+ await new Promise((r) => setTimeout(r, 100));
86
+
87
+ expect(JsonApiGet).not.toHaveBeenCalled();
88
+ expect(result.current.loading).toBe(false);
89
+ expect(result.current.data).toBeNull();
90
+ });
91
+
92
+ it("should handle errors", async () => {
93
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
94
+ const errorResponse = createMockResponse({
95
+ ok: false,
96
+ response: 404,
97
+ error: "Not Found",
98
+ });
99
+ (JsonApiGet as any).mockResolvedValue(errorResponse);
100
+
101
+ const { result } = renderHook(
102
+ () =>
103
+ useJsonApiGet({
104
+ classKey: mockModule,
105
+ endpoint: "/articles/999",
106
+ }),
107
+ { wrapper }
108
+ );
109
+
110
+ await waitFor(() => {
111
+ expect(result.current.loading).toBe(false);
112
+ });
113
+
114
+ expect(result.current.data).toBeNull();
115
+ expect(result.current.error).toBe("Not Found");
116
+ });
117
+
118
+ it("should handle thrown errors", async () => {
119
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
120
+ (JsonApiGet as any).mockRejectedValue(new Error("Network error"));
121
+
122
+ const { result } = renderHook(
123
+ () =>
124
+ useJsonApiGet({
125
+ classKey: mockModule,
126
+ endpoint: "/articles/1",
127
+ }),
128
+ { wrapper }
129
+ );
130
+
131
+ await waitFor(() => {
132
+ expect(result.current.loading).toBe(false);
133
+ });
134
+
135
+ expect(result.current.error).toBe("Network error");
136
+ });
137
+
138
+ it("should support refetch", async () => {
139
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
140
+ let callCount = 0;
141
+ (JsonApiGet as any).mockImplementation(() => {
142
+ callCount++;
143
+ return Promise.resolve(
144
+ createMockResponse({
145
+ data: createMockApiData({
146
+ type: "articles",
147
+ id: "1",
148
+ attributes: { title: `Article ${callCount}` },
149
+ }),
150
+ ok: true,
151
+ })
152
+ );
153
+ });
154
+
155
+ const { result } = renderHook(
156
+ () =>
157
+ useJsonApiGet({
158
+ classKey: mockModule,
159
+ endpoint: "/articles/1",
160
+ }),
161
+ { wrapper }
162
+ );
163
+
164
+ await waitFor(() => {
165
+ expect(result.current.loading).toBe(false);
166
+ });
167
+
168
+ expect(callCount).toBe(1);
169
+
170
+ // Trigger refetch
171
+ await act(async () => {
172
+ await result.current.refetch();
173
+ });
174
+
175
+ expect(callCount).toBe(2);
176
+ });
177
+
178
+ it("should indicate pagination availability", async () => {
179
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
180
+ const mockResponse = createMockResponse({
181
+ data: mockData,
182
+ ok: true,
183
+ next: "/articles?page=2",
184
+ prev: "/articles?page=0",
185
+ });
186
+ (JsonApiGet as any).mockResolvedValue(mockResponse);
187
+
188
+ const { result } = renderHook(
189
+ () =>
190
+ useJsonApiGet({
191
+ classKey: mockModule,
192
+ endpoint: "/articles",
193
+ }),
194
+ { wrapper }
195
+ );
196
+
197
+ await waitFor(() => {
198
+ expect(result.current.loading).toBe(false);
199
+ });
200
+
201
+ expect(result.current.hasNextPage).toBe(true);
202
+ expect(result.current.hasPreviousPage).toBe(true);
203
+ });
204
+
205
+ it("should handle no pagination", async () => {
206
+ const { JsonApiGet } = await import("../../../unified/JsonApiRequest");
207
+ const mockResponse = createMockResponse({
208
+ data: mockData,
209
+ ok: true,
210
+ });
211
+ (JsonApiGet as any).mockResolvedValue(mockResponse);
212
+
213
+ const { result } = renderHook(
214
+ () =>
215
+ useJsonApiGet({
216
+ classKey: mockModule,
217
+ endpoint: "/articles/1",
218
+ }),
219
+ { wrapper }
220
+ );
221
+
222
+ await waitFor(() => {
223
+ expect(result.current.loading).toBe(false);
224
+ });
225
+
226
+ expect(result.current.hasNextPage).toBe(false);
227
+ expect(result.current.hasPreviousPage).toBe(false);
228
+ });
229
+ });
@@ -0,0 +1,348 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { renderHook, waitFor, act } from "@testing-library/react";
3
+ import React from "react";
4
+ import { useJsonApiMutation } from "../useJsonApiMutation";
5
+ import { MockJsonApiProvider } from "../../../testing/providers/MockJsonApiProvider";
6
+ import { createMockModule, createMockResponse, createMockApiData } from "../../../testing";
7
+
8
+ // Mock the JsonApiRequest module
9
+ vi.mock("../../../unified/JsonApiRequest", () => ({
10
+ JsonApiPost: vi.fn(),
11
+ JsonApiPut: vi.fn(),
12
+ JsonApiPatch: vi.fn(),
13
+ JsonApiDelete: vi.fn(),
14
+ }));
15
+
16
+ describe("useJsonApiMutation", () => {
17
+ const mockModule = createMockModule({ name: "articles" });
18
+ const mockData = createMockApiData({
19
+ type: "articles",
20
+ id: "1",
21
+ attributes: { title: "Created Article" },
22
+ });
23
+
24
+ const wrapper = ({ children }: { children: React.ReactNode }) => (
25
+ <MockJsonApiProvider>{children}</MockJsonApiProvider>
26
+ );
27
+
28
+ beforeEach(() => {
29
+ vi.clearAllMocks();
30
+ });
31
+
32
+ afterEach(() => {
33
+ vi.resetModules();
34
+ });
35
+
36
+ describe("POST mutations", () => {
37
+ it("should initialize with idle state", () => {
38
+ const { result } = renderHook(
39
+ () =>
40
+ useJsonApiMutation({
41
+ method: "POST",
42
+ classKey: mockModule,
43
+ }),
44
+ { wrapper }
45
+ );
46
+
47
+ expect(result.current.loading).toBe(false);
48
+ expect(result.current.data).toBeNull();
49
+ expect(result.current.error).toBeNull();
50
+ expect(result.current.response).toBeNull();
51
+ });
52
+
53
+ it("should execute POST mutation", async () => {
54
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
55
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
56
+ (JsonApiPost as any).mockResolvedValue(mockResponse);
57
+
58
+ const { result } = renderHook(
59
+ () =>
60
+ useJsonApiMutation({
61
+ method: "POST",
62
+ classKey: mockModule,
63
+ }),
64
+ { wrapper }
65
+ );
66
+
67
+ let mutationResult: any;
68
+ await act(async () => {
69
+ mutationResult = await result.current.mutate({
70
+ endpoint: "/articles",
71
+ body: { title: "New Article" },
72
+ });
73
+ });
74
+
75
+ expect(result.current.data).toBe(mockData);
76
+ expect(result.current.error).toBeNull();
77
+ expect(mutationResult).toBe(mockData);
78
+ expect(JsonApiPost).toHaveBeenCalled();
79
+ });
80
+
81
+ it("should handle POST errors", async () => {
82
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
83
+ const errorResponse = createMockResponse({
84
+ ok: false,
85
+ response: 400,
86
+ error: "Validation failed",
87
+ });
88
+ (JsonApiPost as any).mockResolvedValue(errorResponse);
89
+
90
+ const { result } = renderHook(
91
+ () =>
92
+ useJsonApiMutation({
93
+ method: "POST",
94
+ classKey: mockModule,
95
+ }),
96
+ { wrapper }
97
+ );
98
+
99
+ let mutationResult: any;
100
+ await act(async () => {
101
+ mutationResult = await result.current.mutate({
102
+ endpoint: "/articles",
103
+ body: {},
104
+ });
105
+ });
106
+
107
+ expect(result.current.data).toBeNull();
108
+ expect(result.current.error).toBe("Validation failed");
109
+ expect(mutationResult).toBeNull();
110
+ });
111
+
112
+ it("should call onSuccess callback", async () => {
113
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
114
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
115
+ (JsonApiPost as any).mockResolvedValue(mockResponse);
116
+ const onSuccess = vi.fn();
117
+
118
+ const { result } = renderHook(
119
+ () =>
120
+ useJsonApiMutation({
121
+ method: "POST",
122
+ classKey: mockModule,
123
+ onSuccess,
124
+ }),
125
+ { wrapper }
126
+ );
127
+
128
+ await act(async () => {
129
+ await result.current.mutate({
130
+ endpoint: "/articles",
131
+ body: { title: "New" },
132
+ });
133
+ });
134
+
135
+ expect(onSuccess).toHaveBeenCalledWith(mockData);
136
+ });
137
+
138
+ it("should call onError callback", async () => {
139
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
140
+ const errorResponse = createMockResponse({
141
+ ok: false,
142
+ error: "Failed",
143
+ });
144
+ (JsonApiPost as any).mockResolvedValue(errorResponse);
145
+ const onError = vi.fn();
146
+
147
+ const { result } = renderHook(
148
+ () =>
149
+ useJsonApiMutation({
150
+ method: "POST",
151
+ classKey: mockModule,
152
+ onError,
153
+ }),
154
+ { wrapper }
155
+ );
156
+
157
+ await act(async () => {
158
+ await result.current.mutate({
159
+ endpoint: "/articles",
160
+ body: {},
161
+ });
162
+ });
163
+
164
+ expect(onError).toHaveBeenCalledWith("Failed");
165
+ });
166
+ });
167
+
168
+ describe("PUT mutations", () => {
169
+ it("should execute PUT mutation", async () => {
170
+ const { JsonApiPut } = await import("../../../unified/JsonApiRequest");
171
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
172
+ (JsonApiPut as any).mockResolvedValue(mockResponse);
173
+
174
+ const { result } = renderHook(
175
+ () =>
176
+ useJsonApiMutation({
177
+ method: "PUT",
178
+ classKey: mockModule,
179
+ }),
180
+ { wrapper }
181
+ );
182
+
183
+ await act(async () => {
184
+ await result.current.mutate({
185
+ endpoint: "/articles/1",
186
+ body: { title: "Updated" },
187
+ });
188
+ });
189
+
190
+ expect(JsonApiPut).toHaveBeenCalled();
191
+ expect(result.current.data).toBe(mockData);
192
+ });
193
+ });
194
+
195
+ describe("PATCH mutations", () => {
196
+ it("should execute PATCH mutation", async () => {
197
+ const { JsonApiPatch } = await import("../../../unified/JsonApiRequest");
198
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
199
+ (JsonApiPatch as any).mockResolvedValue(mockResponse);
200
+
201
+ const { result } = renderHook(
202
+ () =>
203
+ useJsonApiMutation({
204
+ method: "PATCH",
205
+ classKey: mockModule,
206
+ }),
207
+ { wrapper }
208
+ );
209
+
210
+ await act(async () => {
211
+ await result.current.mutate({
212
+ endpoint: "/articles/1",
213
+ body: { title: "Patched" },
214
+ });
215
+ });
216
+
217
+ expect(JsonApiPatch).toHaveBeenCalled();
218
+ expect(result.current.data).toBe(mockData);
219
+ });
220
+ });
221
+
222
+ describe("DELETE mutations", () => {
223
+ it("should execute DELETE mutation", async () => {
224
+ const { JsonApiDelete } = await import("../../../unified/JsonApiRequest");
225
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
226
+ (JsonApiDelete as any).mockResolvedValue(mockResponse);
227
+
228
+ const { result } = renderHook(
229
+ () =>
230
+ useJsonApiMutation({
231
+ method: "DELETE",
232
+ classKey: mockModule,
233
+ }),
234
+ { wrapper }
235
+ );
236
+
237
+ await act(async () => {
238
+ await result.current.mutate({
239
+ endpoint: "/articles/1",
240
+ });
241
+ });
242
+
243
+ expect(JsonApiDelete).toHaveBeenCalled();
244
+ });
245
+ });
246
+
247
+ describe("reset", () => {
248
+ it("should reset state", async () => {
249
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
250
+ const mockResponse = createMockResponse({ data: mockData, ok: true });
251
+ (JsonApiPost as any).mockResolvedValue(mockResponse);
252
+
253
+ const { result } = renderHook(
254
+ () =>
255
+ useJsonApiMutation({
256
+ method: "POST",
257
+ classKey: mockModule,
258
+ }),
259
+ { wrapper }
260
+ );
261
+
262
+ await act(async () => {
263
+ await result.current.mutate({
264
+ endpoint: "/articles",
265
+ body: {},
266
+ });
267
+ });
268
+
269
+ expect(result.current.data).not.toBeNull();
270
+
271
+ act(() => {
272
+ result.current.reset();
273
+ });
274
+
275
+ expect(result.current.data).toBeNull();
276
+ expect(result.current.error).toBeNull();
277
+ expect(result.current.response).toBeNull();
278
+ expect(result.current.loading).toBe(false);
279
+ });
280
+ });
281
+
282
+ describe("loading state", () => {
283
+ it("should set loading during mutation", async () => {
284
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
285
+ let resolvePromise: any;
286
+ const pendingPromise = new Promise((resolve) => {
287
+ resolvePromise = resolve;
288
+ });
289
+ (JsonApiPost as any).mockReturnValue(pendingPromise);
290
+
291
+ const { result } = renderHook(
292
+ () =>
293
+ useJsonApiMutation({
294
+ method: "POST",
295
+ classKey: mockModule,
296
+ }),
297
+ { wrapper }
298
+ );
299
+
300
+ // Start mutation without awaiting
301
+ act(() => {
302
+ result.current.mutate({
303
+ endpoint: "/articles",
304
+ body: {},
305
+ });
306
+ });
307
+
308
+ // Should be loading
309
+ expect(result.current.loading).toBe(true);
310
+
311
+ // Resolve the promise
312
+ await act(async () => {
313
+ resolvePromise(createMockResponse({ data: mockData, ok: true }));
314
+ });
315
+
316
+ // Loading should be false after completion
317
+ await waitFor(() => {
318
+ expect(result.current.loading).toBe(false);
319
+ });
320
+ });
321
+ });
322
+
323
+ describe("error handling", () => {
324
+ it("should handle thrown exceptions", async () => {
325
+ const { JsonApiPost } = await import("../../../unified/JsonApiRequest");
326
+ (JsonApiPost as any).mockRejectedValue(new Error("Network error"));
327
+
328
+ const { result } = renderHook(
329
+ () =>
330
+ useJsonApiMutation({
331
+ method: "POST",
332
+ classKey: mockModule,
333
+ }),
334
+ { wrapper }
335
+ );
336
+
337
+ await act(async () => {
338
+ await result.current.mutate({
339
+ endpoint: "/articles",
340
+ body: {},
341
+ });
342
+ });
343
+
344
+ expect(result.current.error).toBe("Network error");
345
+ expect(result.current.data).toBeNull();
346
+ });
347
+ });
348
+ });