@carlonicora/nextjs-jsonapi 6.12.1 → 6.13.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 (255) hide show
  1. package/dist/{ApiData-DPKNfY-9.d.mts → ApiData-Be8yxCOX.d.mts} +2 -0
  2. package/dist/{ApiData-DPKNfY-9.d.ts → ApiData-Be8yxCOX.d.ts} +2 -0
  3. package/dist/{BlockNoteEditor-N2NBYCPC.mjs → BlockNoteEditor-22Q4DJBU.mjs} +20 -8
  4. package/dist/BlockNoteEditor-22Q4DJBU.mjs.map +1 -0
  5. package/dist/{BlockNoteEditor-CBYKEXAQ.js → BlockNoteEditor-2VLPSEKS.js} +34 -22
  6. package/dist/BlockNoteEditor-2VLPSEKS.js.map +1 -0
  7. package/dist/{BlockNoteViewer-WGCDB7IJ.js → BlockNoteViewer-2XYASA5Y.js} +8 -5
  8. package/dist/BlockNoteViewer-2XYASA5Y.js.map +1 -0
  9. package/dist/{BlockNoteViewer-MTGS6YJV.mjs → BlockNoteViewer-NBW2H6LC.mjs} +7 -4
  10. package/dist/{BlockNoteViewer-MTGS6YJV.mjs.map → BlockNoteViewer-NBW2H6LC.mjs.map} +1 -1
  11. package/dist/{JsonApiRequest-A66XK5WT.mjs → JsonApiRequest-F6TMJ42G.mjs} +2 -2
  12. package/dist/JsonApiRequest-WISJZSDE.js +26 -0
  13. package/dist/{JsonApiRequest-FZGPLNUF.js.map → JsonApiRequest-WISJZSDE.js.map} +1 -1
  14. package/dist/billing/index.js +499 -494
  15. package/dist/billing/index.js.map +1 -1
  16. package/dist/billing/index.mjs +13 -8
  17. package/dist/billing/index.mjs.map +1 -1
  18. package/dist/chunk-27LQDGNP.mjs +317 -0
  19. package/dist/chunk-27LQDGNP.mjs.map +1 -0
  20. package/dist/{chunk-6NZKWIOR.js → chunk-2H342HNN.js} +956 -929
  21. package/dist/chunk-2H342HNN.js.map +1 -0
  22. package/dist/{chunk-KSYQEKJX.js → chunk-2SV4SS6N.js} +14 -14
  23. package/dist/{chunk-KSYQEKJX.js.map → chunk-2SV4SS6N.js.map} +1 -1
  24. package/dist/{chunk-4FNGWALA.mjs → chunk-47BBY5KA.mjs} +6 -4
  25. package/dist/{chunk-4FNGWALA.mjs.map → chunk-47BBY5KA.mjs.map} +1 -1
  26. package/dist/chunk-6JUCIWDC.mjs +570 -0
  27. package/dist/chunk-6JUCIWDC.mjs.map +1 -0
  28. package/dist/chunk-7DBJTNSU.mjs +1049 -0
  29. package/dist/chunk-7DBJTNSU.mjs.map +1 -0
  30. package/dist/chunk-7JZHPMGW.mjs +704 -0
  31. package/dist/chunk-7JZHPMGW.mjs.map +1 -0
  32. package/dist/{chunk-L6PYFQTO.js → chunk-7ZHTPFFT.js} +16 -14
  33. package/dist/chunk-7ZHTPFFT.js.map +1 -0
  34. package/dist/chunk-B6JGKDP2.js +214 -0
  35. package/dist/chunk-B6JGKDP2.js.map +1 -0
  36. package/dist/{chunk-3YW35YHQ.mjs → chunk-BH6JWIKI.mjs} +5 -5
  37. package/dist/chunk-BZ5J2FIV.js +570 -0
  38. package/dist/chunk-BZ5J2FIV.js.map +1 -0
  39. package/dist/{chunk-V5MI7RNB.mjs → chunk-DGWOVYEC.mjs} +2 -2
  40. package/dist/chunk-DOCIFE6A.mjs +212 -0
  41. package/dist/chunk-DOCIFE6A.mjs.map +1 -0
  42. package/dist/chunk-GB6DBFYY.js +25 -0
  43. package/dist/chunk-GB6DBFYY.js.map +1 -0
  44. package/dist/{chunk-6XJOQFCP.mjs → chunk-H4NLDX5G.mjs} +59 -32
  45. package/dist/chunk-H4NLDX5G.mjs.map +1 -0
  46. package/dist/{chunk-EWCY6QJA.mjs → chunk-JJMMT24D.mjs} +37 -3
  47. package/dist/chunk-JJMMT24D.mjs.map +1 -0
  48. package/dist/{chunk-JTPRJNT2.js → chunk-KMW7UNL2.js} +38 -3
  49. package/dist/chunk-KMW7UNL2.js.map +1 -0
  50. package/dist/chunk-MHB36MYE.js +317 -0
  51. package/dist/chunk-MHB36MYE.js.map +1 -0
  52. package/dist/{chunk-FF4EIQ6H.js → chunk-MOGEGWXW.js} +1039 -1680
  53. package/dist/chunk-MOGEGWXW.js.map +1 -0
  54. package/dist/{chunk-AA52ORW2.mjs → chunk-P445QGOC.mjs} +61 -702
  55. package/dist/chunk-P445QGOC.mjs.map +1 -0
  56. package/dist/chunk-PV4Z5W6V.js +212 -0
  57. package/dist/chunk-PV4Z5W6V.js.map +1 -0
  58. package/dist/chunk-PXDUJ47N.js +1049 -0
  59. package/dist/chunk-PXDUJ47N.js.map +1 -0
  60. package/dist/{chunk-GHE4VT2R.js → chunk-QKNGZDSQ.js} +2 -2
  61. package/dist/{chunk-GHE4VT2R.js.map → chunk-QKNGZDSQ.js.map} +1 -1
  62. package/dist/chunk-W62MHDWM.js +704 -0
  63. package/dist/chunk-W62MHDWM.js.map +1 -0
  64. package/dist/chunk-XXP3TQHF.mjs +25 -0
  65. package/dist/chunk-XXP3TQHF.mjs.map +1 -0
  66. package/dist/chunk-YRKIFYOE.mjs +214 -0
  67. package/dist/chunk-YRKIFYOE.mjs.map +1 -0
  68. package/dist/{chunk-O3PDL2CV.js → chunk-Z4POQWFG.js} +40 -6
  69. package/dist/chunk-Z4POQWFG.js.map +1 -0
  70. package/dist/{chunk-PI56A4DG.mjs → chunk-ZLTOUZN2.mjs} +37 -2
  71. package/dist/chunk-ZLTOUZN2.mjs.map +1 -0
  72. package/dist/client/index.d.mts +2 -2
  73. package/dist/client/index.d.ts +2 -2
  74. package/dist/client/index.js +14 -9
  75. package/dist/client/index.js.map +1 -1
  76. package/dist/client/index.mjs +24 -19
  77. package/dist/components/index.d.mts +7 -1
  78. package/dist/components/index.d.ts +7 -1
  79. package/dist/components/index.js +11 -7
  80. package/dist/components/index.js.map +1 -1
  81. package/dist/components/index.mjs +10 -6
  82. package/dist/contexts/index.d.mts +1 -1
  83. package/dist/contexts/index.d.ts +1 -1
  84. package/dist/contexts/index.js +11 -7
  85. package/dist/contexts/index.js.map +1 -1
  86. package/dist/contexts/index.mjs +10 -6
  87. package/dist/core/index.d.mts +128 -2
  88. package/dist/core/index.d.ts +128 -2
  89. package/dist/core/index.js +17 -4
  90. package/dist/core/index.js.map +1 -1
  91. package/dist/core/index.mjs +22 -9
  92. package/dist/email-automations/index.js +101 -96
  93. package/dist/email-automations/index.js.map +1 -1
  94. package/dist/email-automations/index.mjs +13 -8
  95. package/dist/email-automations/index.mjs.map +1 -1
  96. package/dist/features/analytics/index.js +128 -123
  97. package/dist/features/analytics/index.js.map +1 -1
  98. package/dist/features/analytics/index.mjs +13 -8
  99. package/dist/features/analytics/index.mjs.map +1 -1
  100. package/dist/features/analytics/server.js +11 -8
  101. package/dist/features/analytics/server.js.map +1 -1
  102. package/dist/features/analytics/server.mjs +9 -6
  103. package/dist/features/analytics/server.mjs.map +1 -1
  104. package/dist/features/blog/index.js +158 -153
  105. package/dist/features/blog/index.js.map +1 -1
  106. package/dist/features/blog/index.mjs +14 -9
  107. package/dist/features/blog/index.mjs.map +1 -1
  108. package/dist/features/blog/server.js +30 -26
  109. package/dist/features/blog/server.js.map +1 -1
  110. package/dist/features/blog/server.mjs +10 -6
  111. package/dist/features/blog/server.mjs.map +1 -1
  112. package/dist/features/help/index.js +44 -40
  113. package/dist/features/help/index.js.map +1 -1
  114. package/dist/features/help/index.mjs +10 -6
  115. package/dist/features/help/index.mjs.map +1 -1
  116. package/dist/features/tokenusage/index.js +134 -129
  117. package/dist/features/tokenusage/index.js.map +1 -1
  118. package/dist/features/tokenusage/index.mjs +13 -8
  119. package/dist/features/tokenusage/index.mjs.map +1 -1
  120. package/dist/index.d.mts +2 -2
  121. package/dist/index.d.ts +2 -2
  122. package/dist/index.js +18 -5
  123. package/dist/index.js.map +1 -1
  124. package/dist/index.mjs +24 -11
  125. package/dist/lifecycle-4GUOTB46.js +23 -0
  126. package/dist/lifecycle-4GUOTB46.js.map +1 -0
  127. package/dist/lifecycle-LKGPRBS7.mjs +23 -0
  128. package/dist/local-transport-7H3SPZSA.js +15 -0
  129. package/dist/local-transport-7H3SPZSA.js.map +1 -0
  130. package/dist/local-transport-QYFKA6AN.mjs +15 -0
  131. package/dist/local-transport-QYFKA6AN.mjs.map +1 -0
  132. package/dist/offline/index.d.mts +607 -0
  133. package/dist/offline/index.d.ts +607 -0
  134. package/dist/offline/index.js +1052 -0
  135. package/dist/offline/index.js.map +1 -0
  136. package/dist/offline/index.mjs +1052 -0
  137. package/dist/offline/index.mjs.map +1 -0
  138. package/dist/offline/sqlite/device-worker.mjs +62 -0
  139. package/dist/offline/sqlite/index.mjs +17392 -0
  140. package/dist/offline/sqlite/sqlite3-opfs-async-proxy.js +881 -0
  141. package/dist/offline/sqlite/sqlite3.wasm +0 -0
  142. package/dist/request-KTBV6HHH.js +10 -0
  143. package/dist/request-KTBV6HHH.js.map +1 -0
  144. package/dist/request-SQOUNWZ4.mjs +10 -0
  145. package/dist/request-SQOUNWZ4.mjs.map +1 -0
  146. package/dist/server/cachedGet.d.mts +1 -1
  147. package/dist/server/cachedGet.d.ts +1 -1
  148. package/dist/server/cachedGet.stub.d.mts +1 -1
  149. package/dist/server/cachedGet.stub.d.ts +1 -1
  150. package/dist/server/index.d.mts +28 -2
  151. package/dist/server/index.d.ts +28 -2
  152. package/dist/server/index.js +18 -8
  153. package/dist/server/index.js.map +1 -1
  154. package/dist/server/index.mjs +18 -8
  155. package/dist/{useSocket-IRHtk2xc.d.ts → useSocket-Bo9M0t0J.d.ts} +3 -1
  156. package/dist/{useSocket-C8fqU4od.d.mts → useSocket-J5qanQPN.d.mts} +3 -1
  157. package/dist/write-through-FDQ7N4YI.js +15 -0
  158. package/dist/write-through-FDQ7N4YI.js.map +1 -0
  159. package/dist/write-through-R25VQMH6.mjs +15 -0
  160. package/dist/write-through-R25VQMH6.mjs.map +1 -0
  161. package/package.json +7 -1
  162. package/pwa/sw.js +277 -26
  163. package/src/client/request.ts +37 -0
  164. package/src/components/containers/RoundPageContainer.tsx +8 -8
  165. package/src/components/editors/BlockNoteEditor.tsx +14 -0
  166. package/src/components/editors/__tests__/BlockNoteEditor.empty-change.spec.tsx +205 -0
  167. package/src/contexts/SocketContext.tsx +7 -1
  168. package/src/contexts/__tests__/SocketContext.session.spec.tsx +52 -5
  169. package/src/core/factories/RehydrationFactory.ts +28 -8
  170. package/src/core/factories/__tests__/RehydrationFactory.spec.ts +33 -0
  171. package/src/core/index.ts +3 -0
  172. package/src/core/interfaces/ApiData.ts +2 -0
  173. package/src/core/registry/ModuleRegistry.ts +3 -0
  174. package/src/features/auth/components/forms/Logout.tsx +8 -1
  175. package/src/features/auth/components/forms/__tests__/Logout.spec.tsx +62 -0
  176. package/src/hooks/__tests__/useSocket.pause.spec.ts +39 -0
  177. package/src/hooks/useSocket.ts +20 -1
  178. package/src/offline/__tests__/answer-builders.spec.ts +176 -0
  179. package/src/offline/__tests__/device-switch.spec.ts +179 -0
  180. package/src/offline/__tests__/generic-answers.spec.ts +380 -0
  181. package/src/offline/__tests__/local-transport.spec.ts +150 -0
  182. package/src/offline/__tests__/logout.spec.ts +122 -0
  183. package/src/offline/__tests__/offline-fixtures.ts +89 -0
  184. package/src/offline/__tests__/router.spec.ts +56 -0
  185. package/src/offline/__tests__/state.spec.ts +62 -0
  186. package/src/offline/__tests__/write-through.spec.ts +137 -0
  187. package/src/offline/config.ts +229 -0
  188. package/src/offline/configure.ts +14 -0
  189. package/src/offline/device-switch.ts +75 -0
  190. package/src/offline/generic-answers.ts +706 -0
  191. package/src/offline/index.ts +67 -0
  192. package/src/offline/local-transport.ts +189 -0
  193. package/src/offline/logout.ts +41 -0
  194. package/src/offline/router.ts +41 -0
  195. package/src/offline/server/__tests__/build-offline-manifest.spec.ts +76 -0
  196. package/src/offline/server/build-offline-manifest.ts +49 -0
  197. package/src/offline/state-hooks.ts +10 -0
  198. package/src/offline/state.ts +143 -0
  199. package/src/offline/store/DeviceStore.ts +112 -0
  200. package/src/offline/store/__tests__/device-store-lifecycle.spec.ts +343 -0
  201. package/src/offline/store/__tests__/shared-database.spec.ts +151 -0
  202. package/src/offline/store/__tests__/sql-device-store.spec.ts +399 -0
  203. package/src/offline/store/lifecycle.ts +315 -0
  204. package/src/offline/store/schema.ts +101 -0
  205. package/src/offline/store/shared-database.ts +321 -0
  206. package/src/offline/store/sql-device-store.ts +469 -0
  207. package/src/offline/store/worker-client.ts +71 -0
  208. package/src/offline/store/worker.ts +87 -0
  209. package/src/offline/sync/__tests__/conflicts.spec.ts +185 -0
  210. package/src/offline/sync/__tests__/queue-drain.spec.ts +364 -0
  211. package/src/offline/sync/__tests__/runtime.spec.ts +337 -0
  212. package/src/offline/sync/__tests__/sync-fixtures.ts +103 -0
  213. package/src/offline/sync/__tests__/sync-root.spec.ts +727 -0
  214. package/src/offline/sync/artwork-cache.ts +67 -0
  215. package/src/offline/sync/conflicts.ts +211 -0
  216. package/src/offline/sync/counts.ts +39 -0
  217. package/src/offline/sync/drain-queue.ts +246 -0
  218. package/src/offline/sync/known-roots.ts +37 -0
  219. package/src/offline/sync/models/OfflineChangeSet.ts +34 -0
  220. package/src/offline/sync/models/OfflineChangeSetInterface.ts +54 -0
  221. package/src/offline/sync/models/RootSync.ts +68 -0
  222. package/src/offline/sync/models/RootSyncInterface.ts +20 -0
  223. package/src/offline/sync/models/__tests__/OfflineChangeSet.spec.ts +47 -0
  224. package/src/offline/sync/models/__tests__/RootSync.spec.ts +54 -0
  225. package/src/offline/sync/models/index.ts +5 -0
  226. package/src/offline/sync/models/offline.modules.ts +14 -0
  227. package/src/offline/sync/runtime.ts +226 -0
  228. package/src/offline/sync/session-refresh.ts +32 -0
  229. package/src/offline/sync/sync-root.ts +336 -0
  230. package/src/offline/sync/waiting.ts +40 -0
  231. package/src/offline/types.ts +115 -0
  232. package/src/offline/write-through.ts +189 -0
  233. package/src/pwa/__tests__/sw.spec.ts +358 -1
  234. package/src/server/index.ts +5 -0
  235. package/src/unified/__tests__/JsonApiRequest.offline.spec.ts +243 -0
  236. package/dist/BlockNoteEditor-CBYKEXAQ.js.map +0 -1
  237. package/dist/BlockNoteEditor-N2NBYCPC.mjs.map +0 -1
  238. package/dist/BlockNoteViewer-WGCDB7IJ.js.map +0 -1
  239. package/dist/JsonApiRequest-FZGPLNUF.js +0 -26
  240. package/dist/chunk-6NZKWIOR.js.map +0 -1
  241. package/dist/chunk-6XJOQFCP.mjs.map +0 -1
  242. package/dist/chunk-AA52ORW2.mjs.map +0 -1
  243. package/dist/chunk-EWCY6QJA.mjs.map +0 -1
  244. package/dist/chunk-FF4EIQ6H.js.map +0 -1
  245. package/dist/chunk-JTPRJNT2.js.map +0 -1
  246. package/dist/chunk-L6PYFQTO.js.map +0 -1
  247. package/dist/chunk-O3PDL2CV.js.map +0 -1
  248. package/dist/chunk-PI56A4DG.mjs.map +0 -1
  249. package/dist/request-5RLK2AM3.mjs +0 -9
  250. package/dist/request-EUGTI3BE.js +0 -9
  251. package/dist/request-EUGTI3BE.js.map +0 -1
  252. /package/dist/{JsonApiRequest-A66XK5WT.mjs.map → JsonApiRequest-F6TMJ42G.mjs.map} +0 -0
  253. /package/dist/{chunk-3YW35YHQ.mjs.map → chunk-BH6JWIKI.mjs.map} +0 -0
  254. /package/dist/{chunk-V5MI7RNB.mjs.map → chunk-DGWOVYEC.mjs.map} +0 -0
  255. /package/dist/{request-5RLK2AM3.mjs.map → lifecycle-LKGPRBS7.mjs.map} +0 -0
