@carlonicora/nextjs-jsonapi 1.4.0 → 1.6.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 (317) hide show
  1. package/README.md +208 -127
  2. package/dist/{ApiResponseInterface-DDI7QQPR.d.ts → ApiResponseInterface-CfcC7pPC.d.mts} +11 -2
  3. package/dist/{ApiResponseInterface-BHN5D9r5.d.mts → ApiResponseInterface-DTBJaV5R.d.ts} +11 -2
  4. package/dist/{BlockNoteEditor-QV6ESIQA.js → BlockNoteEditor-7FM7B737.js} +19 -24
  5. package/dist/BlockNoteEditor-7FM7B737.js.map +1 -0
  6. package/dist/{BlockNoteEditor-U2IHUVUF.mjs → BlockNoteEditor-RVL76ZAS.mjs} +11 -16
  7. package/dist/BlockNoteEditor-RVL76ZAS.mjs.map +1 -0
  8. package/dist/JsonApiRequest-KOKGVPBI.js +25 -0
  9. package/dist/{JsonApiRequest-UJ7FGIVI.js.map → JsonApiRequest-KOKGVPBI.js.map} +1 -1
  10. package/dist/{JsonApiRequest-6UR7DIAR.mjs → JsonApiRequest-VCCRO732.mjs} +2 -2
  11. package/dist/chunk-2Z56AS2S.js +2723 -0
  12. package/dist/chunk-2Z56AS2S.js.map +1 -0
  13. package/dist/{chunk-HTLEKZND.mjs → chunk-37NJZ2VD.mjs} +281 -1019
  14. package/dist/chunk-37NJZ2VD.mjs.map +1 -0
  15. package/dist/{chunk-2K3Q24UF.js → chunk-3ZPK4QOB.js} +24 -14
  16. package/dist/chunk-3ZPK4QOB.js.map +1 -0
  17. package/dist/chunk-AGWQ75PQ.js +142 -0
  18. package/dist/chunk-AGWQ75PQ.js.map +1 -0
  19. package/dist/{chunk-32HM6MDD.js → chunk-CSM6AIAP.js} +1 -1
  20. package/dist/{chunk-32HM6MDD.js.map → chunk-CSM6AIAP.js.map} +1 -1
  21. package/dist/{chunk-IKBA4AHN.mjs → chunk-F4Y3GZG4.mjs} +3 -3
  22. package/dist/{chunk-YF5XQZDR.mjs → chunk-F5UNXZ3J.mjs} +1 -1
  23. package/dist/chunk-F5UNXZ3J.mjs.map +1 -0
  24. package/dist/chunk-IGOWVLJH.mjs +142 -0
  25. package/dist/chunk-IGOWVLJH.mjs.map +1 -0
  26. package/dist/{chunk-HAG77QBV.mjs → chunk-K4W5QXL5.mjs} +1 -1
  27. package/dist/chunk-KFL5ZFM4.mjs +2723 -0
  28. package/dist/chunk-KFL5ZFM4.mjs.map +1 -0
  29. package/dist/{chunk-HR4H2FP7.mjs → chunk-KJ4ETLJB.mjs} +24 -14
  30. package/dist/chunk-KJ4ETLJB.mjs.map +1 -0
  31. package/dist/chunk-LOSPCUCF.js +637 -0
  32. package/dist/chunk-LOSPCUCF.js.map +1 -0
  33. package/dist/{chunk-E2HRC2OG.js → chunk-SVX7E6RR.js} +10360 -6256
  34. package/dist/chunk-SVX7E6RR.js.map +1 -0
  35. package/dist/{chunk-EFJEWLRL.js → chunk-YUO55Q5A.js} +1 -1
  36. package/dist/chunk-YUO55Q5A.js.map +1 -0
  37. package/dist/chunk-ZQTFZKLJ.mjs +12089 -0
  38. package/dist/chunk-ZQTFZKLJ.mjs.map +1 -0
  39. package/dist/{chunk-PMXG5WBC.js → chunk-ZUEEIQHW.js} +3 -3
  40. package/dist/{chunk-PMXG5WBC.js.map → chunk-ZUEEIQHW.js.map} +1 -1
  41. package/dist/client/index.d.mts +161 -11
  42. package/dist/client/index.d.ts +161 -11
  43. package/dist/client/index.js +74 -12
  44. package/dist/client/index.js.map +1 -1
  45. package/dist/client/index.mjs +73 -11
  46. package/dist/components/index.d.mts +762 -73
  47. package/dist/components/index.d.ts +762 -73
  48. package/dist/components/index.js +465 -12
  49. package/dist/components/index.js.map +1 -1
  50. package/dist/components/index.mjs +466 -13
  51. package/dist/config-B43zxEvn.d.mts +69 -0
  52. package/dist/config-D2OUrI_G.d.ts +69 -0
  53. package/dist/content.fields-Ck5lkQ5d.d.mts +47 -0
  54. package/dist/content.fields-Ck5lkQ5d.d.ts +47 -0
  55. package/dist/{content.interface-C_PGZMuy.d.ts → content.interface-Bs8a7uW6.d.mts} +2 -3
  56. package/dist/{content.interface-D_WS6CrB.d.mts → content.interface-UtsJ-mzs.d.ts} +2 -3
  57. package/dist/contexts/index.d.mts +13 -6
  58. package/dist/contexts/index.d.ts +13 -6
  59. package/dist/contexts/index.js +10 -12
  60. package/dist/contexts/index.js.map +1 -1
  61. package/dist/contexts/index.mjs +9 -11
  62. package/dist/core/index.d.mts +539 -8
  63. package/dist/core/index.d.ts +539 -8
  64. package/dist/core/index.js +104 -2
  65. package/dist/core/index.js.map +1 -1
  66. package/dist/core/index.mjs +105 -3
  67. package/dist/index.d.mts +131 -70
  68. package/dist/index.d.ts +131 -70
  69. package/dist/index.js +97 -7
  70. package/dist/index.js.map +1 -1
  71. package/dist/index.mjs +118 -28
  72. package/dist/notification.interface-BdcwkuQE.d.mts +228 -0
  73. package/dist/notification.interface-BdcwkuQE.d.ts +228 -0
  74. package/dist/request-GBLBPYFM.js +8 -0
  75. package/dist/request-GBLBPYFM.js.map +1 -0
  76. package/dist/request-XABCMU25.mjs +8 -0
  77. package/dist/{AbstractService-wLid8dB0.d.ts → s3.interface-D7ttGatc.d.ts} +36 -26
  78. package/dist/{AbstractService-BsY6W3Ej.d.mts → s3.interface-DlaMDRTn.d.mts} +36 -26
  79. package/dist/scripts/generate-web-module/generator.d.ts.map +1 -1
  80. package/dist/scripts/generate-web-module/generator.js +8 -5
  81. package/dist/scripts/generate-web-module/generator.js.map +1 -1
  82. package/dist/scripts/generate-web-module/index.js +1 -1
  83. package/dist/scripts/generate-web-module/index.js.map +1 -1
  84. package/dist/scripts/generate-web-module/templates/components/editor.template.js +8 -1
  85. package/dist/scripts/generate-web-module/templates/components/editor.template.js.map +1 -1
  86. package/dist/scripts/generate-web-module/transformers/parent-detector.d.ts +4 -3
  87. package/dist/scripts/generate-web-module/transformers/parent-detector.d.ts.map +1 -1
  88. package/dist/scripts/generate-web-module/transformers/parent-detector.js +9 -3
  89. package/dist/scripts/generate-web-module/transformers/parent-detector.js.map +1 -1
  90. package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts +11 -0
  91. package/dist/scripts/generate-web-module/transformers/relationship-resolver.d.ts.map +1 -1
  92. package/dist/scripts/generate-web-module/transformers/relationship-resolver.js +36 -9
  93. package/dist/scripts/generate-web-module/transformers/relationship-resolver.js.map +1 -1
  94. package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts +2 -0
  95. package/dist/scripts/generate-web-module/types/json-schema.interface.d.ts.map +1 -1
  96. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts +1 -0
  97. package/dist/scripts/generate-web-module/types/template-data.interface.d.ts.map +1 -1
  98. package/dist/scripts/generate-web-module/utils/i18n-updater.d.ts +4 -3
  99. package/dist/scripts/generate-web-module/utils/i18n-updater.d.ts.map +1 -1
  100. package/dist/scripts/generate-web-module/utils/i18n-updater.js +9 -9
  101. package/dist/scripts/generate-web-module/utils/i18n-updater.js.map +1 -1
  102. package/dist/scripts/generate-web-module/validators/json-schema-validator.js +3 -3
  103. package/dist/scripts/generate-web-module/validators/json-schema-validator.js.map +1 -1
  104. package/dist/server/index.d.mts +299 -4
  105. package/dist/server/index.d.ts +299 -4
  106. package/dist/server/index.js +215 -5
  107. package/dist/server/index.js.map +1 -1
  108. package/dist/server/index.mjs +214 -4
  109. package/dist/server/index.mjs.map +1 -1
  110. package/dist/token-2UWQJY5T.js +8 -0
  111. package/dist/token-2UWQJY5T.js.map +1 -0
  112. package/dist/token-EOK3N45S.mjs +8 -0
  113. package/dist/{useSocket-DzMKRKCA.d.ts → useSocket-8vwK_R_c.d.ts} +1 -1
  114. package/dist/{useSocket-Cn7fB_B1.d.mts → useSocket-BWJUXuOl.d.mts} +1 -1
  115. package/package.json +12 -52
  116. package/scripts/generate-web-module/generator.ts +8 -5
  117. package/scripts/generate-web-module/index.ts +1 -1
  118. package/scripts/generate-web-module/templates/components/editor.template.ts +7 -2
  119. package/scripts/generate-web-module/transformers/parent-detector.ts +10 -3
  120. package/scripts/generate-web-module/transformers/relationship-resolver.ts +36 -9
  121. package/scripts/generate-web-module/types/json-schema.interface.ts +2 -0
  122. package/scripts/generate-web-module/types/template-data.interface.ts +1 -0
  123. package/scripts/generate-web-module/utils/i18n-updater.ts +9 -9
  124. package/scripts/generate-web-module/validators/json-schema-validator.ts +3 -3
  125. package/src/client/JsonApiClient.ts +248 -0
  126. package/src/client/config.ts +78 -0
  127. package/src/client/index.ts +6 -1
  128. package/src/components/containers/TabsContainer.tsx +1 -1
  129. package/src/components/editors/BlockNoteEditor.tsx +3 -1
  130. package/src/components/index.ts +4 -0
  131. package/src/components/navigations/Breadcrumb.tsx +1 -1
  132. package/src/components/navigations/Header.tsx +2 -2
  133. package/src/contexts/CommonContext.tsx +1 -1
  134. package/src/contexts/SocketContext.tsx +1 -1
  135. package/src/contexts/index.ts +3 -0
  136. package/src/core/abstracts/ClientAbstractService.ts +255 -0
  137. package/src/core/abstracts/ServerAbstractService.ts +180 -0
  138. package/src/core/abstracts/index.ts +2 -0
  139. package/src/core/index.ts +32 -3
  140. package/src/discord/config.ts +15 -0
  141. package/src/discord/index.ts +1 -0
  142. package/src/features/auth/components/details/LandingComponent.tsx +2 -2
  143. package/src/features/auth/components/forms/AcceptInvitation.tsx +1 -1
  144. package/src/features/auth/components/forms/ActivateAccount.tsx +1 -1
  145. package/src/features/auth/components/forms/Cookies.tsx +2 -1
  146. package/src/features/auth/components/forms/ForgotPassword.tsx +1 -1
  147. package/src/features/auth/components/forms/Login.tsx +1 -1
  148. package/src/features/auth/components/forms/Logout.tsx +1 -1
  149. package/src/features/auth/components/forms/RefreshUser.tsx +2 -1
  150. package/src/features/auth/components/forms/Register.tsx +1 -1
  151. package/src/features/auth/components/forms/ResetPassword.tsx +1 -1
  152. package/src/features/auth/data/auth.service.ts +1 -1
  153. package/src/features/auth/data/index.ts +0 -1
  154. package/src/features/auth/utils/AuthCookies.ts +1 -1
  155. package/src/features/company/components/forms/CompanyConfigurationEditor.tsx +4 -2
  156. package/src/features/company/components/forms/CompanyDeleter.tsx +2 -1
  157. package/src/features/company/components/forms/CompanyEditor.tsx +6 -3
  158. package/src/features/company/components/forms/CompanyLicense.tsx +4 -2
  159. package/src/features/company/components/lists/CompaniesList.tsx +2 -1
  160. package/src/features/company/data/index.ts +0 -1
  161. package/src/features/content/components/lists/ContentsListById.tsx +2 -1
  162. package/src/features/content/components/lists/RelevantContentsList.tsx +2 -1
  163. package/src/features/content/data/index.ts +0 -1
  164. package/src/features/feature/data/index.ts +0 -1
  165. package/src/features/notification/components/lists/NotificationsList.tsx +2 -1
  166. package/src/features/notification/contexts/NotificationContext.tsx +2 -1
  167. package/src/features/notification/data/index.ts +0 -1
  168. package/src/features/push/data/index.ts +0 -1
  169. package/src/features/role/components/forms/RemoveUserFromRole.tsx +4 -2
  170. package/src/features/role/components/forms/UserRoleAdd.tsx +2 -1
  171. package/src/features/role/components/lists/RolesList.tsx +2 -1
  172. package/src/features/role/components/lists/UserRolesList.tsx +2 -1
  173. package/src/features/role/data/index.ts +0 -1
  174. package/src/features/s3/data/index.ts +0 -1
  175. package/src/features/user/components/forms/RoleUserAdd.tsx +4 -2
  176. package/src/features/user/components/forms/UserDeleter.tsx +2 -1
  177. package/src/features/user/components/forms/UserEditor.tsx +6 -3
  178. package/src/features/user/components/forms/UserMultiSelect.tsx +2 -1
  179. package/src/features/user/components/forms/UserReactivator.tsx +2 -1
  180. package/src/features/user/components/forms/UserResentInvitationEmail.tsx +2 -1
  181. package/src/features/user/components/forms/UserSelector.tsx +2 -1
  182. package/src/features/user/components/lists/AdminUsersList.tsx +2 -1
  183. package/src/features/user/components/lists/CompanyUsersList.tsx +2 -1
  184. package/src/features/user/components/lists/RelevantUsersList.tsx +2 -1
  185. package/src/features/user/components/lists/RoleUsersList.tsx +2 -1
  186. package/src/features/user/components/lists/UsersListByContentIds.tsx +2 -1
  187. package/src/features/user/data/index.ts +0 -1
  188. package/src/features/user/hooks/useUserSearch.ts +2 -1
  189. package/src/features/user/index.ts +1 -0
  190. package/src/hooks/useDataListRetriever.ts +4 -4
  191. package/src/hooks/usePageTracker.ts +1 -1
  192. package/src/hooks/usePushNotifications.ts +3 -2
  193. package/src/hooks/useSocket.ts +1 -1
  194. package/src/index.ts +7 -2
  195. package/src/roles/config.ts +0 -15
  196. package/src/roles/index.ts +1 -9
  197. package/src/server/JsonApiServer.ts +249 -0
  198. package/src/server/cache.ts +1 -1
  199. package/src/server/index.ts +13 -0
  200. package/src/server/request.ts +32 -18
  201. package/src/server/token.ts +1 -1
  202. package/dist/ApiData-DPKNfY-9.d.mts +0 -10
  203. package/dist/ApiData-DPKNfY-9.d.ts +0 -10
  204. package/dist/ApiDataInterface-DPP8s46n.d.mts +0 -21
  205. package/dist/ApiDataInterface-DPP8s46n.d.ts +0 -21
  206. package/dist/BlockNoteEditor-QV6ESIQA.js.map +0 -1
  207. package/dist/BlockNoteEditor-U2IHUVUF.mjs.map +0 -1
  208. package/dist/JsonApiRequest-UJ7FGIVI.js +0 -25
  209. package/dist/atoms/index.d.mts +0 -12
  210. package/dist/atoms/index.d.ts +0 -12
  211. package/dist/atoms/index.js +0 -9
  212. package/dist/atoms/index.js.map +0 -1
  213. package/dist/atoms/index.mjs +0 -9
  214. package/dist/chunk-2K3Q24UF.js.map +0 -1
  215. package/dist/chunk-3FBCC4G3.js +0 -8
  216. package/dist/chunk-3FBCC4G3.js.map +0 -1
  217. package/dist/chunk-3UELCPIN.js +0 -46
  218. package/dist/chunk-3UELCPIN.js.map +0 -1
  219. package/dist/chunk-5IET37O4.js +0 -4210
  220. package/dist/chunk-5IET37O4.js.map +0 -1
  221. package/dist/chunk-AYHKQWHH.js +0 -68
  222. package/dist/chunk-AYHKQWHH.js.map +0 -1
  223. package/dist/chunk-DEYKTLA3.js +0 -1131
  224. package/dist/chunk-DEYKTLA3.js.map +0 -1
  225. package/dist/chunk-E2HRC2OG.js.map +0 -1
  226. package/dist/chunk-EFJEWLRL.js.map +0 -1
  227. package/dist/chunk-FMBQZAIP.mjs +0 -490
  228. package/dist/chunk-FMBQZAIP.mjs.map +0 -1
  229. package/dist/chunk-HR4H2FP7.mjs.map +0 -1
  230. package/dist/chunk-HTLEKZND.mjs.map +0 -1
  231. package/dist/chunk-JGFWIT2E.mjs +0 -1131
  232. package/dist/chunk-JGFWIT2E.mjs.map +0 -1
  233. package/dist/chunk-P2F54I7Q.mjs +0 -4210
  234. package/dist/chunk-P2F54I7Q.mjs.map +0 -1
  235. package/dist/chunk-PO5Q3H5I.js +0 -1375
  236. package/dist/chunk-PO5Q3H5I.js.map +0 -1
  237. package/dist/chunk-Q2N6SQYW.mjs +0 -8
  238. package/dist/chunk-Q2N6SQYW.mjs.map +0 -1
  239. package/dist/chunk-Q4FXESVT.js +0 -490
  240. package/dist/chunk-Q4FXESVT.js.map +0 -1
  241. package/dist/chunk-R2ONK22M.mjs +0 -7985
  242. package/dist/chunk-R2ONK22M.mjs.map +0 -1
  243. package/dist/chunk-SM63SZCP.mjs +0 -68
  244. package/dist/chunk-SM63SZCP.mjs.map +0 -1
  245. package/dist/chunk-SZZYEG3P.mjs +0 -46
  246. package/dist/chunk-SZZYEG3P.mjs.map +0 -1
  247. package/dist/chunk-YF5XQZDR.mjs.map +0 -1
  248. package/dist/config-BmnK65TD.d.mts +0 -35
  249. package/dist/config-BmnK65TD.d.ts +0 -35
  250. package/dist/config-DQeAo9Kf.d.mts +0 -49
  251. package/dist/config-DQeAo9Kf.d.ts +0 -49
  252. package/dist/content.fields-cHPdM8GJ.d.mts +0 -27
  253. package/dist/content.fields-cHPdM8GJ.d.ts +0 -27
  254. package/dist/d3.link.interface-ClC4Irqp.d.mts +0 -21
  255. package/dist/d3.link.interface-ClC4Irqp.d.ts +0 -21
  256. package/dist/features/index.d.mts +0 -476
  257. package/dist/features/index.d.ts +0 -476
  258. package/dist/features/index.js +0 -87
  259. package/dist/features/index.js.map +0 -1
  260. package/dist/features/index.mjs +0 -87
  261. package/dist/hooks/index.d.mts +0 -69
  262. package/dist/hooks/index.d.ts +0 -69
  263. package/dist/hooks/index.js +0 -56
  264. package/dist/hooks/index.js.map +0 -1
  265. package/dist/hooks/index.mjs +0 -56
  266. package/dist/hooks/index.mjs.map +0 -1
  267. package/dist/interfaces/index.d.mts +0 -4
  268. package/dist/interfaces/index.d.ts +0 -4
  269. package/dist/interfaces/index.js +0 -2
  270. package/dist/interfaces/index.js.map +0 -1
  271. package/dist/interfaces/index.mjs +0 -2
  272. package/dist/interfaces/index.mjs.map +0 -1
  273. package/dist/notification.interface-BBgMUdLR.d.mts +0 -14
  274. package/dist/notification.interface-gyvT-Z2F.d.ts +0 -14
  275. package/dist/permissions/index.d.mts +0 -41
  276. package/dist/permissions/index.d.ts +0 -41
  277. package/dist/permissions/index.js +0 -14
  278. package/dist/permissions/index.js.map +0 -1
  279. package/dist/permissions/index.mjs +0 -14
  280. package/dist/permissions/index.mjs.map +0 -1
  281. package/dist/request-7FE3LJLV.mjs +0 -9
  282. package/dist/request-7FE3LJLV.mjs.map +0 -1
  283. package/dist/request-QFS7NEIE.js +0 -9
  284. package/dist/request-QFS7NEIE.js.map +0 -1
  285. package/dist/roles/index.d.mts +0 -39
  286. package/dist/roles/index.d.ts +0 -39
  287. package/dist/roles/index.js +0 -18
  288. package/dist/roles/index.js.map +0 -1
  289. package/dist/roles/index.mjs +0 -18
  290. package/dist/roles/index.mjs.map +0 -1
  291. package/dist/shadcnui/index.d.mts +0 -698
  292. package/dist/shadcnui/index.d.ts +0 -698
  293. package/dist/shadcnui/index.js +0 -468
  294. package/dist/shadcnui/index.js.map +0 -1
  295. package/dist/shadcnui/index.mjs +0 -467
  296. package/dist/shadcnui/index.mjs.map +0 -1
  297. package/dist/token-IJSPOMW6.mjs +0 -9
  298. package/dist/token-IJSPOMW6.mjs.map +0 -1
  299. package/dist/token-UYE7CV6X.js +0 -9
  300. package/dist/token-UYE7CV6X.js.map +0 -1
  301. package/dist/types-B2QRyqyK.d.ts +0 -39
  302. package/dist/types-CgvNmxTd.d.mts +0 -39
  303. package/dist/types-t2PyXhDu.d.mts +0 -116
  304. package/dist/types-t2PyXhDu.d.ts +0 -116
  305. package/dist/user.interface-CAsTIbuQ.d.mts +0 -85
  306. package/dist/user.interface-CbWqMaaU.d.ts +0 -85
  307. package/dist/utils/index.d.mts +0 -224
  308. package/dist/utils/index.d.ts +0 -224
  309. package/dist/utils/index.js +0 -46
  310. package/dist/utils/index.js.map +0 -1
  311. package/dist/utils/index.mjs +0 -46
  312. package/dist/utils/index.mjs.map +0 -1
  313. /package/dist/{JsonApiRequest-6UR7DIAR.mjs.map → JsonApiRequest-VCCRO732.mjs.map} +0 -0
  314. /package/dist/{chunk-IKBA4AHN.mjs.map → chunk-F4Y3GZG4.mjs.map} +0 -0
  315. /package/dist/{chunk-HAG77QBV.mjs.map → chunk-K4W5QXL5.mjs.map} +0 -0
  316. /package/dist/{atoms/index.mjs.map → request-XABCMU25.mjs.map} +0 -0
  317. /package/dist/{features/index.mjs.map → token-EOK3N45S.mjs.map} +0 -0
@@ -0,0 +1,255 @@
1
+ "use client";
2
+
3
+ import { ApiRequestDataTypeInterface } from "../interfaces/ApiRequestDataTypeInterface";
4
+ import { ApiResponseInterface } from "../interfaces/ApiResponseInterface";
5
+ import {
6
+ ClientJsonApiGet,
7
+ ClientJsonApiPost,
8
+ ClientJsonApiPut,
9
+ ClientJsonApiPatch,
10
+ ClientJsonApiDelete,
11
+ } from "../../client/JsonApiClient";
12
+ // Duplicated to avoid importing from AbstractService which pulls in server code
13
+ // These are exported so client services can import them from here instead of core
14
+ export enum ClientHttpMethod {
15
+ GET = "GET",
16
+ POST = "POST",
17
+ PUT = "PUT",
18
+ PATCH = "PATCH",
19
+ DELETE = "DELETE",
20
+ }
21
+
22
+ export interface ClientNextRef {
23
+ next?: string;
24
+ }
25
+
26
+ export interface ClientPreviousRef {
27
+ previous?: string;
28
+ }
29
+
30
+ export interface ClientSelfRef {
31
+ self?: string;
32
+ }
33
+
34
+ let globalErrorHandler: ((status: number, message: string) => void) | null = null;
35
+
36
+ /**
37
+ * Set a global error handler for API errors (client-side only).
38
+ * This handler will be called instead of throwing errors.
39
+ */
40
+ export function setClientGlobalErrorHandler(handler: (status: number, message: string) => void) {
41
+ globalErrorHandler = handler;
42
+ }
43
+
44
+ /**
45
+ * Get the current global error handler.
46
+ */
47
+ export function getClientGlobalErrorHandler(): ((status: number, message: string) => void) | null {
48
+ return globalErrorHandler;
49
+ }
50
+
51
+ /**
52
+ * Client-side abstract base class for services that interact with the JSON:API.
53
+ * Use this for client components.
54
+ */
55
+ export abstract class ClientAbstractService {
56
+ /**
57
+ * Extract locale from client-side URL pathname
58
+ * URL structure: /{locale}/route-path (e.g., /it/accounts)
59
+ * Fallback chain: URL locale → navigator.language → "en"
60
+ */
61
+ private static getClientLocale(): string {
62
+ if (typeof window === "undefined") {
63
+ return "en"; // Should not happen in client service
64
+ }
65
+
66
+ // Extract locale from URL pathname (first segment after leading slash)
67
+ const pathSegments = window.location.pathname.split("/").filter(Boolean);
68
+ const urlLocale = pathSegments[0];
69
+
70
+ // Validate against supported locales (currently only "en")
71
+ const supportedLocales = ["en"];
72
+ if (urlLocale && supportedLocales.includes(urlLocale)) {
73
+ return urlLocale;
74
+ }
75
+
76
+ // Fallback to navigator language
77
+ const navigatorLocale = navigator.language.split("-")[0];
78
+ if (navigatorLocale && supportedLocales.includes(navigatorLocale)) {
79
+ return navigatorLocale;
80
+ }
81
+
82
+ // Final fallback
83
+ return "en";
84
+ }
85
+
86
+ /**
87
+ * Fetch the next page of results.
88
+ */
89
+ static async next<T>(params: {
90
+ type: ApiRequestDataTypeInterface;
91
+ endpoint: string;
92
+ next?: ClientNextRef;
93
+ previous?: ClientPreviousRef;
94
+ self?: ClientSelfRef;
95
+ }): Promise<T> {
96
+ return await this.callApi<T>({
97
+ method: ClientHttpMethod.GET,
98
+ type: params.type,
99
+ endpoint: params.endpoint,
100
+ next: params.next,
101
+ previous: params.previous,
102
+ self: params.self,
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Fetch the previous page of results.
108
+ */
109
+ static async previous<T>(params: {
110
+ type: ApiRequestDataTypeInterface;
111
+ endpoint: string;
112
+ next?: ClientNextRef;
113
+ previous?: ClientPreviousRef;
114
+ self?: ClientSelfRef;
115
+ }): Promise<T> {
116
+ return await this.callApi<T>({
117
+ method: ClientHttpMethod.GET,
118
+ type: params.type,
119
+ endpoint: params.endpoint,
120
+ next: params.next,
121
+ previous: params.previous,
122
+ self: params.self,
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Make a client-side API call.
128
+ */
129
+ protected static async callApi<T>(params: {
130
+ type: ApiRequestDataTypeInterface;
131
+ method: ClientHttpMethod;
132
+ endpoint: string;
133
+ companyId?: string;
134
+ input?: any;
135
+ overridesJsonApiCreation?: boolean;
136
+ next?: ClientNextRef;
137
+ previous?: ClientPreviousRef;
138
+ self?: ClientSelfRef;
139
+ responseType?: ApiRequestDataTypeInterface;
140
+ files?: { [key: string]: File | Blob } | File | Blob;
141
+ }): Promise<T> {
142
+ let apiResponse: ApiResponseInterface;
143
+
144
+ // Client-side: extract locale from URL pathname
145
+ const language = this.getClientLocale();
146
+
147
+ switch (params.method) {
148
+ case ClientHttpMethod.GET:
149
+ apiResponse = await ClientJsonApiGet({
150
+ classKey: params.type,
151
+ endpoint: params.endpoint,
152
+ companyId: params.companyId,
153
+ language: language,
154
+ });
155
+ break;
156
+ case ClientHttpMethod.POST:
157
+ apiResponse = await ClientJsonApiPost({
158
+ classKey: params.type,
159
+ endpoint: params.endpoint,
160
+ companyId: params.companyId,
161
+ body: params.input,
162
+ overridesJsonApiCreation: params.overridesJsonApiCreation,
163
+ language: language,
164
+ responseType: params.responseType,
165
+ files: params.files,
166
+ });
167
+ break;
168
+ case ClientHttpMethod.PUT:
169
+ apiResponse = await ClientJsonApiPut({
170
+ classKey: params.type,
171
+ endpoint: params.endpoint,
172
+ companyId: params.companyId,
173
+ body: params.input,
174
+ language: language,
175
+ responseType: params.responseType,
176
+ files: params.files,
177
+ });
178
+ break;
179
+ case ClientHttpMethod.PATCH:
180
+ apiResponse = await ClientJsonApiPatch({
181
+ classKey: params.type,
182
+ endpoint: params.endpoint,
183
+ companyId: params.companyId,
184
+ body: params.input,
185
+ overridesJsonApiCreation: params.overridesJsonApiCreation,
186
+ language: language,
187
+ responseType: params.responseType,
188
+ files: params.files,
189
+ });
190
+ break;
191
+ case ClientHttpMethod.DELETE:
192
+ apiResponse = await ClientJsonApiDelete({
193
+ classKey: params.type,
194
+ endpoint: params.endpoint,
195
+ companyId: params.companyId,
196
+ language: language,
197
+ responseType: params.responseType,
198
+ });
199
+ break;
200
+ default:
201
+ throw new Error("Method not found");
202
+ }
203
+
204
+ if (!apiResponse.ok) {
205
+ if (globalErrorHandler) {
206
+ globalErrorHandler(apiResponse.response, apiResponse.error);
207
+ return undefined as any;
208
+ } else {
209
+ const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;
210
+ error.status = apiResponse.response;
211
+ error.digest = `HTTP_${apiResponse.response}`;
212
+ throw error;
213
+ }
214
+ }
215
+
216
+ if (apiResponse.next && params.next) params.next.next = apiResponse.next;
217
+ if (apiResponse.prev && params.previous) params.previous.previous = apiResponse.prev;
218
+ if (apiResponse.self && params.self) params.self.self = apiResponse.self;
219
+
220
+ return apiResponse.data as T;
221
+ }
222
+
223
+ /**
224
+ * Get raw JSON:API response data without deserialization.
225
+ */
226
+ protected static async getRawData(params: {
227
+ type: ApiRequestDataTypeInterface;
228
+ method: ClientHttpMethod;
229
+ endpoint: string;
230
+ companyId?: string;
231
+ }): Promise<any> {
232
+ const language = this.getClientLocale();
233
+
234
+ const apiResponse: ApiResponseInterface = await ClientJsonApiGet({
235
+ classKey: params.type,
236
+ endpoint: params.endpoint,
237
+ companyId: params.companyId,
238
+ language: language,
239
+ });
240
+
241
+ if (!apiResponse.ok) {
242
+ if (globalErrorHandler) {
243
+ globalErrorHandler(apiResponse.response, apiResponse.error);
244
+ return undefined as any;
245
+ } else {
246
+ const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;
247
+ error.status = apiResponse.response;
248
+ error.digest = `HTTP_${apiResponse.response}`;
249
+ throw error;
250
+ }
251
+ }
252
+
253
+ return apiResponse.raw;
254
+ }
255
+ }
@@ -0,0 +1,180 @@
1
+ // Server-only abstract service (NOT a server action - cannot be called from client components)
2
+
3
+ import { ApiRequestDataTypeInterface } from "../interfaces/ApiRequestDataTypeInterface";
4
+ import { ApiResponseInterface } from "../interfaces/ApiResponseInterface";
5
+ import {
6
+ ServerJsonApiGet,
7
+ ServerJsonApiPost,
8
+ ServerJsonApiPut,
9
+ ServerJsonApiPatch,
10
+ ServerJsonApiDelete,
11
+ } from "../../server/JsonApiServer";
12
+ import { HttpMethod, NextRef, PreviousRef, SelfRef } from "./AbstractService";
13
+
14
+ /**
15
+ * Server-side abstract base class for services that interact with the JSON:API.
16
+ * Use this for server components and server actions.
17
+ */
18
+ export abstract class ServerAbstractService {
19
+ /**
20
+ * Fetch the next page of results.
21
+ */
22
+ static async next<T>(params: {
23
+ type: ApiRequestDataTypeInterface;
24
+ endpoint: string;
25
+ next?: NextRef;
26
+ previous?: PreviousRef;
27
+ self?: SelfRef;
28
+ }): Promise<T> {
29
+ return await this.callApi<T>({
30
+ method: HttpMethod.GET,
31
+ type: params.type,
32
+ endpoint: params.endpoint,
33
+ next: params.next,
34
+ previous: params.previous,
35
+ self: params.self,
36
+ });
37
+ }
38
+
39
+ /**
40
+ * Fetch the previous page of results.
41
+ */
42
+ static async previous<T>(params: {
43
+ type: ApiRequestDataTypeInterface;
44
+ endpoint: string;
45
+ next?: NextRef;
46
+ previous?: PreviousRef;
47
+ self?: SelfRef;
48
+ }): Promise<T> {
49
+ return await this.callApi<T>({
50
+ method: HttpMethod.GET,
51
+ type: params.type,
52
+ endpoint: params.endpoint,
53
+ next: params.next,
54
+ previous: params.previous,
55
+ self: params.self,
56
+ });
57
+ }
58
+
59
+ /**
60
+ * Make a server-side API call.
61
+ */
62
+ protected static async callApi<T>(params: {
63
+ type: ApiRequestDataTypeInterface;
64
+ method: HttpMethod;
65
+ endpoint: string;
66
+ companyId?: string;
67
+ input?: any;
68
+ overridesJsonApiCreation?: boolean;
69
+ next?: NextRef;
70
+ previous?: PreviousRef;
71
+ self?: SelfRef;
72
+ responseType?: ApiRequestDataTypeInterface;
73
+ files?: { [key: string]: File | Blob } | File | Blob;
74
+ }): Promise<T> {
75
+ let apiResponse: ApiResponseInterface;
76
+
77
+ // Get language from next-intl server
78
+ const { getLocale } = await import("next-intl/server");
79
+ const language = (await getLocale()) ?? "en";
80
+
81
+ switch (params.method) {
82
+ case HttpMethod.GET:
83
+ apiResponse = await ServerJsonApiGet({
84
+ classKey: params.type,
85
+ endpoint: params.endpoint,
86
+ companyId: params.companyId,
87
+ language: language,
88
+ });
89
+ break;
90
+ case HttpMethod.POST:
91
+ apiResponse = await ServerJsonApiPost({
92
+ classKey: params.type,
93
+ endpoint: params.endpoint,
94
+ companyId: params.companyId,
95
+ body: params.input,
96
+ overridesJsonApiCreation: params.overridesJsonApiCreation,
97
+ language: language,
98
+ responseType: params.responseType,
99
+ files: params.files,
100
+ });
101
+ break;
102
+ case HttpMethod.PUT:
103
+ apiResponse = await ServerJsonApiPut({
104
+ classKey: params.type,
105
+ endpoint: params.endpoint,
106
+ companyId: params.companyId,
107
+ body: params.input,
108
+ language: language,
109
+ responseType: params.responseType,
110
+ files: params.files,
111
+ });
112
+ break;
113
+ case HttpMethod.PATCH:
114
+ apiResponse = await ServerJsonApiPatch({
115
+ classKey: params.type,
116
+ endpoint: params.endpoint,
117
+ companyId: params.companyId,
118
+ body: params.input,
119
+ overridesJsonApiCreation: params.overridesJsonApiCreation,
120
+ language: language,
121
+ responseType: params.responseType,
122
+ files: params.files,
123
+ });
124
+ break;
125
+ case HttpMethod.DELETE:
126
+ apiResponse = await ServerJsonApiDelete({
127
+ classKey: params.type,
128
+ endpoint: params.endpoint,
129
+ companyId: params.companyId,
130
+ language: language,
131
+ responseType: params.responseType,
132
+ });
133
+ break;
134
+ default:
135
+ throw new Error("Method not found");
136
+ }
137
+
138
+ if (!apiResponse.ok) {
139
+ const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;
140
+ error.status = apiResponse.response;
141
+ error.digest = `HTTP_${apiResponse.response}`;
142
+ throw error;
143
+ }
144
+
145
+ if (apiResponse.next && params.next) params.next.next = apiResponse.next;
146
+ if (apiResponse.prev && params.previous) params.previous.previous = apiResponse.prev;
147
+ if (apiResponse.self && params.self) params.self.self = apiResponse.self;
148
+
149
+ return apiResponse.data as T;
150
+ }
151
+
152
+ /**
153
+ * Get raw JSON:API response data without deserialization.
154
+ */
155
+ protected static async getRawData(params: {
156
+ type: ApiRequestDataTypeInterface;
157
+ method: HttpMethod;
158
+ endpoint: string;
159
+ companyId?: string;
160
+ }): Promise<any> {
161
+ const { getLocale } = await import("next-intl/server");
162
+ const language = (await getLocale()) ?? "en";
163
+
164
+ const apiResponse: ApiResponseInterface = await ServerJsonApiGet({
165
+ classKey: params.type,
166
+ endpoint: params.endpoint,
167
+ companyId: params.companyId,
168
+ language: language,
169
+ });
170
+
171
+ if (!apiResponse.ok) {
172
+ const error = new Error(`${apiResponse.response}:${apiResponse.error}`) as any;
173
+ error.status = apiResponse.response;
174
+ error.digest = `HTTP_${apiResponse.response}`;
175
+ throw error;
176
+ }
177
+
178
+ return apiResponse.raw;
179
+ }
180
+ }
@@ -1,2 +1,4 @@
1
1
  export * from "./AbstractApiData";
2
+ // AbstractService is a base class needed by all services
2
3
  export * from "./AbstractService";
4
+ export * from "./ClientAbstractService";
package/src/core/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- // Interfaces
1
+ // Core interfaces
2
2
  export * from "./interfaces";
3
3
 
4
- // Abstracts (will be added)
4
+ // Abstracts
5
5
  export * from "./abstracts";
6
6
 
7
7
  // Factories
@@ -16,5 +16,34 @@ export * from "./endpoint";
16
16
  // Field selectors
17
17
  export * from "./fields";
18
18
 
19
- // Utilities
19
+ // Core utilities
20
20
  export * from "./utils";
21
+
22
+ // Top-level interfaces (breadcrumb, d3)
23
+ export * from "../interfaces";
24
+
25
+ // Top-level utilities (cn, date-formatter, schemas, etc.)
26
+ export * from "../utils";
27
+
28
+ // Feature data classes, interfaces, and modules
29
+ export * from "../features/auth/data";
30
+ export * from "../features/auth/enums";
31
+ export * from "../features/auth/auth.module";
32
+ export * from "../features/company/data";
33
+ export * from "../features/company/company.module";
34
+ export * from "../features/content/data";
35
+ export * from "../features/content/content.module";
36
+ export * from "../features/feature/data";
37
+ export * from "../features/feature/feature.module";
38
+ export * from "../features/module";
39
+ export * from "../features/notification/data";
40
+ export * from "../features/notification/notification.module";
41
+ export * from "../features/push/data";
42
+ export * from "../features/push/push.module";
43
+ export * from "../features/role/data";
44
+ export * from "../features/role/role.module";
45
+ export * from "../features/s3";
46
+ export * from "../features/search";
47
+ export * from "../features/user/data";
48
+ export * from "../features/user/user.module";
49
+ export * from "../features/user/author.module";
@@ -0,0 +1,15 @@
1
+ let _useDiscord: boolean = false;
2
+ let _useInternalAuth: boolean = true;
3
+
4
+ export function configureDiscord(params: { useDiscord: boolean; useInternalAuth: boolean }): void {
5
+ _useDiscord = params.useDiscord;
6
+ _useInternalAuth = params.useInternalAuth;
7
+ }
8
+
9
+ export function isDiscordConfigured(): boolean {
10
+ return _useDiscord;
11
+ }
12
+
13
+ export function isInternalAuthConfigured(): boolean {
14
+ return _useInternalAuth;
15
+ }
@@ -0,0 +1 @@
1
+ export { configureDiscord, isDiscordConfigured, isInternalAuthConfigured } from "./config";
@@ -2,9 +2,9 @@
2
2
 
3
3
  import { useTranslations } from "next-intl";
4
4
  import Image from "next/image";
5
- import { isDiscordConfigured, isInternalAuthConfigured } from "../../../../roles";
5
+ import { isDiscordConfigured, isInternalAuthConfigured } from "../../../../discord";
6
6
  import { Button, CardDescription, CardFooter, CardHeader, CardTitle, Link } from "../../../../shadcnui";
7
- import { getApiUrl } from "../../../../unified";
7
+ import { getApiUrl } from "../../../../client/config";
8
8
  import { useAuthContext } from "../../contexts";
9
9
  import { AuthComponent } from "../../enums";
10
10
 
@@ -10,7 +10,7 @@ import { z } from "zod";
10
10
  import { errorToast, FormPassword } from "../../../../components";
11
11
  import { Button, CardContent, CardDescription, CardHeader, CardTitle, Form } from "../../../../shadcnui";
12
12
  import { useAuthContext } from "../../contexts";
13
- import { AuthService } from "../../data";
13
+ import { AuthService } from "../../data/auth.service";
14
14
  import { AuthComponent } from "../../enums";
15
15
 
16
16
  export function AcceptInvitation() {
@@ -7,7 +7,7 @@ import { toast } from "sonner";
7
7
  import { errorToast } from "../../../../components";
8
8
  import { CardContent, CardDescription, CardHeader, CardTitle } from "../../../../shadcnui";
9
9
  import { useAuthContext } from "../../contexts";
10
- import { AuthService } from "../../data";
10
+ import { AuthService } from "../../data/auth.service";
11
11
  import { AuthComponent } from "../../enums";
12
12
 
13
13
  export function ActivateAccount() {
@@ -5,7 +5,8 @@ import { JsonApiHydratedDataInterface, Modules, rehydrate } from "../../../../co
5
5
  import { useI18nRouter } from "../../../../i18n";
6
6
  import { UserInterface } from "../../../user";
7
7
  import { useCurrentUserContext } from "../../../user/contexts";
8
- import { AuthInterface, AuthService } from "../../data";
8
+ import { AuthInterface } from "../../data";
9
+ import { AuthService } from "../../data/auth.service";
9
10
 
10
11
  export function Cookies({ dehydratedAuth, page }: { dehydratedAuth: JsonApiHydratedDataInterface; page?: string }) {
11
12
  const { setUser } = useCurrentUserContext<UserInterface>();
@@ -18,7 +18,7 @@ import {
18
18
  Link,
19
19
  } from "../../../../shadcnui";
20
20
  import { useAuthContext } from "../../contexts";
21
- import { AuthService } from "../../data";
21
+ import { AuthService } from "../../data/auth.service";
22
22
  import { AuthComponent } from "../../enums";
23
23
 
24
24
  export function ForgotPassword() {
@@ -20,7 +20,7 @@ import {
20
20
  import { UserInterface } from "../../../user";
21
21
  import { useCurrentUserContext } from "../../../user/contexts";
22
22
  import { useAuthContext } from "../../contexts";
23
- import { AuthService } from "../../data";
23
+ import { AuthService } from "../../data/auth.service";
24
24
  import { AuthComponent } from "../../enums";
25
25
 
26
26
  export function Login() {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useEffect } from "react";
4
4
  import { usePageUrlGenerator } from "../../../../hooks";
5
- import { AuthService } from "../../data";
5
+ import { AuthService } from "../../data/auth.service";
6
6
 
7
7
  export function Logout() {
8
8
  const generateUrl = usePageUrlGenerator();
@@ -2,7 +2,8 @@
2
2
 
3
3
  import { deleteCookie, getCookie } from "cookies-next";
4
4
  import { useEffect } from "react";
5
- import { UserInterface, UserService } from "../../../user";
5
+ import { UserInterface } from "../../../user";
6
+ import { UserService } from "../../../user/data/user.service";
6
7
  import { useCurrentUserContext } from "../../../user/contexts";
7
8
  import { getTokenHandler } from "../../config";
8
9
 
@@ -19,7 +19,7 @@ import {
19
19
  Link,
20
20
  } from "../../../../shadcnui";
21
21
  import { useAuthContext } from "../../contexts";
22
- import { AuthService } from "../../data";
22
+ import { AuthService } from "../../data/auth.service";
23
23
  import { AuthComponent } from "../../enums";
24
24
 
25
25
  export default function Register() {
@@ -10,7 +10,7 @@ import { z } from "zod";
10
10
  import { errorToast, FormPassword } from "../../../../components";
11
11
  import { Button, CardContent, CardDescription, CardHeader, CardTitle, Form } from "../../../../shadcnui";
12
12
  import { useAuthContext } from "../../contexts";
13
- import { AuthService } from "../../data";
13
+ import { AuthService } from "../../data/auth.service";
14
14
  import { AuthComponent } from "../../enums";
15
15
 
16
16
  export function ResetPassword() {
@@ -1,5 +1,5 @@
1
1
  import { AuthInput, AuthInterface } from ".";
2
- import { JsonApiDelete, JsonApiGet, JsonApiPost } from "../../../";
2
+ import { JsonApiDelete, JsonApiGet, JsonApiPost } from "../../../unified";
3
3
  import {
4
4
  AbstractService,
5
5
  ApiResponseInterface,
@@ -1,3 +1,2 @@
1
1
  export * from "./auth";
2
2
  export * from "./auth.interface";
3
- export * from "./auth.service";
@@ -1,4 +1,4 @@
1
- "use server";
1
+ // Server-only cookie utilities (consumers should provide their own server actions via configureAuth)
2
2
 
3
3
  import { cookies } from "next/headers";
4
4
  import zlib from "zlib";
@@ -23,9 +23,11 @@ import {
23
23
  TabsList,
24
24
  TabsTrigger,
25
25
  } from "../../../../shadcnui";
26
- import { UserInterface, UserService } from "../../../user";
26
+ import { UserInterface } from "../../../user";
27
+ import { UserService } from "../../../user/data/user.service";
27
28
  import { useCurrentUserContext } from "../../../user/contexts";
28
- import { CompanyInput, CompanyInterface, CompanyService } from "../../data";
29
+ import { CompanyInput, CompanyInterface } from "../../data";
30
+ import { CompanyService } from "../../data/company.service";
29
31
  import { CompanyConfigurationSecurityForm } from "./CompanyConfigurationSecurityForm";
30
32
 
31
33
  type CompanyConfigurationEditorProps = {
@@ -21,7 +21,8 @@ import {
21
21
  } from "../../../../shadcnui";
22
22
  import { UserInterface } from "../../../user";
23
23
  import { useCurrentUserContext } from "../../../user/contexts";
24
- import { CompanyInterface, CompanyService } from "../../data";
24
+ import { CompanyInterface } from "../../data";
25
+ import { CompanyService } from "../../data/company.service";
25
26
 
26
27
  type CompanyDeleterProps = {
27
28
  company: CompanyInterface;
@@ -25,11 +25,14 @@ import { usePageUrlGenerator } from "../../../../hooks";
25
25
  import { useI18nRouter } from "../../../../i18n";
26
26
  import { getRoleId } from "../../../../roles";
27
27
  import { Dialog, DialogContent, Form, ScrollArea } from "../../../../shadcnui";
28
- import { FeatureInterface, FeatureService } from "../../../feature";
29
- import { S3Interface, S3Service } from "../../../s3";
28
+ import { FeatureInterface } from "../../../feature";
29
+ import { S3Interface } from "../../../s3";
30
+ import { FeatureService } from "../../../feature/data/feature.service";
31
+ import { S3Service } from "../../../s3/data/s3.service";
30
32
  import { UserInterface } from "../../../user";
31
33
  import { useCurrentUserContext } from "../../../user/contexts";
32
- import { CompanyInput, CompanyInterface, CompanyService } from "../../data";
34
+ import { CompanyInput, CompanyInterface } from "../../data";
35
+ import { CompanyService } from "../../data/company.service";
33
36
 
34
37
  type CompanyEditorProps = {
35
38
  company?: CompanyInterface;