@@ -1,18 +1,22 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkKSYQEKJXjs = require('../../chunk-KSYQEKJX.js');
4
- require('../../chunk-YUO55Q5A.js');
3
+ var _chunk2SV4SS6Njs = require('../../chunk-2SV4SS6N.js');
5
4
  require('../../chunk-6TUB7Y6T.js');
5
+ require('../../chunk-YUO55Q5A.js');
6
+
6
7
 
7
8
 
8
9
 
10
+ var _chunkMOGEGWXWjs = require('../../chunk-MOGEGWXW.js');
9
11
 
10
12
 
11
13
 
12
- var _chunkFF4EIQ6Hjs = require('../../chunk-FF4EIQ6H.js');
13
- require('../../chunk-GHE4VT2R.js');
14
+ var _chunkBZ5J2FIVjs = require('../../chunk-BZ5J2FIV.js');
15
+ require('../../chunk-PV4Z5W6V.js');
16
+ require('../../chunk-KMW7UNL2.js');
17
+ require('../../chunk-MHB36MYE.js');
18
+ require('../../chunk-QKNGZDSQ.js');
14
19
  require('../../chunk-LXKSUWAV.js');
15
- require('../../chunk-JTPRJNT2.js');
16
20
 
17
21
 
18
22
  var _chunk7QVYU63Ejs = require('../../chunk-7QVYU63E.js');
@@ -50,14 +54,14 @@ _chunk7QVYU63Ejs.__name.call(void 0, toPublicBlogCategory, "toPublicBlogCategory
50
54
 
51
55
  // src/features/blog/server/fetchers.ts
52
56
  var BLOG_PAGE_SIZE = 12;
53
- var publicPostsEndpoint = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => `${_chunkFF4EIQ6Hjs.BLOG_PUBLIC_PREFIX}/${_chunkFF4EIQ6Hjs.Modules.BlogPost.name}`, "publicPostsEndpoint");
57
+ var publicPostsEndpoint = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => `${_chunkMOGEGWXWjs.BLOG_PUBLIC_PREFIX}/${_chunkBZ5J2FIVjs.Modules.BlogPost.name}`, "publicPostsEndpoint");
54
58
  var asArray = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (data) => Array.isArray(data) ? data : data ? [data] : [], "asArray");
55
59
  async function fetchPublicBlogPosts(params) {
56
60
  if (params.all) return { posts: await fetchEveryPublicBlogPost(params), hasMore: false };
57
61
  const page = Math.min(10, Math.max(1, Math.floor(params.page || 1)));
58
62
  const size = BLOG_PAGE_SIZE * page;
59
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
60
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogPost, cache: "minutes" },
63
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
64
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogPost, cache: "minutes" },
61
65
  endpoint: publicPostsListEndpoint({ ...params, size }),
62
66
  language: params.language
63
67
  });
@@ -69,7 +73,7 @@ async function fetchPublicBlogPosts(params) {
69
73
  }
70
74
  _chunk7QVYU63Ejs.__name.call(void 0, fetchPublicBlogPosts, "fetchPublicBlogPosts");
71
75
  function publicPostsListEndpoint(params) {
72
- const endpoint = new (0, _chunkFF4EIQ6Hjs.EndpointCreator)({ endpoint: publicPostsEndpoint() });
76
+ const endpoint = new (0, _chunkBZ5J2FIVjs.EndpointCreator)({ endpoint: publicPostsEndpoint() });
73
77
  endpoint.addAdditionalParam("language", params.language);
74
78
  if (params.categorySlug) endpoint.addAdditionalParam("category", encodeURIComponent(params.categorySlug));
75
79
  if (params.search) endpoint.addAdditionalParam("search", encodeURIComponent(params.search));
@@ -83,8 +87,8 @@ var MAX_ALL_PAGES = 100;
83
87
  async function fetchEveryPublicBlogPost(params) {
84
88
  const posts = [];
85
89
  for (let index = 0; index < MAX_ALL_PAGES; index++) {
86
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
87
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogPost, cache: "minutes" },
90
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
91
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogPost, cache: "minutes" },
88
92
  endpoint: publicPostsListEndpoint({
89
93
  ...params,
90
94
  size: PUBLIC_MAX_PAGE_SIZE,
@@ -101,10 +105,10 @@ async function fetchEveryPublicBlogPost(params) {
101
105
  }
102
106
  _chunk7QVYU63Ejs.__name.call(void 0, fetchEveryPublicBlogPost, "fetchEveryPublicBlogPost");
103
107
  async function fetchPublicBlogPost(params) {
104
- const endpoint = new (0, _chunkFF4EIQ6Hjs.EndpointCreator)({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });
108
+ const endpoint = new (0, _chunkBZ5J2FIVjs.EndpointCreator)({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });
105
109
  endpoint.addAdditionalParam("language", params.language);
106
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
107
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogPost, cache: "minutes" },
110
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
111
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogPost, cache: "minutes" },
108
112
  endpoint: endpoint.generate(),
109
113
  language: params.language
110
114
  });
@@ -114,14 +118,14 @@ async function fetchPublicBlogPost(params) {
114
118
  }
115
119
  _chunk7QVYU63Ejs.__name.call(void 0, fetchPublicBlogPost, "fetchPublicBlogPost");
116
120
  async function fetchRelatedBlogPosts(params) {
117
- const endpoint = new (0, _chunkFF4EIQ6Hjs.EndpointCreator)({
121
+ const endpoint = new (0, _chunkBZ5J2FIVjs.EndpointCreator)({
118
122
  endpoint: publicPostsEndpoint(),
119
123
  id: encodeURIComponent(params.slug),
120
- childEndpoint: _chunkFF4EIQ6Hjs.BLOG_ACTION.related
124
+ childEndpoint: _chunkMOGEGWXWjs.BLOG_ACTION.related
121
125
  });
122
126
  endpoint.addAdditionalParam("language", params.language);
123
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
124
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogPost, cache: "minutes" },
127
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
128
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogPost, cache: "minutes" },
125
129
  endpoint: endpoint.generate(),
126
130
  language: params.language
127
131
  });
@@ -130,10 +134,10 @@ async function fetchRelatedBlogPosts(params) {
130
134
  }
131
135
  _chunk7QVYU63Ejs.__name.call(void 0, fetchRelatedBlogPosts, "fetchRelatedBlogPosts");
132
136
  async function fetchPublicBlogCategories(params) {
133
- const endpoint = new (0, _chunkFF4EIQ6Hjs.EndpointCreator)({ endpoint: `${_chunkFF4EIQ6Hjs.BLOG_PUBLIC_PREFIX}/${_chunkFF4EIQ6Hjs.Modules.BlogCategory.name}` });
137
+ const endpoint = new (0, _chunkBZ5J2FIVjs.EndpointCreator)({ endpoint: `${_chunkMOGEGWXWjs.BLOG_PUBLIC_PREFIX}/${_chunkBZ5J2FIVjs.Modules.BlogCategory.name}` });
134
138
  endpoint.addAdditionalParam("language", params.language);
135
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
136
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogCategory, cache: "minutes" },
139
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
140
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogCategory, cache: "minutes" },
137
141
  endpoint: endpoint.generate(),
138
142
  language: params.language
139
143
  });
@@ -143,14 +147,14 @@ async function fetchPublicBlogCategories(params) {
143
147
  _chunk7QVYU63Ejs.__name.call(void 0, fetchPublicBlogCategories, "fetchPublicBlogCategories");
144
148
  async function fetchBlogSettings() {
145
149
  const fallback = { listLayout: "featured" };
146
- const res = await _chunkKSYQEKJXjs.ServerJsonApiGet.call(void 0, {
147
- classKey: { ..._chunkFF4EIQ6Hjs.Modules.BlogSettings, cache: "minutes" },
148
- endpoint: new (0, _chunkFF4EIQ6Hjs.EndpointCreator)({ endpoint: `${_chunkFF4EIQ6Hjs.BLOG_PUBLIC_PREFIX}/${_chunkFF4EIQ6Hjs.Modules.BlogSettings.name}` }).generate(),
150
+ const res = await _chunk2SV4SS6Njs.ServerJsonApiGet.call(void 0, {
151
+ classKey: { ..._chunkBZ5J2FIVjs.Modules.BlogSettings, cache: "minutes" },
152
+ endpoint: new (0, _chunkBZ5J2FIVjs.EndpointCreator)({ endpoint: `${_chunkMOGEGWXWjs.BLOG_PUBLIC_PREFIX}/${_chunkBZ5J2FIVjs.Modules.BlogSettings.name}` }).generate(),
149
153
  language: "en"
150
154
  });
151
155
  if (!res.ok) return fallback;
152
156
  const settings = asArray(res.data)[0];
153
- if (!settings || !_chunkFF4EIQ6Hjs.BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;
157
+ if (!settings || !_chunkMOGEGWXWjs.BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;
154
158
  return { listLayout: settings.listLayout };
155
159
  }
156
160
  _chunk7QVYU63Ejs.__name.call(void 0, fetchBlogSettings, "fetchBlogSettings");
@@ -163,5 +167,5 @@ _chunk7QVYU63Ejs.__name.call(void 0, fetchBlogSettings, "fetchBlogSettings");
163
167
 
164
168
 
165
169
 
166
- exports.BLOG_LIST_LAYOUTS = _chunkFF4EIQ6Hjs.BLOG_LIST_LAYOUTS; exports.fetchBlogSettings = fetchBlogSettings; exports.fetchPublicBlogCategories = fetchPublicBlogCategories; exports.fetchPublicBlogPost = fetchPublicBlogPost; exports.fetchPublicBlogPosts = fetchPublicBlogPosts; exports.fetchRelatedBlogPosts = fetchRelatedBlogPosts; exports.toPublicBlogCategory = toPublicBlogCategory; exports.toPublicBlogPost = toPublicBlogPost;
170
+ exports.BLOG_LIST_LAYOUTS = _chunkMOGEGWXWjs.BLOG_LIST_LAYOUTS; exports.fetchBlogSettings = fetchBlogSettings; exports.fetchPublicBlogCategories = fetchPublicBlogCategories; exports.fetchPublicBlogPost = fetchPublicBlogPost; exports.fetchPublicBlogPosts = fetchPublicBlogPosts; exports.fetchRelatedBlogPosts = fetchRelatedBlogPosts; exports.toPublicBlogCategory = toPublicBlogCategory; exports.toPublicBlogPost = toPublicBlogPost;
167
171
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/blog/server.js","../../../src/features/blog/server/toPublic.ts","../../../src/features/blog/server/fetchers.ts"],"names":[],"mappings":"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","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/blog/server.js","sourcesContent":[null,"import { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { PublicBlogCategory, PublicBlogPost } from \"../types/blog-public.types\";\n\n// Serialisation boundary: a rehydrated model (class instance, Date getters)\n// becomes plain data a server page can pass to the public client components.\n\nexport function toPublicBlogPost(post: BlogPostInterface): PublicBlogPost {\n const publishedAt = post.publishedAt ?? post.createdAt;\n\n return {\n id: post.id,\n language: post.language ?? post.originalLanguage,\n title: post.title ?? \"\",\n slug: post.slug ?? \"\",\n summary: post.summary,\n body: post.body,\n coverImage: post.coverImage,\n coverImageAlt: post.coverImageAlt,\n readingMinutes: post.readingMinutes ?? 1,\n publishedAt: publishedAt.toISOString(),\n updatedAt: post.updatedAt.toISOString(),\n authorName: post.authorName,\n categoryIds: [...post.categoryIds],\n };\n}\n\nexport function toPublicBlogCategory(category: BlogCategoryInterface): PublicBlogCategory {\n return {\n id: category.id,\n name: category.name ?? \"\",\n slug: category.slug ?? \"\",\n description: category.description,\n image: category.image,\n };\n}\n","import { EndpointCreator, Modules } from \"../../../core\";\nimport { ServerJsonApiGet } from \"../../../server/JsonApiServer\";\nimport { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { BlogSettingsInterface } from \"../data/BlogSettingsInterface\";\nimport { BLOG_ACTION, BLOG_LIST_LAYOUTS, BLOG_PUBLIC_PREFIX, BlogListLayout } from \"../types/blog.constants\";\nimport { PublicBlogCategory, PublicBlogList, PublicBlogPost } from \"../types/blog-public.types\";\nimport { toPublicBlogCategory, toPublicBlogPost } from \"./toPublic\";\n\n// Public, token-free reads for the marketing blog pages.\n//\n// `cache: \"minutes\"` is a cacheLife profile name: the GET goes through\n// cachedServerGet (\"use cache\"), so an admin change shows up within about a\n// minute. Nothing connects API or worker writes to the web cache, and\n// translations finish asynchronously in the worker, so there is no tag to expire.\n//\n// Each classKey is built INSIDE the function, never at module scope: reading\n// Modules.X while the module evaluates throws \"Module X not registered\" in build\n// workers that never ran the app's bootstrapper (see the app's publicHowTo.ts).\n\nconst BLOG_PAGE_SIZE = 12;\n\nconst publicPostsEndpoint = () => `${BLOG_PUBLIC_PREFIX}/${Modules.BlogPost.name}`;\n\nconst asArray = <T>(data: unknown): T[] => (Array.isArray(data) ? data : data ? [data] : []) as T[];\n\nexport async function fetchPublicBlogPosts(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n /** 1-based list page; ignored with `all`. */\n page?: number;\n /** Every matching post, read in API-sized pages (a sitemap). `hasMore` is then false. */\n all?: boolean;\n}): Promise<PublicBlogList> {\n if (params.all) return { posts: await fetchEveryPublicBlogPost(params), hasMore: false };\n\n // Matches the API cap (120 = 10 pages of 12); a larger ?page= is served as the last allowed one.\n const page = Math.min(10, Math.max(1, Math.floor(params.page || 1)));\n const size = BLOG_PAGE_SIZE * page;\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({ ...params, size }),\n language: params.language,\n });\n if (!res.ok) return { posts: [], hasMore: false };\n\n const posts = asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n const total = Number(res.meta?.total);\n const hasMore = Number.isFinite(total) ? total > posts.length : false;\n\n return { posts, hasMore };\n}\n\nfunction publicPostsListEndpoint(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n size: number;\n offset?: number;\n}): string {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint() });\n endpoint.addAdditionalParam(\"language\", params.language);\n if (params.categorySlug) endpoint.addAdditionalParam(\"category\", encodeURIComponent(params.categorySlug));\n if (params.search) endpoint.addAdditionalParam(\"search\", encodeURIComponent(params.search));\n endpoint.addAdditionalParam(\"page[size]\", String(params.size));\n if (params.offset) endpoint.addAdditionalParam(\"page[offset]\", String(params.offset));\n return endpoint.generate();\n}\n\n// The API serves at most PUBLIC_MAX_PAGE_SIZE posts per request, so \"all\" walks\n// page[offset] until a short page comes back. MAX_ALL_PAGES only stops a runaway loop.\nconst PUBLIC_MAX_PAGE_SIZE = 120;\nconst MAX_ALL_PAGES = 100;\n\nasync function fetchEveryPublicBlogPost(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n}): Promise<PublicBlogPost[]> {\n const posts: PublicBlogPost[] = [];\n\n // In sequence: a failing cached call throws, and parallel failing cached calls\n // never close the response.\n for (let index = 0; index < MAX_ALL_PAGES; index++) {\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({\n ...params,\n size: PUBLIC_MAX_PAGE_SIZE,\n offset: index * PUBLIC_MAX_PAGE_SIZE,\n }),\n language: params.language,\n });\n if (!res.ok) break;\n\n const batch = asArray<BlogPostInterface>(res.data);\n posts.push(...batch.map(toPublicBlogPost));\n if (batch.length < PUBLIC_MAX_PAGE_SIZE) break;\n }\n\n return posts;\n}\n\nexport async function fetchPublicBlogPost(params: { language: string; slug: string }): Promise<PublicBlogPost | null> {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return null;\n\n const post = asArray<BlogPostInterface>(res.data)[0];\n return post ? toPublicBlogPost(post) : null;\n}\n\nexport async function fetchRelatedBlogPosts(params: { language: string; slug: string }): Promise<PublicBlogPost[]> {\n const endpoint = new EndpointCreator({\n endpoint: publicPostsEndpoint(),\n id: encodeURIComponent(params.slug),\n childEndpoint: BLOG_ACTION.related,\n });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n}\n\nexport async function fetchPublicBlogCategories(params: { language: string }): Promise<PublicBlogCategory[]> {\n const endpoint = new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogCategory.name}` });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogCategory, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogCategoryInterface>(res.data).map(toPublicBlogCategory);\n}\n\nexport async function fetchBlogSettings(): Promise<{ listLayout: BlogListLayout }> {\n const fallback: { listLayout: BlogListLayout } = { listLayout: \"featured\" };\n\n // The settings are language-neutral; the language only fills the required\n // request header, so one fixed value keeps a single cache entry.\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogSettings, cache: \"minutes\" },\n endpoint: new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogSettings.name}` }).generate(),\n language: \"en\",\n });\n if (!res.ok) return fallback;\n\n const settings = asArray<BlogSettingsInterface>(res.data)[0];\n if (!settings || !BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;\n\n return { listLayout: settings.listLayout };\n}\n"]}
1
+ {"version":3,"sources":["/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/blog/server.js","../../../src/features/blog/server/toPublic.ts","../../../src/features/blog/server/fetchers.ts"],"names":[],"mappings":"AAAA;AACE;AACF,0DAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC;AACE;AACA;AACA;AACF,0DAAgC;AAChC;AACE;AACA;AACF,0DAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC,mCAAgC;AAChC;AACE;AACF,0DAAgC;AAChC;AACA;AChBO,SAAS,gBAAA,CAAiB,IAAA,EAAyC;AACxE,EAAA,MAAM,YAAA,mBAAc,IAAA,CAAK,WAAA,UAAe,IAAA,CAAK,WAAA;AAE7C,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,IAAA,CAAK,EAAA;AAAA,IACT,QAAA,mBAAU,IAAA,CAAK,QAAA,UAAY,IAAA,CAAK,kBAAA;AAAA,IAChC,KAAA,mBAAO,IAAA,CAAK,KAAA,UAAS,IAAA;AAAA,IACrB,IAAA,mBAAM,IAAA,CAAK,IAAA,UAAQ,IAAA;AAAA,IACnB,OAAA,EAAS,IAAA,CAAK,OAAA;AAAA,IACd,IAAA,EAAM,IAAA,CAAK,IAAA;AAAA,IACX,UAAA,EAAY,IAAA,CAAK,UAAA;AAAA,IACjB,aAAA,EAAe,IAAA,CAAK,aAAA;AAAA,IACpB,cAAA,mBAAgB,IAAA,CAAK,cAAA,UAAkB,GAAA;AAAA,IACvC,WAAA,EAAa,WAAA,CAAY,WAAA,CAAY,CAAA;AAAA,IACrC,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,CAAA;AAAA,IACtC,UAAA,EAAY,IAAA,CAAK,UAAA;AAAA,IACjB,WAAA,EAAa,CAAC,GAAG,IAAA,CAAK,WAAW;AAAA,EACnC,CAAA;AACF;AAlBgB,qCAAA,gBAAA,EAAA,kBAAA,CAAA;AAoBT,SAAS,oBAAA,CAAqB,QAAA,EAAqD;AACxF,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,QAAA,CAAS,EAAA;AAAA,IACb,IAAA,mBAAM,QAAA,CAAS,IAAA,UAAQ,IAAA;AAAA,IACvB,IAAA,mBAAM,QAAA,CAAS,IAAA,UAAQ,IAAA;AAAA,IACvB,WAAA,EAAa,QAAA,CAAS,WAAA;AAAA,IACtB,KAAA,EAAO,QAAA,CAAS;AAAA,EAClB,CAAA;AACF;AARgB,qCAAA,oBAAA,EAAA,sBAAA,CAAA;AD0BhB;AACA;AElCA,IAAM,eAAA,EAAiB,EAAA;AAEvB,IAAM,oBAAA,kBAAsB,qCAAA,CAAA,EAAA,GAAM,CAAA,EAAA;AAEgB;AAUtB;AACY,EAAA;AAGW,EAAA;AACnB,EAAA;AAEK,EAAA;AACiB,IAAA;AACE,IAAA;AACnC,IAAA;AAClB,EAAA;AAC+C,EAAA;AAEuB,EAAA;AACnC,EAAA;AACa,EAAA;AAEzB,EAAA;AAC1B;AA3BsB;AAmCX;AACwC,EAAA;AACF,EAAA;AACM,EAAA;AACN,EAAA;AACE,EAAA;AACF,EAAA;AACtB,EAAA;AAC3B;AAdS;AAkBoB;AACP;AAMQ;AACK,EAAA;AAImB,EAAA;AACf,IAAA;AACiB,MAAA;AAChB,MAAA;AAC7B,QAAA;AACG,QAAA;AACU,QAAA;AACjB,MAAA;AACgB,MAAA;AAClB,IAAA;AACY,IAAA;AAEoC,IAAA;AACR,IAAA;AACA,IAAA;AAC3C,EAAA;AAEO,EAAA;AACT;AA3Be;AA6BuG;AACnE,EAAA;AACF,EAAA;AAEZ,EAAA;AACiB,IAAA;AACtB,IAAA;AACX,IAAA;AAClB,EAAA;AACmB,EAAA;AAE+B,EAAA;AACZ,EAAA;AACzC;AAbsB;AAe6F;AAC5E,EAAA;AACL,IAAA;AACI,IAAA;AACP,IAAA;AAC5B,EAAA;AAC8C,EAAA;AAEZ,EAAA;AACiB,IAAA;AACtB,IAAA;AACX,IAAA;AAClB,EAAA;AACoB,EAAA;AAE2C,EAAA;AAClE;AAhBsB;AAkBuF;AACvD,EAAA;AACL,EAAA;AAEZ,EAAA;AACW,IAAA;AAChB,IAAA;AACX,IAAA;AAClB,EAAA;AACoB,EAAA;AAEmD,EAAA;AAC1E;AAZsB;AAc6D;AACP,EAAA;AAIvC,EAAA;AACW,IAAA;AACC,IAAA;AACnC,IAAA;AACX,EAAA;AACmB,EAAA;AAEuC,EAAA;AACL,EAAA;AAEb,EAAA;AAC3C;AAhBsB;AFQkC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/nextjs-jsonapi/nextjs-jsonapi/dist/features/blog/server.js","sourcesContent":[null,"import { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { PublicBlogCategory, PublicBlogPost } from \"../types/blog-public.types\";\n\n// Serialisation boundary: a rehydrated model (class instance, Date getters)\n// becomes plain data a server page can pass to the public client components.\n\nexport function toPublicBlogPost(post: BlogPostInterface): PublicBlogPost {\n const publishedAt = post.publishedAt ?? post.createdAt;\n\n return {\n id: post.id,\n language: post.language ?? post.originalLanguage,\n title: post.title ?? \"\",\n slug: post.slug ?? \"\",\n summary: post.summary,\n body: post.body,\n coverImage: post.coverImage,\n coverImageAlt: post.coverImageAlt,\n readingMinutes: post.readingMinutes ?? 1,\n publishedAt: publishedAt.toISOString(),\n updatedAt: post.updatedAt.toISOString(),\n authorName: post.authorName,\n categoryIds: [...post.categoryIds],\n };\n}\n\nexport function toPublicBlogCategory(category: BlogCategoryInterface): PublicBlogCategory {\n return {\n id: category.id,\n name: category.name ?? \"\",\n slug: category.slug ?? \"\",\n description: category.description,\n image: category.image,\n };\n}\n","import { EndpointCreator, Modules } from \"../../../core\";\nimport { ServerJsonApiGet } from \"../../../server/JsonApiServer\";\nimport { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { BlogSettingsInterface } from \"../data/BlogSettingsInterface\";\nimport { BLOG_ACTION, BLOG_LIST_LAYOUTS, BLOG_PUBLIC_PREFIX, BlogListLayout } from \"../types/blog.constants\";\nimport { PublicBlogCategory, PublicBlogList, PublicBlogPost } from \"../types/blog-public.types\";\nimport { toPublicBlogCategory, toPublicBlogPost } from \"./toPublic\";\n\n// Public, token-free reads for the marketing blog pages.\n//\n// `cache: \"minutes\"` is a cacheLife profile name: the GET goes through\n// cachedServerGet (\"use cache\"), so an admin change shows up within about a\n// minute. Nothing connects API or worker writes to the web cache, and\n// translations finish asynchronously in the worker, so there is no tag to expire.\n//\n// Each classKey is built INSIDE the function, never at module scope: reading\n// Modules.X while the module evaluates throws \"Module X not registered\" in build\n// workers that never ran the app's bootstrapper (see the app's publicHowTo.ts).\n\nconst BLOG_PAGE_SIZE = 12;\n\nconst publicPostsEndpoint = () => `${BLOG_PUBLIC_PREFIX}/${Modules.BlogPost.name}`;\n\nconst asArray = <T>(data: unknown): T[] => (Array.isArray(data) ? data : data ? [data] : []) as T[];\n\nexport async function fetchPublicBlogPosts(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n /** 1-based list page; ignored with `all`. */\n page?: number;\n /** Every matching post, read in API-sized pages (a sitemap). `hasMore` is then false. */\n all?: boolean;\n}): Promise<PublicBlogList> {\n if (params.all) return { posts: await fetchEveryPublicBlogPost(params), hasMore: false };\n\n // Matches the API cap (120 = 10 pages of 12); a larger ?page= is served as the last allowed one.\n const page = Math.min(10, Math.max(1, Math.floor(params.page || 1)));\n const size = BLOG_PAGE_SIZE * page;\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({ ...params, size }),\n language: params.language,\n });\n if (!res.ok) return { posts: [], hasMore: false };\n\n const posts = asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n const total = Number(res.meta?.total);\n const hasMore = Number.isFinite(total) ? total > posts.length : false;\n\n return { posts, hasMore };\n}\n\nfunction publicPostsListEndpoint(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n size: number;\n offset?: number;\n}): string {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint() });\n endpoint.addAdditionalParam(\"language\", params.language);\n if (params.categorySlug) endpoint.addAdditionalParam(\"category\", encodeURIComponent(params.categorySlug));\n if (params.search) endpoint.addAdditionalParam(\"search\", encodeURIComponent(params.search));\n endpoint.addAdditionalParam(\"page[size]\", String(params.size));\n if (params.offset) endpoint.addAdditionalParam(\"page[offset]\", String(params.offset));\n return endpoint.generate();\n}\n\n// The API serves at most PUBLIC_MAX_PAGE_SIZE posts per request, so \"all\" walks\n// page[offset] until a short page comes back. MAX_ALL_PAGES only stops a runaway loop.\nconst PUBLIC_MAX_PAGE_SIZE = 120;\nconst MAX_ALL_PAGES = 100;\n\nasync function fetchEveryPublicBlogPost(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n}): Promise<PublicBlogPost[]> {\n const posts: PublicBlogPost[] = [];\n\n // In sequence: a failing cached call throws, and parallel failing cached calls\n // never close the response.\n for (let index = 0; index < MAX_ALL_PAGES; index++) {\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({\n ...params,\n size: PUBLIC_MAX_PAGE_SIZE,\n offset: index * PUBLIC_MAX_PAGE_SIZE,\n }),\n language: params.language,\n });\n if (!res.ok) break;\n\n const batch = asArray<BlogPostInterface>(res.data);\n posts.push(...batch.map(toPublicBlogPost));\n if (batch.length < PUBLIC_MAX_PAGE_SIZE) break;\n }\n\n return posts;\n}\n\nexport async function fetchPublicBlogPost(params: { language: string; slug: string }): Promise<PublicBlogPost | null> {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return null;\n\n const post = asArray<BlogPostInterface>(res.data)[0];\n return post ? toPublicBlogPost(post) : null;\n}\n\nexport async function fetchRelatedBlogPosts(params: { language: string; slug: string }): Promise<PublicBlogPost[]> {\n const endpoint = new EndpointCreator({\n endpoint: publicPostsEndpoint(),\n id: encodeURIComponent(params.slug),\n childEndpoint: BLOG_ACTION.related,\n });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n}\n\nexport async function fetchPublicBlogCategories(params: { language: string }): Promise<PublicBlogCategory[]> {\n const endpoint = new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogCategory.name}` });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogCategory, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogCategoryInterface>(res.data).map(toPublicBlogCategory);\n}\n\nexport async function fetchBlogSettings(): Promise<{ listLayout: BlogListLayout }> {\n const fallback: { listLayout: BlogListLayout } = { listLayout: \"featured\" };\n\n // The settings are language-neutral; the language only fills the required\n // request header, so one fixed value keeps a single cache entry.\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogSettings, cache: \"minutes\" },\n endpoint: new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogSettings.name}` }).generate(),\n language: \"en\",\n });\n if (!res.ok) return fallback;\n\n const settings = asArray<BlogSettingsInterface>(res.data)[0];\n if (!settings || !BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;\n\n return { listLayout: settings.listLayout };\n}\n"]}
@@ -1,18 +1,22 @@
1
1
  import {
2
2
  ServerJsonApiGet
3
- } from "../../chunk-3YW35YHQ.mjs";
4
- import "../../chunk-F5UNXZ3J.mjs";
3
+ } from "../../chunk-BH6JWIKI.mjs";
5
4
  import "../../chunk-E2LENTUH.mjs";
5
+ import "../../chunk-F5UNXZ3J.mjs";
6
6
  import {
7
7
  BLOG_ACTION,
8
8
  BLOG_LIST_LAYOUTS,
9
- BLOG_PUBLIC_PREFIX,
9
+ BLOG_PUBLIC_PREFIX
10
+ } from "../../chunk-P445QGOC.mjs";
11
+ import {
10
12
  EndpointCreator,
11
13
  Modules
12
- } from "../../chunk-AA52ORW2.mjs";
13
- import "../../chunk-V5MI7RNB.mjs";
14
+ } from "../../chunk-6JUCIWDC.mjs";
15
+ import "../../chunk-DOCIFE6A.mjs";
16
+ import "../../chunk-ZLTOUZN2.mjs";
17
+ import "../../chunk-27LQDGNP.mjs";
18
+ import "../../chunk-DGWOVYEC.mjs";
14
19
  import "../../chunk-AUXK7QSA.mjs";
15
- import "../../chunk-PI56A4DG.mjs";
16
20
  import {
17
21
  __name
18
22
  } from "../../chunk-PAWJFY3S.mjs";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/features/blog/server/toPublic.ts","../../../src/features/blog/server/fetchers.ts"],"sourcesContent":["import { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { PublicBlogCategory, PublicBlogPost } from \"../types/blog-public.types\";\n\n// Serialisation boundary: a rehydrated model (class instance, Date getters)\n// becomes plain data a server page can pass to the public client components.\n\nexport function toPublicBlogPost(post: BlogPostInterface): PublicBlogPost {\n const publishedAt = post.publishedAt ?? post.createdAt;\n\n return {\n id: post.id,\n language: post.language ?? post.originalLanguage,\n title: post.title ?? \"\",\n slug: post.slug ?? \"\",\n summary: post.summary,\n body: post.body,\n coverImage: post.coverImage,\n coverImageAlt: post.coverImageAlt,\n readingMinutes: post.readingMinutes ?? 1,\n publishedAt: publishedAt.toISOString(),\n updatedAt: post.updatedAt.toISOString(),\n authorName: post.authorName,\n categoryIds: [...post.categoryIds],\n };\n}\n\nexport function toPublicBlogCategory(category: BlogCategoryInterface): PublicBlogCategory {\n return {\n id: category.id,\n name: category.name ?? \"\",\n slug: category.slug ?? \"\",\n description: category.description,\n image: category.image,\n };\n}\n","import { EndpointCreator, Modules } from \"../../../core\";\nimport { ServerJsonApiGet } from \"../../../server/JsonApiServer\";\nimport { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { BlogSettingsInterface } from \"../data/BlogSettingsInterface\";\nimport { BLOG_ACTION, BLOG_LIST_LAYOUTS, BLOG_PUBLIC_PREFIX, BlogListLayout } from \"../types/blog.constants\";\nimport { PublicBlogCategory, PublicBlogList, PublicBlogPost } from \"../types/blog-public.types\";\nimport { toPublicBlogCategory, toPublicBlogPost } from \"./toPublic\";\n\n// Public, token-free reads for the marketing blog pages.\n//\n// `cache: \"minutes\"` is a cacheLife profile name: the GET goes through\n// cachedServerGet (\"use cache\"), so an admin change shows up within about a\n// minute. Nothing connects API or worker writes to the web cache, and\n// translations finish asynchronously in the worker, so there is no tag to expire.\n//\n// Each classKey is built INSIDE the function, never at module scope: reading\n// Modules.X while the module evaluates throws \"Module X not registered\" in build\n// workers that never ran the app's bootstrapper (see the app's publicHowTo.ts).\n\nconst BLOG_PAGE_SIZE = 12;\n\nconst publicPostsEndpoint = () => `${BLOG_PUBLIC_PREFIX}/${Modules.BlogPost.name}`;\n\nconst asArray = <T>(data: unknown): T[] => (Array.isArray(data) ? data : data ? [data] : []) as T[];\n\nexport async function fetchPublicBlogPosts(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n /** 1-based list page; ignored with `all`. */\n page?: number;\n /** Every matching post, read in API-sized pages (a sitemap). `hasMore` is then false. */\n all?: boolean;\n}): Promise<PublicBlogList> {\n if (params.all) return { posts: await fetchEveryPublicBlogPost(params), hasMore: false };\n\n // Matches the API cap (120 = 10 pages of 12); a larger ?page= is served as the last allowed one.\n const page = Math.min(10, Math.max(1, Math.floor(params.page || 1)));\n const size = BLOG_PAGE_SIZE * page;\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({ ...params, size }),\n language: params.language,\n });\n if (!res.ok) return { posts: [], hasMore: false };\n\n const posts = asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n const total = Number(res.meta?.total);\n const hasMore = Number.isFinite(total) ? total > posts.length : false;\n\n return { posts, hasMore };\n}\n\nfunction publicPostsListEndpoint(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n size: number;\n offset?: number;\n}): string {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint() });\n endpoint.addAdditionalParam(\"language\", params.language);\n if (params.categorySlug) endpoint.addAdditionalParam(\"category\", encodeURIComponent(params.categorySlug));\n if (params.search) endpoint.addAdditionalParam(\"search\", encodeURIComponent(params.search));\n endpoint.addAdditionalParam(\"page[size]\", String(params.size));\n if (params.offset) endpoint.addAdditionalParam(\"page[offset]\", String(params.offset));\n return endpoint.generate();\n}\n\n// The API serves at most PUBLIC_MAX_PAGE_SIZE posts per request, so \"all\" walks\n// page[offset] until a short page comes back. MAX_ALL_PAGES only stops a runaway loop.\nconst PUBLIC_MAX_PAGE_SIZE = 120;\nconst MAX_ALL_PAGES = 100;\n\nasync function fetchEveryPublicBlogPost(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n}): Promise<PublicBlogPost[]> {\n const posts: PublicBlogPost[] = [];\n\n // In sequence: a failing cached call throws, and parallel failing cached calls\n // never close the response.\n for (let index = 0; index < MAX_ALL_PAGES; index++) {\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({\n ...params,\n size: PUBLIC_MAX_PAGE_SIZE,\n offset: index * PUBLIC_MAX_PAGE_SIZE,\n }),\n language: params.language,\n });\n if (!res.ok) break;\n\n const batch = asArray<BlogPostInterface>(res.data);\n posts.push(...batch.map(toPublicBlogPost));\n if (batch.length < PUBLIC_MAX_PAGE_SIZE) break;\n }\n\n return posts;\n}\n\nexport async function fetchPublicBlogPost(params: { language: string; slug: string }): Promise<PublicBlogPost | null> {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return null;\n\n const post = asArray<BlogPostInterface>(res.data)[0];\n return post ? toPublicBlogPost(post) : null;\n}\n\nexport async function fetchRelatedBlogPosts(params: { language: string; slug: string }): Promise<PublicBlogPost[]> {\n const endpoint = new EndpointCreator({\n endpoint: publicPostsEndpoint(),\n id: encodeURIComponent(params.slug),\n childEndpoint: BLOG_ACTION.related,\n });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n}\n\nexport async function fetchPublicBlogCategories(params: { language: string }): Promise<PublicBlogCategory[]> {\n const endpoint = new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogCategory.name}` });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogCategory, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogCategoryInterface>(res.data).map(toPublicBlogCategory);\n}\n\nexport async function fetchBlogSettings(): Promise<{ listLayout: BlogListLayout }> {\n const fallback: { listLayout: BlogListLayout } = { listLayout: \"featured\" };\n\n // The settings are language-neutral; the language only fills the required\n // request header, so one fixed value keeps a single cache entry.\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogSettings, cache: \"minutes\" },\n endpoint: new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogSettings.name}` }).generate(),\n language: \"en\",\n });\n if (!res.ok) return fallback;\n\n const settings = asArray<BlogSettingsInterface>(res.data)[0];\n if (!settings || !BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;\n\n return { listLayout: settings.listLayout };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/features/blog/server/toPublic.ts","../../../src/features/blog/server/fetchers.ts"],"sourcesContent":["import { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { PublicBlogCategory, PublicBlogPost } from \"../types/blog-public.types\";\n\n// Serialisation boundary: a rehydrated model (class instance, Date getters)\n// becomes plain data a server page can pass to the public client components.\n\nexport function toPublicBlogPost(post: BlogPostInterface): PublicBlogPost {\n const publishedAt = post.publishedAt ?? post.createdAt;\n\n return {\n id: post.id,\n language: post.language ?? post.originalLanguage,\n title: post.title ?? \"\",\n slug: post.slug ?? \"\",\n summary: post.summary,\n body: post.body,\n coverImage: post.coverImage,\n coverImageAlt: post.coverImageAlt,\n readingMinutes: post.readingMinutes ?? 1,\n publishedAt: publishedAt.toISOString(),\n updatedAt: post.updatedAt.toISOString(),\n authorName: post.authorName,\n categoryIds: [...post.categoryIds],\n };\n}\n\nexport function toPublicBlogCategory(category: BlogCategoryInterface): PublicBlogCategory {\n return {\n id: category.id,\n name: category.name ?? \"\",\n slug: category.slug ?? \"\",\n description: category.description,\n image: category.image,\n };\n}\n","import { EndpointCreator, Modules } from \"../../../core\";\nimport { ServerJsonApiGet } from \"../../../server/JsonApiServer\";\nimport { BlogCategoryInterface } from \"../data/BlogCategoryInterface\";\nimport { BlogPostInterface } from \"../data/BlogPostInterface\";\nimport { BlogSettingsInterface } from \"../data/BlogSettingsInterface\";\nimport { BLOG_ACTION, BLOG_LIST_LAYOUTS, BLOG_PUBLIC_PREFIX, BlogListLayout } from \"../types/blog.constants\";\nimport { PublicBlogCategory, PublicBlogList, PublicBlogPost } from \"../types/blog-public.types\";\nimport { toPublicBlogCategory, toPublicBlogPost } from \"./toPublic\";\n\n// Public, token-free reads for the marketing blog pages.\n//\n// `cache: \"minutes\"` is a cacheLife profile name: the GET goes through\n// cachedServerGet (\"use cache\"), so an admin change shows up within about a\n// minute. Nothing connects API or worker writes to the web cache, and\n// translations finish asynchronously in the worker, so there is no tag to expire.\n//\n// Each classKey is built INSIDE the function, never at module scope: reading\n// Modules.X while the module evaluates throws \"Module X not registered\" in build\n// workers that never ran the app's bootstrapper (see the app's publicHowTo.ts).\n\nconst BLOG_PAGE_SIZE = 12;\n\nconst publicPostsEndpoint = () => `${BLOG_PUBLIC_PREFIX}/${Modules.BlogPost.name}`;\n\nconst asArray = <T>(data: unknown): T[] => (Array.isArray(data) ? data : data ? [data] : []) as T[];\n\nexport async function fetchPublicBlogPosts(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n /** 1-based list page; ignored with `all`. */\n page?: number;\n /** Every matching post, read in API-sized pages (a sitemap). `hasMore` is then false. */\n all?: boolean;\n}): Promise<PublicBlogList> {\n if (params.all) return { posts: await fetchEveryPublicBlogPost(params), hasMore: false };\n\n // Matches the API cap (120 = 10 pages of 12); a larger ?page= is served as the last allowed one.\n const page = Math.min(10, Math.max(1, Math.floor(params.page || 1)));\n const size = BLOG_PAGE_SIZE * page;\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({ ...params, size }),\n language: params.language,\n });\n if (!res.ok) return { posts: [], hasMore: false };\n\n const posts = asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n const total = Number(res.meta?.total);\n const hasMore = Number.isFinite(total) ? total > posts.length : false;\n\n return { posts, hasMore };\n}\n\nfunction publicPostsListEndpoint(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n size: number;\n offset?: number;\n}): string {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint() });\n endpoint.addAdditionalParam(\"language\", params.language);\n if (params.categorySlug) endpoint.addAdditionalParam(\"category\", encodeURIComponent(params.categorySlug));\n if (params.search) endpoint.addAdditionalParam(\"search\", encodeURIComponent(params.search));\n endpoint.addAdditionalParam(\"page[size]\", String(params.size));\n if (params.offset) endpoint.addAdditionalParam(\"page[offset]\", String(params.offset));\n return endpoint.generate();\n}\n\n// The API serves at most PUBLIC_MAX_PAGE_SIZE posts per request, so \"all\" walks\n// page[offset] until a short page comes back. MAX_ALL_PAGES only stops a runaway loop.\nconst PUBLIC_MAX_PAGE_SIZE = 120;\nconst MAX_ALL_PAGES = 100;\n\nasync function fetchEveryPublicBlogPost(params: {\n language: string;\n categorySlug?: string;\n search?: string;\n}): Promise<PublicBlogPost[]> {\n const posts: PublicBlogPost[] = [];\n\n // In sequence: a failing cached call throws, and parallel failing cached calls\n // never close the response.\n for (let index = 0; index < MAX_ALL_PAGES; index++) {\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: publicPostsListEndpoint({\n ...params,\n size: PUBLIC_MAX_PAGE_SIZE,\n offset: index * PUBLIC_MAX_PAGE_SIZE,\n }),\n language: params.language,\n });\n if (!res.ok) break;\n\n const batch = asArray<BlogPostInterface>(res.data);\n posts.push(...batch.map(toPublicBlogPost));\n if (batch.length < PUBLIC_MAX_PAGE_SIZE) break;\n }\n\n return posts;\n}\n\nexport async function fetchPublicBlogPost(params: { language: string; slug: string }): Promise<PublicBlogPost | null> {\n const endpoint = new EndpointCreator({ endpoint: publicPostsEndpoint(), id: encodeURIComponent(params.slug) });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return null;\n\n const post = asArray<BlogPostInterface>(res.data)[0];\n return post ? toPublicBlogPost(post) : null;\n}\n\nexport async function fetchRelatedBlogPosts(params: { language: string; slug: string }): Promise<PublicBlogPost[]> {\n const endpoint = new EndpointCreator({\n endpoint: publicPostsEndpoint(),\n id: encodeURIComponent(params.slug),\n childEndpoint: BLOG_ACTION.related,\n });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogPost, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogPostInterface>(res.data).map(toPublicBlogPost);\n}\n\nexport async function fetchPublicBlogCategories(params: { language: string }): Promise<PublicBlogCategory[]> {\n const endpoint = new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogCategory.name}` });\n endpoint.addAdditionalParam(\"language\", params.language);\n\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogCategory, cache: \"minutes\" },\n endpoint: endpoint.generate(),\n language: params.language,\n });\n if (!res.ok) return [];\n\n return asArray<BlogCategoryInterface>(res.data).map(toPublicBlogCategory);\n}\n\nexport async function fetchBlogSettings(): Promise<{ listLayout: BlogListLayout }> {\n const fallback: { listLayout: BlogListLayout } = { listLayout: \"featured\" };\n\n // The settings are language-neutral; the language only fills the required\n // request header, so one fixed value keeps a single cache entry.\n const res = await ServerJsonApiGet({\n classKey: { ...Modules.BlogSettings, cache: \"minutes\" },\n endpoint: new EndpointCreator({ endpoint: `${BLOG_PUBLIC_PREFIX}/${Modules.BlogSettings.name}` }).generate(),\n language: \"en\",\n });\n if (!res.ok) return fallback;\n\n const settings = asArray<BlogSettingsInterface>(res.data)[0];\n if (!settings || !BLOG_LIST_LAYOUTS.includes(settings.listLayout)) return fallback;\n\n return { listLayout: settings.listLayout };\n}\n"],"mappings":"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","names":[]}
@@ -23,18 +23,22 @@ var _chunkYBZVWLPHjs = require('../../chunk-YBZVWLPH.js');
23
23
 
24
24
 
25
25
 
26
- var _chunk6NZKWIORjs = require('../../chunk-6NZKWIOR.js');
26
+ var _chunk2H342HNNjs = require('../../chunk-2H342HNN.js');
27
+ require('../../chunk-3EPNHTMH.js');
27
28
 
28
29
 
29
- var _chunkL6PYFQTOjs = require('../../chunk-L6PYFQTO.js');
30
+ var _chunk7ZHTPFFTjs = require('../../chunk-7ZHTPFFT.js');
30
31
  require('../../chunk-G4JR3SFV.js');
31
32
 
32
33
 
33
- var _chunkFF4EIQ6Hjs = require('../../chunk-FF4EIQ6H.js');
34
- require('../../chunk-GHE4VT2R.js');
34
+ var _chunkMOGEGWXWjs = require('../../chunk-MOGEGWXW.js');
35
+ require('../../chunk-GB6DBFYY.js');
36
+ require('../../chunk-BZ5J2FIV.js');
37
+ require('../../chunk-PV4Z5W6V.js');
38
+ require('../../chunk-KMW7UNL2.js');
39
+ require('../../chunk-MHB36MYE.js');
40
+ require('../../chunk-QKNGZDSQ.js');
35
41
  require('../../chunk-LXKSUWAV.js');
36
- require('../../chunk-JTPRJNT2.js');
37
- require('../../chunk-3EPNHTMH.js');
38
42
 
39
43
 
40
44
  var _chunk7QVYU63Ejs = require('../../chunk-7QVYU63E.js');
@@ -44,7 +48,7 @@ var _react = require('react');
44
48
  var _jsxruntime = require('react/jsx-runtime');
45
49
  var HelpContext = _react.createContext.call(void 0, null);
46
50
  function HelpProvider({ children }) {
47
- const cfg = _chunkL6PYFQTOjs._getStaticHelpContent.call(void 0, );
51
+ const cfg = _chunk7ZHTPFFTjs._getStaticHelpContent.call(void 0, );
48
52
  if (!cfg) {
49
53
  throw new Error(
50
54
  "Help content not configured \u2014 call configureJsonApi({ helpContent: {...} }) before importing help components."
@@ -76,29 +80,29 @@ var _lucidereact = require('lucide-react');
76
80
 
77
81
 
78
82
  function HelpAssistantSheet({ open, onOpenChange }) {
79
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.Sheet, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
80
- _chunk6NZKWIORjs.SheetContent,
83
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.Sheet, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
84
+ _chunk2H342HNNjs.SheetContent,
81
85
  {
82
86
  side: "end",
83
87
  className: "flex w-full flex-col data-[side=right]:sm:max-w-2xl data-[side=right]:lg:max-w-3xl data-[side=left]:sm:max-w-2xl data-[side=left]:lg:max-w-3xl",
84
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.AssistantProvider, { manageUrl: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheetBody, {}) })
88
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.AssistantProvider, { manageUrl: false, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAssistantSheetBody, {}) })
85
89
  }
86
90
  ) });
87
91
  }
88
92
  _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheet, "HelpAssistantSheet");
89
93
  function HelpAssistantSheetBody() {
90
94
  const t = _nextintl.useTranslations.call(void 0, );
91
- const ctx = _chunk6NZKWIORjs.useAssistantContext.call(void 0, );
95
+ const ctx = _chunk2H342HNNjs.useAssistantContext.call(void 0, );
92
96
  const showThread = !!ctx.assistant || ctx.sending || ctx.messages.length > 0;
93
97
  const send = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (content) => ctx.sendMessage(content, { howToMode: true }), "send");
94
98
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
95
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.SheetHeader, { children: [
96
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.SheetTitle, { children: t("help.askAi.sheet.title") }),
97
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.SheetDescription, { children: t("help.askAi.sheet.subtitle") })
99
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.SheetHeader, { children: [
100
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.SheetTitle, { children: t("help.askAi.sheet.title") }),
101
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.SheetDescription, { children: t("help.askAi.sheet.subtitle") })
98
102
  ] }),
99
- !showThread ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.AssistantEmptyState, { onSend: send }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
103
+ !showThread ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.AssistantEmptyState, { onSend: send }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
100
104
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
101
- _chunk6NZKWIORjs.AssistantThread,
105
+ _chunk2H342HNNjs.AssistantThread,
102
106
  {
103
107
  messages: ctx.messages,
104
108
  sending: ctx.sending,
@@ -108,7 +112,7 @@ function HelpAssistantSheetBody() {
108
112
  onRetry: ctx.retrySend
109
113
  }
110
114
  ),
111
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.AssistantComposer, { onSend: send, disabled: ctx.sending })
115
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.AssistantComposer, { onSend: send, disabled: ctx.sending })
112
116
  ] })
113
117
  ] });
114
118
  }
@@ -118,20 +122,20 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpAssistantSheetBody, "HelpAssistantSheet
118
122
 
119
123
  function HelpAskAi() {
120
124
  const t = _nextintl.useTranslations.call(void 0, );
121
- const { currentUser } = _chunk6NZKWIORjs.useCurrentUserContext.call(void 0, );
125
+ const { currentUser } = _chunk2H342HNNjs.useCurrentUserContext.call(void 0, );
122
126
  const [open, setOpen] = _react.useState.call(void 0, false);
123
127
  const disabled = !currentUser;
124
128
  if (disabled) {
125
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.Tooltip, { children: [
126
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.TooltipTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.Button, { variant: "outline", size: "sm", disabled: true }), children: [
129
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.Tooltip, { children: [
130
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.TooltipTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.Button, { variant: "outline", size: "sm", disabled: true }), children: [
127
131
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
128
132
  t("help.askAi.button")
129
133
  ] }),
130
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.TooltipContent, { children: t("help.askAi.loginTooltip") })
134
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.TooltipContent, { children: t("help.askAi.loginTooltip") })
131
135
  ] });
132
136
  }
133
137
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
134
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.Button, { variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
138
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.Button, { variant: "outline", size: "sm", onClick: () => setOpen(true), children: [
135
139
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { className: "h-4 w-4" }),
136
140
  t("help.askAi.button")
137
141
  ] }),
@@ -144,7 +148,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpAskAi, "HelpAskAi");
144
148
 
145
149
  function HelpHeader() {
146
150
  const t = _nextintl.useTranslations.call(void 0, );
147
- const { currentUser } = _chunk6NZKWIORjs.useCurrentUserContext.call(void 0, );
151
+ const { currentUser } = _chunk2H342HNNjs.useCurrentUserContext.call(void 0, );
148
152
  const { brand } = useHelp();
149
153
  const logo = _optionalChain([brand, 'optionalAccess', _ => _.logo]);
150
154
  const label = _nullishCoalesce(_optionalChain([brand, 'optionalAccess', _2 => _2.label]), () => ( t("help.title")));
@@ -160,7 +164,7 @@ function HelpHeader() {
160
164
  ] }),
161
165
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 max-md:shrink-0", children: [
162
166
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HelpAskAi, {}),
163
- currentUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: appHref, className: _chunk6NZKWIORjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.openApp") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: "/login", className: _chunk6NZKWIORjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.login") })
167
+ currentUser ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: appHref, className: _chunk2H342HNNjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.openApp") }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _link2.default, { href: "/login", className: _chunk2H342HNNjs.buttonVariants.call(void 0, { variant: "outline", size: "sm" }), children: t("help.header.login") })
164
168
  ] })
165
169
  ] });
166
170
  }
@@ -202,12 +206,12 @@ _chunk7QVYU63Ejs.__name.call(void 0, useHelpFilter, "useHelpFilter");
202
206
 
203
207
  function HelpSideNav() {
204
208
  const t = _nextintl.useTranslations.call(void 0, );
205
- const generateUrl = _chunk6NZKWIORjs.usePageUrlGenerator.call(void 0, );
209
+ const generateUrl = _chunk2H342HNNjs.usePageUrlGenerator.call(void 0, );
206
210
  const pathname = _navigation.usePathname.call(void 0, );
207
211
  const [articles, setArticles] = _react.useState.call(void 0, []);
208
212
  _react.useEffect.call(void 0, () => {
209
213
  let active = true;
210
- _chunkFF4EIQ6Hjs.HowToService.findPublished().then((list) => active && setArticles(list)).catch(() => active && setArticles([]));
214
+ _chunkMOGEGWXWjs.HowToService.findPublished().then((list) => active && setArticles(list)).catch(() => active && setArticles([]));
211
215
  return () => {
212
216
  active = false;
213
217
  };
@@ -283,7 +287,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpSideNav, "HelpSideNav");
283
287
  function HelpArticleBody(props) {
284
288
  const t = _nextintl.useTranslations.call(void 0, );
285
289
  const format = _nextintl.useFormatter.call(void 0, );
286
- const generateUrl = _chunk6NZKWIORjs.usePageUrlGenerator.call(void 0, );
290
+ const generateUrl = _chunk2H342HNNjs.usePageUrlGenerator.call(void 0, );
287
291
  const { howToType, title, summary, updatedAt, prev, next, children } = props;
288
292
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "article", { className: "prose dark:prose-invert max-w-none", children: [
289
293
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { className: "text-muted-foreground mb-2 text-xs", children: [
@@ -340,7 +344,7 @@ function HelpTOC({ headings }) {
340
344
  }, [headings]);
341
345
  if (headings.length === 0) return null;
342
346
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "nav", { "aria-label": t("help.toc.title"), className: "hidden lg:block", children: [
343
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.MicroLabel, { className: "mb-2", children: t("help.toc.title") }),
347
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.MicroLabel, { className: "mb-2", children: t("help.toc.title") }),
344
348
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-1 text-sm", children: headings.map((h) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { style: { paddingInlineStart: `${(h.depth - 2) * 0.75}rem` }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
345
349
  "a",
346
350
  {
@@ -361,13 +365,13 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpTOC, "HelpTOC");
361
365
 
362
366
  function HelpHint({ contextKey }) {
363
367
  const t = _nextintl.useTranslations.call(void 0, );
364
- const generateUrl = _chunk6NZKWIORjs.usePageUrlGenerator.call(void 0, );
368
+ const generateUrl = _chunk2H342HNNjs.usePageUrlGenerator.call(void 0, );
365
369
  const [open, setOpen] = _react.useState.call(void 0, false);
366
370
  const [picked, setPicked] = _react.useState.call(void 0, null);
367
371
  const [articles, setArticles] = _react.useState.call(void 0, []);
368
372
  _react.useEffect.call(void 0, () => {
369
373
  let active2 = true;
370
- _chunkFF4EIQ6Hjs.HowToService.findPublished().then((list) => active2 && setArticles(list)).catch(() => active2 && setArticles([]));
374
+ _chunkMOGEGWXWjs.HowToService.findPublished().then((list) => active2 && setArticles(list)).catch(() => active2 && setArticles([]));
371
375
  return () => {
372
376
  active2 = false;
373
377
  };
@@ -379,7 +383,7 @@ function HelpHint({ contextKey }) {
379
383
  if (matches.length === 0) return null;
380
384
  const active = _nullishCoalesce(picked, () => ( (matches.length === 1 ? matches[0] : null)));
381
385
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
382
- _chunk6NZKWIORjs.Sheet,
386
+ _chunk2H342HNNjs.Sheet,
383
387
  {
384
388
  open,
385
389
  onOpenChange: (o) => {
@@ -387,11 +391,11 @@ function HelpHint({ contextKey }) {
387
391
  if (!o) setPicked(null);
388
392
  },
389
393
  children: [
390
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.SheetTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.Button, { variant: "ghost", size: "icon-sm", "aria-label": t("help.hint.trigger") }), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.HelpCircleIcon, { className: "h-4 w-4" }) }),
391
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.SheetContent, { side: "end", className: "w-full max-w-md sm:max-w-lg", children: [
392
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk6NZKWIORjs.SheetHeader, { children: [
393
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.SheetTitle, { children: active ? active.name : t("help.hint.pickArticle") }),
394
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.SheetDescription, { children: _nullishCoalesce(_optionalChain([active, 'optionalAccess', _4 => _4.summary]), () => ( "")) })
394
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.SheetTrigger, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.Button, { variant: "ghost", size: "icon-sm", "aria-label": t("help.hint.trigger") }), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.HelpCircleIcon, { className: "h-4 w-4" }) }),
395
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.SheetContent, { side: "end", className: "w-full max-w-md sm:max-w-lg", children: [
396
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk2H342HNNjs.SheetHeader, { children: [
397
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.SheetTitle, { children: active ? active.name : t("help.hint.pickArticle") }),
398
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.SheetDescription, { children: _nullishCoalesce(_optionalChain([active, 'optionalAccess', _4 => _4.summary]), () => ( "")) })
395
399
  ] }),
396
400
  active ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-4 space-y-3", children: [
397
401
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: active.summary }),
@@ -423,18 +427,18 @@ _chunk7QVYU63Ejs.__name.call(void 0, HelpHint, "HelpHint");
423
427
 
424
428
  function HelpSearchResultRow({ result, onSelect }) {
425
429
  const t = _nextintl.useTranslations.call(void 0, );
426
- const generateUrl = _chunk6NZKWIORjs.usePageUrlGenerator.call(void 0, );
430
+ const generateUrl = _chunk2H342HNNjs.usePageUrlGenerator.call(void 0, );
427
431
  const [article, setArticle] = _react.useState.call(void 0, null);
428
432
  _react.useEffect.call(void 0, () => {
429
433
  let active = true;
430
- _chunkFF4EIQ6Hjs.HowToService.findOne({ id: result.id }).then((a) => active && setArticle(a)).catch(() => active && setArticle(null));
434
+ _chunkMOGEGWXWjs.HowToService.findOne({ id: result.id }).then((a) => active && setArticle(a)).catch(() => active && setArticle(null));
431
435
  return () => {
432
436
  active = false;
433
437
  };
434
438
  }, [result.id]);
435
439
  if (!article) {
436
440
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
437
- _chunk6NZKWIORjs.CommandItem,
441
+ _chunk2H342HNNjs.CommandItem,
438
442
  {
439
443
  value: result.id,
440
444
  disabled: true,
@@ -443,7 +447,7 @@ function HelpSearchResultRow({ result, onSelect }) {
443
447
  }
444
448
  );
445
449
  }
446
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk6NZKWIORjs.CommandItem, { value: result.id, onSelect, className: "cursor-pointer p-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
450
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk2H342HNNjs.CommandItem, { value: result.id, onSelect, className: "cursor-pointer p-0", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
447
451
  _link2.default,
448
452
  {
449
453
  href: generateUrl({ page: `/help/${article.howToType}/${article.slug}` }),