@lupinum/ginko-content 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/compatibility.json +27 -0
  4. package/dist/cli.d.mts +1 -0
  5. package/dist/cli.mjs +690 -0
  6. package/dist/cms-contract/build +1 -0
  7. package/dist/cms-contract/build.d.ts +44 -0
  8. package/dist/cms-contract/build.js +513 -0
  9. package/dist/cms-contract/index +1 -0
  10. package/dist/cms-contract/index.d.ts +25 -0
  11. package/dist/cms-contract/index.js +37 -0
  12. package/dist/cms-contract/mdc +1 -0
  13. package/dist/cms-contract/mdc.d.ts +32 -0
  14. package/dist/cms-contract/mdc.js +52 -0
  15. package/dist/cms-contract/path +1 -0
  16. package/dist/cms-contract/path.d.ts +12 -0
  17. package/dist/cms-contract/path.js +18 -0
  18. package/dist/cms-contract/schema +1 -0
  19. package/dist/cms-contract/schema.d.ts +18 -0
  20. package/dist/cms-contract/schema.js +13 -0
  21. package/dist/cms-contract/types +1 -0
  22. package/dist/cms-contract/types.d.ts +177 -0
  23. package/dist/cms-contract/types.js +0 -0
  24. package/dist/cms-import/index +1 -0
  25. package/dist/cms-import/index.d.ts +21 -0
  26. package/dist/cms-import/index.js +57 -0
  27. package/dist/config.d.mts +3 -0
  28. package/dist/config.mjs +3 -0
  29. package/dist/core/cache +1 -0
  30. package/dist/core/cache-hints +1 -0
  31. package/dist/core/cache-hints.d.ts +3 -0
  32. package/dist/core/cache-hints.js +55 -0
  33. package/dist/core/cache.d.ts +29 -0
  34. package/dist/core/cache.js +0 -0
  35. package/dist/core/content/collection +1 -0
  36. package/dist/core/content/collection.d.ts +3 -0
  37. package/dist/core/content/collection.js +52 -0
  38. package/dist/core/content/graph +1 -0
  39. package/dist/core/content/graph.d.ts +147 -0
  40. package/dist/core/content/graph.js +189 -0
  41. package/dist/core/content/ignore +1 -0
  42. package/dist/core/content/ignore.d.ts +5 -0
  43. package/dist/core/content/ignore.js +10 -0
  44. package/dist/core/content/locale +1 -0
  45. package/dist/core/content/locale.d.ts +61 -0
  46. package/dist/core/content/locale.js +77 -0
  47. package/dist/core/content/path +1 -0
  48. package/dist/core/content/path.d.ts +36 -0
  49. package/dist/core/content/path.js +143 -0
  50. package/dist/core/content/slug +1 -0
  51. package/dist/core/content/slug.d.ts +4 -0
  52. package/dist/core/content/slug.js +41 -0
  53. package/dist/core/content/sources +1 -0
  54. package/dist/core/content/sources.d.ts +2 -0
  55. package/dist/core/content/sources.js +6 -0
  56. package/dist/core/errors +1 -0
  57. package/dist/core/errors.d.ts +15 -0
  58. package/dist/core/errors.js +10 -0
  59. package/dist/core/markdown/tree +1 -0
  60. package/dist/core/markdown/tree.d.ts +9 -0
  61. package/dist/core/markdown/tree.js +47 -0
  62. package/dist/core/query/builder +1 -0
  63. package/dist/core/query/builder.d.ts +18 -0
  64. package/dist/core/query/builder.js +186 -0
  65. package/dist/core/query/execute +1 -0
  66. package/dist/core/query/execute.d.ts +52 -0
  67. package/dist/core/query/execute.js +304 -0
  68. package/dist/core/query/filter +1 -0
  69. package/dist/core/query/filter.d.ts +42 -0
  70. package/dist/core/query/filter.js +118 -0
  71. package/dist/core/query/json +1 -0
  72. package/dist/core/query/json.d.ts +2 -0
  73. package/dist/core/query/json.js +20 -0
  74. package/dist/core/query/lower +1 -0
  75. package/dist/core/query/lower.d.ts +14 -0
  76. package/dist/core/query/lower.js +121 -0
  77. package/dist/core/query/operators +1 -0
  78. package/dist/core/query/operators.d.ts +23 -0
  79. package/dist/core/query/operators.js +126 -0
  80. package/dist/core/query/params +1 -0
  81. package/dist/core/query/params.d.ts +15 -0
  82. package/dist/core/query/params.js +83 -0
  83. package/dist/core/query/plan +1 -0
  84. package/dist/core/query/plan.d.ts +110 -0
  85. package/dist/core/query/plan.js +0 -0
  86. package/dist/core/references/resolve +1 -0
  87. package/dist/core/references/resolve.d.ts +31 -0
  88. package/dist/core/references/resolve.js +121 -0
  89. package/dist/core/references/schema +1 -0
  90. package/dist/core/references/schema.d.ts +8 -0
  91. package/dist/core/references/schema.js +70 -0
  92. package/dist/core/result +1 -0
  93. package/dist/core/result.d.ts +27 -0
  94. package/dist/core/result.js +2 -0
  95. package/dist/features/collections/resolve +1 -0
  96. package/dist/features/collections/resolve.d.ts +63 -0
  97. package/dist/features/collections/resolve.js +76 -0
  98. package/dist/features/localization/config +1 -0
  99. package/dist/features/localization/config.d.ts +18 -0
  100. package/dist/features/localization/config.js +25 -0
  101. package/dist/features/localization/links +1 -0
  102. package/dist/features/localization/links.d.ts +1 -0
  103. package/dist/features/localization/links.js +69 -0
  104. package/dist/features/localization/path +1 -0
  105. package/dist/features/localization/path.d.ts +32 -0
  106. package/dist/features/localization/path.js +80 -0
  107. package/dist/features/localization/results +1 -0
  108. package/dist/features/localization/results.d.ts +42 -0
  109. package/dist/features/localization/results.js +149 -0
  110. package/dist/features/localization/translated-slugs +1 -0
  111. package/dist/features/localization/translated-slugs.d.ts +11 -0
  112. package/dist/features/localization/translated-slugs.js +80 -0
  113. package/dist/features/navigation/build +1 -0
  114. package/dist/features/navigation/build.d.ts +28 -0
  115. package/dist/features/navigation/build.js +104 -0
  116. package/dist/features/navigation/canonical +1 -0
  117. package/dist/features/navigation/canonical.d.ts +33 -0
  118. package/dist/features/navigation/canonical.js +149 -0
  119. package/dist/features/navigation/query +1 -0
  120. package/dist/features/navigation/query.d.ts +19 -0
  121. package/dist/features/navigation/query.js +51 -0
  122. package/dist/features/navigation/resolve +1 -0
  123. package/dist/features/navigation/resolve.d.ts +20 -0
  124. package/dist/features/navigation/resolve.js +79 -0
  125. package/dist/features/navigation/tree +1 -0
  126. package/dist/features/navigation/tree.d.ts +6 -0
  127. package/dist/features/navigation/tree.js +32 -0
  128. package/dist/features/search/navigation +1 -0
  129. package/dist/features/search/navigation.d.ts +6 -0
  130. package/dist/features/search/navigation.js +21 -0
  131. package/dist/features/search/sections +1 -0
  132. package/dist/features/search/sections.d.ts +21 -0
  133. package/dist/features/search/sections.js +98 -0
  134. package/dist/features/sitemap/query +1 -0
  135. package/dist/features/sitemap/query.d.ts +68 -0
  136. package/dist/features/sitemap/query.js +171 -0
  137. package/dist/integrations/nitro/context +1 -0
  138. package/dist/integrations/nitro/context.d.ts +63 -0
  139. package/dist/integrations/nitro/context.js +28 -0
  140. package/dist/integrations/nitro/ingest +1 -0
  141. package/dist/integrations/nitro/ingest.d.ts +18 -0
  142. package/dist/integrations/nitro/ingest.js +120 -0
  143. package/dist/integrations/nitro/preview +1 -0
  144. package/dist/integrations/nitro/preview.d.ts +5 -0
  145. package/dist/integrations/nitro/preview.js +21 -0
  146. package/dist/integrations/nitro/runtime-config +1 -0
  147. package/dist/integrations/nitro/runtime-config.d.ts +1 -0
  148. package/dist/integrations/nitro/runtime-config.js +4 -0
  149. package/dist/integrations/nitro/storage +1 -0
  150. package/dist/integrations/nitro/storage.d.ts +9 -0
  151. package/dist/integrations/nitro/storage.js +113 -0
  152. package/dist/integrations/vue/content-components +1 -0
  153. package/dist/integrations/vue/content-components.d.ts +24 -0
  154. package/dist/integrations/vue/content-components.js +67 -0
  155. package/dist/integrations/vue/html-tags +1 -0
  156. package/dist/integrations/vue/html-tags.d.ts +2 -0
  157. package/dist/integrations/vue/html-tags.js +119 -0
  158. package/dist/integrations/vue/markdown-refs +1 -0
  159. package/dist/integrations/vue/markdown-refs.d.ts +1 -0
  160. package/dist/integrations/vue/markdown-refs.js +1 -0
  161. package/dist/module.d.mts +2044 -0
  162. package/dist/module.json +12 -0
  163. package/dist/module.mjs +1381 -0
  164. package/dist/parsers/csv +1 -0
  165. package/dist/parsers/csv.d.ts +2 -0
  166. package/dist/parsers/csv.js +38 -0
  167. package/dist/parsers/from-csv +1 -0
  168. package/dist/parsers/from-csv.d.ts +20 -0
  169. package/dist/parsers/from-csv.js +85 -0
  170. package/dist/parsers/index +1 -0
  171. package/dist/parsers/index.d.ts +10 -0
  172. package/dist/parsers/index.js +50 -0
  173. package/dist/parsers/json +1 -0
  174. package/dist/parsers/json.d.ts +2 -0
  175. package/dist/parsers/json.js +29 -0
  176. package/dist/parsers/markdown +1 -0
  177. package/dist/parsers/markdown-plugins +1 -0
  178. package/dist/parsers/markdown-plugins.d.ts +3 -0
  179. package/dist/parsers/markdown-plugins.js +58 -0
  180. package/dist/parsers/markdown.d.ts +2 -0
  181. package/dist/parsers/markdown.js +64 -0
  182. package/dist/parsers/path-meta +1 -0
  183. package/dist/parsers/path-meta.d.ts +4 -0
  184. package/dist/parsers/path-meta.js +37 -0
  185. package/dist/parsers/utils +1 -0
  186. package/dist/parsers/utils.d.ts +2 -0
  187. package/dist/parsers/utils.js +3 -0
  188. package/dist/parsers/yaml +1 -0
  189. package/dist/parsers/yaml.d.ts +2 -0
  190. package/dist/parsers/yaml.js +19 -0
  191. package/dist/public/client +1 -0
  192. package/dist/public/client.d.ts +19 -0
  193. package/dist/public/client.js +26 -0
  194. package/dist/public/provider +1 -0
  195. package/dist/public/provider-errors +1 -0
  196. package/dist/public/provider-errors.d.ts +4 -0
  197. package/dist/public/provider-errors.js +28 -0
  198. package/dist/public/provider.d.ts +74 -0
  199. package/dist/public/provider.js +6 -0
  200. package/dist/public/server +1 -0
  201. package/dist/public/server.d.ts +19 -0
  202. package/dist/public/server.js +28 -0
  203. package/dist/runtime/app/components/ContentRenderer.d.vue.ts +62 -0
  204. package/dist/runtime/app/components/ContentRenderer.vue +84 -0
  205. package/dist/runtime/app/components/ContentRenderer.vue.d.ts +62 -0
  206. package/dist/runtime/app/components/ContentRendererInline.d.vue.ts +50 -0
  207. package/dist/runtime/app/components/ContentRendererInline.vue +97 -0
  208. package/dist/runtime/app/components/ContentRendererInline.vue.d.ts +50 -0
  209. package/dist/runtime/app/components/Prose/ProseCode.d.vue.ts +61 -0
  210. package/dist/runtime/app/components/Prose/ProseCode.vue +32 -0
  211. package/dist/runtime/app/components/Prose/ProseCode.vue.d.ts +61 -0
  212. package/dist/runtime/app/components/Prose/ProseCodeInline.d.vue.ts +13 -0
  213. package/dist/runtime/app/components/Prose/ProseCodeInline.vue +3 -0
  214. package/dist/runtime/app/components/Prose/ProseCodeInline.vue.d.ts +13 -0
  215. package/dist/runtime/app/components/Prose/ProseImg.d.vue.ts +59 -0
  216. package/dist/runtime/app/components/Prose/ProseImg.vue +59 -0
  217. package/dist/runtime/app/components/Prose/ProseImg.vue.d.ts +59 -0
  218. package/dist/runtime/app/components/Prose/ProsePre.d.vue.ts +79 -0
  219. package/dist/runtime/app/components/Prose/ProsePre.vue +42 -0
  220. package/dist/runtime/app/components/Prose/ProsePre.vue.d.ts +79 -0
  221. package/dist/runtime/app/components/internal/ContentRendererMarkdown.d.vue.ts +68 -0
  222. package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue +99 -0
  223. package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue.d.ts +68 -0
  224. package/dist/runtime/app/components/internal/MarkdownRenderer +1 -0
  225. package/dist/runtime/app/components/internal/MarkdownRenderer.d.ts +90 -0
  226. package/dist/runtime/app/components/internal/MarkdownRenderer.js +191 -0
  227. package/dist/runtime/app/composables/async-data +1 -0
  228. package/dist/runtime/app/composables/async-data.d.ts +2 -0
  229. package/dist/runtime/app/composables/async-data.js +4 -0
  230. package/dist/runtime/app/composables/content-i18n +1 -0
  231. package/dist/runtime/app/composables/content-i18n.d.ts +5 -0
  232. package/dist/runtime/app/composables/content-i18n.js +1 -0
  233. package/dist/runtime/app/composables/head +1 -0
  234. package/dist/runtime/app/composables/head.d.ts +11 -0
  235. package/dist/runtime/app/composables/head.js +98 -0
  236. package/dist/runtime/app/composables/locale +1 -0
  237. package/dist/runtime/app/composables/locale-context +1 -0
  238. package/dist/runtime/app/composables/locale-context.d.ts +5 -0
  239. package/dist/runtime/app/composables/locale-context.js +8 -0
  240. package/dist/runtime/app/composables/locale.d.ts +8 -0
  241. package/dist/runtime/app/composables/locale.js +15 -0
  242. package/dist/runtime/app/composables/navigation +1 -0
  243. package/dist/runtime/app/composables/navigation.d.ts +3 -0
  244. package/dist/runtime/app/composables/navigation.js +7 -0
  245. package/dist/runtime/app/composables/preview +1 -0
  246. package/dist/runtime/app/composables/preview.d.ts +5 -0
  247. package/dist/runtime/app/composables/preview.js +52 -0
  248. package/dist/runtime/app/composables/query-api +1 -0
  249. package/dist/runtime/app/composables/query-api.d.ts +27 -0
  250. package/dist/runtime/app/composables/query-api.js +46 -0
  251. package/dist/runtime/app/composables/route +1 -0
  252. package/dist/runtime/app/composables/route.d.ts +11 -0
  253. package/dist/runtime/app/composables/route.js +150 -0
  254. package/dist/runtime/app/composables/runtime +1 -0
  255. package/dist/runtime/app/composables/runtime.d.ts +2 -0
  256. package/dist/runtime/app/composables/runtime.js +7 -0
  257. package/dist/runtime/app/composables/search +1 -0
  258. package/dist/runtime/app/composables/search.d.ts +58 -0
  259. package/dist/runtime/app/composables/search.js +321 -0
  260. package/dist/runtime/app/composables/site-data +1 -0
  261. package/dist/runtime/app/composables/site-data.d.ts +12 -0
  262. package/dist/runtime/app/composables/site-data.js +12 -0
  263. package/dist/runtime/app/composables/toc +1 -0
  264. package/dist/runtime/app/composables/toc.d.ts +10 -0
  265. package/dist/runtime/app/composables/toc.js +31 -0
  266. package/dist/runtime/app/composables/use-content +1 -0
  267. package/dist/runtime/app/composables/use-content.d.ts +188 -0
  268. package/dist/runtime/app/composables/use-content.js +307 -0
  269. package/dist/runtime/app/composables/useUnwrap +1 -0
  270. package/dist/runtime/app/composables/useUnwrap.d.ts +8 -0
  271. package/dist/runtime/app/composables/useUnwrap.js +35 -0
  272. package/dist/runtime/app/composables/utils +1 -0
  273. package/dist/runtime/app/composables/utils.d.ts +22 -0
  274. package/dist/runtime/app/composables/utils.js +76 -0
  275. package/dist/runtime/app/composables/web-socket +1 -0
  276. package/dist/runtime/app/composables/web-socket.d.ts +3 -0
  277. package/dist/runtime/app/composables/web-socket.js +65 -0
  278. package/dist/runtime/app/pages/content.d.vue.ts +3 -0
  279. package/dist/runtime/app/pages/content.vue +14 -0
  280. package/dist/runtime/app/pages/content.vue.d.ts +3 -0
  281. package/dist/runtime/app/plugins/markdown-components +1 -0
  282. package/dist/runtime/app/plugins/markdown-components.d.ts +2 -0
  283. package/dist/runtime/app/plugins/markdown-components.js +19 -0
  284. package/dist/runtime/app/plugins/ws +1 -0
  285. package/dist/runtime/app/plugins/ws.d.ts +2 -0
  286. package/dist/runtime/app/plugins/ws.js +7 -0
  287. package/dist/runtime/app.d.vue.ts +3 -0
  288. package/dist/runtime/app.vue +3 -0
  289. package/dist/runtime/app.vue.d.ts +3 -0
  290. package/dist/runtime/markdown/plugins +1 -0
  291. package/dist/runtime/markdown/plugins.d.ts +3 -0
  292. package/dist/runtime/markdown/plugins.js +39 -0
  293. package/dist/runtime/query/public-limits +1 -0
  294. package/dist/runtime/query/public-limits.d.ts +2 -0
  295. package/dist/runtime/query/public-limits.js +2 -0
  296. package/dist/runtime/query/resolve +1 -0
  297. package/dist/runtime/query/resolve.d.ts +5 -0
  298. package/dist/runtime/query/resolve.js +9 -0
  299. package/dist/runtime/query/routes +1 -0
  300. package/dist/runtime/query/routes.d.ts +33 -0
  301. package/dist/runtime/query/routes.js +21 -0
  302. package/dist/runtime/query/unified +1 -0
  303. package/dist/runtime/query/unified.d.ts +94 -0
  304. package/dist/runtime/query/unified.js +473 -0
  305. package/dist/runtime/server/api/cache +1 -0
  306. package/dist/runtime/server/api/cache.d.ts +8 -0
  307. package/dist/runtime/server/api/cache.js +26 -0
  308. package/dist/runtime/server/api/locales +1 -0
  309. package/dist/runtime/server/api/locales.d.ts +6 -0
  310. package/dist/runtime/server/api/locales.js +28 -0
  311. package/dist/runtime/server/api/navigation +1 -0
  312. package/dist/runtime/server/api/navigation.d.ts +2 -0
  313. package/dist/runtime/server/api/navigation.js +21 -0
  314. package/dist/runtime/server/api/query +1 -0
  315. package/dist/runtime/server/api/query.d.ts +2 -0
  316. package/dist/runtime/server/api/query.js +6 -0
  317. package/dist/runtime/server/api/revalidate +1 -0
  318. package/dist/runtime/server/api/revalidate.d.ts +6 -0
  319. package/dist/runtime/server/api/revalidate.js +156 -0
  320. package/dist/runtime/server/api/search +1 -0
  321. package/dist/runtime/server/api/search-index +1 -0
  322. package/dist/runtime/server/api/search-index.d.ts +2 -0
  323. package/dist/runtime/server/api/search-index.js +20 -0
  324. package/dist/runtime/server/api/search.d.ts +2 -0
  325. package/dist/runtime/server/api/search.js +40 -0
  326. package/dist/runtime/server/api/site-data +1 -0
  327. package/dist/runtime/server/api/site-data.d.ts +2 -0
  328. package/dist/runtime/server/api/site-data.js +22 -0
  329. package/dist/runtime/server/api/sitemap +1 -0
  330. package/dist/runtime/server/api/sitemap.d.ts +2 -0
  331. package/dist/runtime/server/api/sitemap.js +11 -0
  332. package/dist/runtime/server/cache-adapter +1 -0
  333. package/dist/runtime/server/cache-adapter.d.ts +2 -0
  334. package/dist/runtime/server/cache-adapter.js +11 -0
  335. package/dist/runtime/server/cache-adapters +1 -0
  336. package/dist/runtime/server/cache-adapters.d.ts +9 -0
  337. package/dist/runtime/server/cache-adapters.js +50 -0
  338. package/dist/runtime/server/cache-hints +1 -0
  339. package/dist/runtime/server/cache-hints.d.ts +5 -0
  340. package/dist/runtime/server/cache-hints.js +17 -0
  341. package/dist/runtime/server/collection-helpers +1 -0
  342. package/dist/runtime/server/collection-helpers.d.ts +13 -0
  343. package/dist/runtime/server/collection-helpers.js +99 -0
  344. package/dist/runtime/server/index +1 -0
  345. package/dist/runtime/server/index.d.ts +9 -0
  346. package/dist/runtime/server/index.js +15 -0
  347. package/dist/runtime/server/manifest +1 -0
  348. package/dist/runtime/server/manifest.d.ts +1 -0
  349. package/dist/runtime/server/manifest.js +1 -0
  350. package/dist/runtime/server/navigation +1 -0
  351. package/dist/runtime/server/navigation-query +1 -0
  352. package/dist/runtime/server/navigation-query.d.ts +4 -0
  353. package/dist/runtime/server/navigation-query.js +80 -0
  354. package/dist/runtime/server/navigation.d.ts +2 -0
  355. package/dist/runtime/server/navigation.js +9 -0
  356. package/dist/runtime/server/pagefind +1 -0
  357. package/dist/runtime/server/pagefind.d.ts +2 -0
  358. package/dist/runtime/server/pagefind.js +30 -0
  359. package/dist/runtime/server/plugins/cache +1 -0
  360. package/dist/runtime/server/plugins/cache.d.ts +2 -0
  361. package/dist/runtime/server/plugins/cache.js +17 -0
  362. package/dist/runtime/server/plugins/sitemap +1 -0
  363. package/dist/runtime/server/plugins/sitemap.d.ts +2 -0
  364. package/dist/runtime/server/plugins/sitemap.js +25 -0
  365. package/dist/runtime/server/preview +1 -0
  366. package/dist/runtime/server/preview.d.ts +1 -0
  367. package/dist/runtime/server/preview.js +1 -0
  368. package/dist/runtime/server/provider-query +1 -0
  369. package/dist/runtime/server/provider-query.d.ts +27 -0
  370. package/dist/runtime/server/provider-query.js +131 -0
  371. package/dist/runtime/server/provider-result +1 -0
  372. package/dist/runtime/server/provider-result.d.ts +10 -0
  373. package/dist/runtime/server/provider-result.js +30 -0
  374. package/dist/runtime/server/providers/filesystem +1 -0
  375. package/dist/runtime/server/providers/filesystem.d.ts +2 -0
  376. package/dist/runtime/server/providers/filesystem.js +47 -0
  377. package/dist/runtime/server/providers/index +1 -0
  378. package/dist/runtime/server/providers/index.d.ts +3 -0
  379. package/dist/runtime/server/providers/index.js +190 -0
  380. package/dist/runtime/server/query-api +1 -0
  381. package/dist/runtime/server/query-api.d.ts +28 -0
  382. package/dist/runtime/server/query-api.js +54 -0
  383. package/dist/runtime/server/query-executor +1 -0
  384. package/dist/runtime/server/query-executor.d.ts +4 -0
  385. package/dist/runtime/server/query-executor.js +121 -0
  386. package/dist/runtime/server/runtime-config +1 -0
  387. package/dist/runtime/server/runtime-config.d.ts +1 -0
  388. package/dist/runtime/server/runtime-config.js +1 -0
  389. package/dist/runtime/server/search +1 -0
  390. package/dist/runtime/server/search.d.ts +18 -0
  391. package/dist/runtime/server/search.js +134 -0
  392. package/dist/runtime/server/sitemap +1 -0
  393. package/dist/runtime/server/sitemap-provider +1 -0
  394. package/dist/runtime/server/sitemap-provider.d.ts +10 -0
  395. package/dist/runtime/server/sitemap-provider.js +11 -0
  396. package/dist/runtime/server/sitemap.d.ts +6 -0
  397. package/dist/runtime/server/sitemap.js +45 -0
  398. package/dist/runtime/server/storage +1 -0
  399. package/dist/runtime/server/storage-access +1 -0
  400. package/dist/runtime/server/storage-access.d.ts +1 -0
  401. package/dist/runtime/server/storage-access.js +9 -0
  402. package/dist/runtime/server/storage.d.ts +2 -0
  403. package/dist/runtime/server/storage.js +2 -0
  404. package/dist/runtime/server/validation +1 -0
  405. package/dist/runtime/server/validation.d.ts +1 -0
  406. package/dist/runtime/server/validation.js +6 -0
  407. package/dist/runtime/shared/search +1 -0
  408. package/dist/runtime/shared/search.d.ts +2 -0
  409. package/dist/runtime/shared/search.js +89 -0
  410. package/dist/runtime/transformers/component-resolver +1 -0
  411. package/dist/runtime/transformers/component-resolver.d.ts +10 -0
  412. package/dist/runtime/transformers/component-resolver.js +30 -0
  413. package/dist/runtime/transformers/csv/from-csv +1 -0
  414. package/dist/runtime/transformers/csv/from-csv.d.ts +1 -0
  415. package/dist/runtime/transformers/csv/from-csv.js +1 -0
  416. package/dist/runtime/transformers/csv/index +1 -0
  417. package/dist/runtime/transformers/csv/index.d.ts +1 -0
  418. package/dist/runtime/transformers/csv/index.js +1 -0
  419. package/dist/runtime/transformers/define +1 -0
  420. package/dist/runtime/transformers/define.d.ts +1 -0
  421. package/dist/runtime/transformers/define.js +1 -0
  422. package/dist/runtime/transformers/index +1 -0
  423. package/dist/runtime/transformers/index.d.ts +1 -0
  424. package/dist/runtime/transformers/index.js +1 -0
  425. package/dist/runtime/transformers/json +1 -0
  426. package/dist/runtime/transformers/json.d.ts +1 -0
  427. package/dist/runtime/transformers/json.js +1 -0
  428. package/dist/runtime/transformers/markdown +1 -0
  429. package/dist/runtime/transformers/markdown.d.ts +1 -0
  430. package/dist/runtime/transformers/markdown.js +1 -0
  431. package/dist/runtime/transformers/path-meta +1 -0
  432. package/dist/runtime/transformers/path-meta.d.ts +2 -0
  433. package/dist/runtime/transformers/path-meta.js +2 -0
  434. package/dist/runtime/transformers/utils +1 -0
  435. package/dist/runtime/transformers/utils.d.ts +1 -0
  436. package/dist/runtime/transformers/utils.js +1 -0
  437. package/dist/runtime/transformers/yaml +1 -0
  438. package/dist/runtime/transformers/yaml.d.ts +1 -0
  439. package/dist/runtime/transformers/yaml.js +1 -0
  440. package/dist/runtime/utils/content-components +1 -0
  441. package/dist/runtime/utils/content-components.d.ts +9 -0
  442. package/dist/runtime/utils/content-components.js +16 -0
  443. package/dist/runtime/utils/query +1 -0
  444. package/dist/runtime/utils/query.d.ts +5 -0
  445. package/dist/runtime/utils/query.js +18 -0
  446. package/dist/runtime/virtual/transformers.d.ts +4 -0
  447. package/dist/runtime/virtual.d.ts +7 -0
  448. package/dist/storage/cache +1 -0
  449. package/dist/storage/cache.d.ts +32 -0
  450. package/dist/storage/cache.js +42 -0
  451. package/dist/storage/content +1 -0
  452. package/dist/storage/content.d.ts +41 -0
  453. package/dist/storage/content.js +86 -0
  454. package/dist/storage/contents +1 -0
  455. package/dist/storage/contents.d.ts +5 -0
  456. package/dist/storage/contents.js +116 -0
  457. package/dist/storage/driver +1 -0
  458. package/dist/storage/driver.d.ts +28 -0
  459. package/dist/storage/driver.js +22 -0
  460. package/dist/storage/graph +1 -0
  461. package/dist/storage/graph.d.ts +3 -0
  462. package/dist/storage/graph.js +14 -0
  463. package/dist/storage/manifest +1 -0
  464. package/dist/storage/manifest.d.ts +18 -0
  465. package/dist/storage/manifest.js +68 -0
  466. package/dist/storage/references +1 -0
  467. package/dist/storage/references.d.ts +13 -0
  468. package/dist/storage/references.js +78 -0
  469. package/dist/storage/validation +1 -0
  470. package/dist/storage/validation.d.ts +46 -0
  471. package/dist/storage/validation.js +341 -0
  472. package/dist/testing/provider-contract +1 -0
  473. package/dist/testing/provider-contract.d.ts +31 -0
  474. package/dist/testing/provider-contract.js +237 -0
  475. package/dist/testing/provider-fixture +1 -0
  476. package/dist/testing/provider-fixture.d.ts +65 -0
  477. package/dist/testing/provider-fixture.js +606 -0
  478. package/dist/types/api +1 -0
  479. package/dist/types/api.d.ts +47 -0
  480. package/dist/types/api.js +1 -0
  481. package/dist/types/config +1 -0
  482. package/dist/types/config.d.ts +281 -0
  483. package/dist/types/config.js +28 -0
  484. package/dist/types/content +1 -0
  485. package/dist/types/content.d.ts +311 -0
  486. package/dist/types/content.js +1 -0
  487. package/dist/types/fields +1 -0
  488. package/dist/types/fields.d.ts +81 -0
  489. package/dist/types/fields.js +146 -0
  490. package/dist/types/index +1 -0
  491. package/dist/types/index.d.ts +6 -0
  492. package/dist/types/index.js +6 -0
  493. package/dist/types/module +1 -0
  494. package/dist/types/module.d.ts +428 -0
  495. package/dist/types/module.js +0 -0
  496. package/dist/types/picomatch.d.ts +8 -0
  497. package/dist/types/query +1 -0
  498. package/dist/types/query.d.ts +862 -0
  499. package/dist/types/query.js +1 -0
  500. package/dist/types/reference +1 -0
  501. package/dist/types/reference.d.ts +1 -0
  502. package/dist/types/reference.js +1 -0
  503. package/dist/types/runtime +1 -0
  504. package/dist/types/runtime.d.ts +45 -0
  505. package/dist/types/runtime.js +1 -0
  506. package/dist/types/search +1 -0
  507. package/dist/types/search.d.ts +64 -0
  508. package/dist/types/search.js +0 -0
  509. package/dist/types/virtual.d.ts +19 -0
  510. package/dist/types.d.mts +11 -0
  511. package/dist/web-types.json +466 -0
  512. package/package.json +135 -0
@@ -0,0 +1,1381 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { join as join$1, basename, resolve as resolve$1, relative as relative$1, dirname } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { addTypeTemplate, addImports, addServerImports, addComponentsDir, addPlugin, addServerHandler, defineNuxtModule, createResolver, useLogger, addTemplate } from '@nuxt/kit';
5
+ import { defu } from 'defu';
6
+ import { hash } from 'ohash';
7
+ import { resolve, join, relative, isAbsolute } from 'pathe';
8
+ import { withTrailingSlash } from 'ufo';
9
+ import 'unstorage/drivers/fs';
10
+ import 'unstorage/drivers/http';
11
+ import 'unstorage/drivers/github';
12
+ import { WebSocketServer } from 'ws';
13
+ import { consola } from 'consola';
14
+ import fs, { existsSync } from 'fs';
15
+ import jiti from 'jiti';
16
+ import { createRequire } from 'node:module';
17
+ import { genSafeVariableName, genImport } from 'knitwork';
18
+ import { listen } from 'listhen';
19
+ import { makeIgnored } from '../dist/core/content/ignore';
20
+ import { readFile, readdir } from 'node:fs/promises';
21
+ import { resolveCollectionI18nConfig } from '../dist/features/localization/config';
22
+ import { globby } from 'globby';
23
+ import { transformContent } from '../dist/parsers/index';
24
+ import { expandDataLocaleVariants } from '../dist/core/content/locale';
25
+ import { buildContentGraph } from '../dist/core/content/graph';
26
+ import { normalizeCollectionSources, normalizeCollectionExcludes } from '../dist/core/content/sources';
27
+ import { resolveCollectionI18n, prefixPathWithLocale } from '../dist/features/localization/path';
28
+ import { resolveCollection } from '../dist/core/content/collection';
29
+ export { defineCollection, defineContentConfig, reference } from '../dist/types/config';
30
+
31
+ const name = "@lupinum/ginko-content";
32
+ const version = "0.1.0";
33
+
34
+ const logger = consola.withTag("@lupinum/ginko-content");
35
+ const CACHE_VERSION = 3;
36
+ const MOUNT_PREFIX = "content:source:";
37
+ function useContentMounts(nuxt, storages) {
38
+ const key = (path, prefix = "") => `${MOUNT_PREFIX}${path.replace(/[/:]/g, "_")}${prefix.replace(/\//g, ":")}`;
39
+ const baseDir = nuxt.options.future?.compatibilityVersion === 4 ? nuxt.options.rootDir : nuxt.options.srcDir;
40
+ storages = Object.entries(storages).reduce((mounts, [name, storage]) => {
41
+ mounts[key(storage.name || name, storage.prefix)] = storage;
42
+ return mounts;
43
+ }, {});
44
+ const defaultStorage = key("content");
45
+ if (!storages[defaultStorage]) {
46
+ storages[defaultStorage] = {
47
+ name: defaultStorage,
48
+ driver: "fs",
49
+ base: resolve(baseDir, "content")
50
+ };
51
+ }
52
+ return storages;
53
+ }
54
+ function createWebSocket() {
55
+ const wss = new WebSocketServer({ noServer: true });
56
+ const serve = (req, socket = req.socket, head = "") => wss.handleUpgrade(req, socket, head, (client) => wss.emit("connection", client, req));
57
+ const broadcast = (data) => {
58
+ data = JSON.stringify(data);
59
+ for (const client of wss.clients) {
60
+ try {
61
+ client.send(data);
62
+ } catch {
63
+ logger.debug("Skipping websocket client that is not ready to receive content refresh events.");
64
+ }
65
+ }
66
+ };
67
+ return {
68
+ serve,
69
+ broadcast,
70
+ close: () => {
71
+ wss.clients.forEach((client) => client.close());
72
+ return new Promise((resolve2) => wss.close(resolve2));
73
+ }
74
+ };
75
+ }
76
+ function processMarkdownOptions(options) {
77
+ const anchorLinks = typeof options.anchorLinks === "boolean" ? { depth: options.anchorLinks ? 6 : 0, exclude: [] } : { depth: 4, exclude: [1], ...options.anchorLinks };
78
+ const plugins = options.plugins?.length ? options.plugins : [
79
+ ["toc", { depth: 2, searchDepth: 2 }],
80
+ "summary"
81
+ ];
82
+ return {
83
+ ...options,
84
+ anchorLinks,
85
+ plugins: resolveMarkdownPlugins(plugins)
86
+ };
87
+ }
88
+ function resolveMarkdownPlugins(plugins) {
89
+ return (plugins || []).map((plugin) => {
90
+ const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}];
91
+ return {
92
+ name,
93
+ options
94
+ };
95
+ });
96
+ }
97
+
98
+ const CONFIG_FILES = [
99
+ "content.config.ts",
100
+ "content.config.mts",
101
+ "content.config.js",
102
+ "content.config.mjs",
103
+ "content.config.cjs"
104
+ ];
105
+ function resolveContentConfigPath(nuxt) {
106
+ return CONFIG_FILES.map((name) => join(nuxt.options.rootDir, name)).find((path) => existsSync(path));
107
+ }
108
+ async function loadContentConfig(nuxt) {
109
+ const configPath = resolveContentConfigPath(nuxt);
110
+ if (!configPath) {
111
+ return {};
112
+ }
113
+ const importer = jiti(nuxt.options.rootDir, { interopDefault: true });
114
+ const loaded = await importer.import(configPath);
115
+ return loaded?.default || loaded || {};
116
+ }
117
+
118
+ const require$1 = createRequire(import.meta.url);
119
+ const jitiImportSpecifier = pathToFileURL(require$1.resolve("jiti")).href;
120
+ const createVirtualContentTemplates = (contentContext, nuxt, contentConfigPath, addTemplateImpl) => {
121
+ const transformersTemplate = addTemplateImpl({
122
+ filename: "content/virtual-transformers.mjs",
123
+ write: true,
124
+ getContents: () => {
125
+ const transformers = contentContext.transformers.map((transformer) => {
126
+ const name = genSafeVariableName(relative(nuxt.options.rootDir, transformer)).replace(/_(45|46|47)/g, "_") + "_" + hash(transformer);
127
+ return { name, import: genImport(transformer, name) };
128
+ });
129
+ return [
130
+ ...transformers.map((transformer) => transformer.import),
131
+ `export const transformers = [${transformers.map((transformer) => transformer.name).join(", ")}]`,
132
+ 'export const getParser = (ext) => transformers.find(p => ext.match(new RegExp(p.extensions.join("|"), "i")) && p.parse)',
133
+ 'export const getTransformers = (ext) => transformers.filter(p => ext.match(new RegExp(p.extensions.join("|"), "i")) && p.transform)',
134
+ "export default () => {}"
135
+ ].join("\n");
136
+ }
137
+ }).dst;
138
+ const virtualConfigTemplate = addTemplateImpl({
139
+ filename: "content/virtual-config.mjs",
140
+ write: true,
141
+ getContents: () => contentConfigPath ? [
142
+ `import jiti from ${JSON.stringify(jitiImportSpecifier)}`,
143
+ `const importer = jiti(import.meta.url, { interopDefault: true })`,
144
+ `const config = await importer.import(${JSON.stringify(contentConfigPath)})`,
145
+ "export default config?.default || config || {}"
146
+ ].join("\n") : "export default {}"
147
+ }).dst;
148
+ const virtualProvidersTemplate = addTemplateImpl({
149
+ filename: "content/virtual-providers.mjs",
150
+ write: true,
151
+ getContents: () => {
152
+ const providers = Object.entries(contentContext.providers || {});
153
+ const cases = providers.map(([name, specifier]) => {
154
+ return `case ${JSON.stringify(name)}: return import(${JSON.stringify(specifier)}).then(resolveProviderModule)`;
155
+ });
156
+ return [
157
+ "const resolveProviderModule = (mod) => mod.default || mod.contentProvider || mod.provider",
158
+ "export const externalContentProviderNames = " + JSON.stringify(providers.map(([name]) => name)),
159
+ "export const loadExternalContentProvider = (name) => {",
160
+ " switch (name) {",
161
+ ...cases.map((item) => ` ${item}`),
162
+ " default: return undefined",
163
+ " }",
164
+ "}",
165
+ "export default {}"
166
+ ].join("\n");
167
+ }
168
+ }).dst;
169
+ const virtualCacheAdapterTemplate = addTemplateImpl({
170
+ filename: "content/virtual-cache-adapter.mjs",
171
+ write: true,
172
+ getContents: () => {
173
+ const cache = contentContext.cache;
174
+ if (!cache || cache === false) {
175
+ return [
176
+ "export const loadContentCacheAdapter = () => undefined",
177
+ "export default {}"
178
+ ].join("\n");
179
+ }
180
+ return [
181
+ "const resolveCacheAdapterModule = (mod) => mod.default || mod.contentCacheAdapter || mod.cacheAdapter",
182
+ `export const loadContentCacheAdapter = () => import(${JSON.stringify(cache)}).then(resolveCacheAdapterModule)`,
183
+ "export default {}"
184
+ ].join("\n");
185
+ }
186
+ }).dst;
187
+ return {
188
+ transformersTemplate,
189
+ virtualConfigTemplate,
190
+ virtualProvidersTemplate,
191
+ virtualCacheAdapterTemplate
192
+ };
193
+ };
194
+ const registerVirtualContentAliases = (nuxt, transformersTemplate, virtualConfigTemplate, virtualProvidersTemplate, virtualCacheAdapterTemplate, resolveRuntimeModule) => {
195
+ nuxt.options.alias = nuxt.options.alias || {};
196
+ nuxt.options.alias["#content/virtual/transformers"] = transformersTemplate;
197
+ nuxt.options.alias["#content/virtual/config"] = virtualConfigTemplate;
198
+ nuxt.options.alias["#content/virtual/providers"] = virtualProvidersTemplate;
199
+ nuxt.options.alias["#content/virtual/cache-adapter"] = virtualCacheAdapterTemplate;
200
+ nuxt.hook("nitro:config", (nitroConfig) => {
201
+ nitroConfig.alias = nitroConfig.alias || {};
202
+ nitroConfig.alias["#content/server"] = resolveRuntimeModule("./server/index.js");
203
+ nitroConfig.alias["#content/virtual/transformers"] = transformersTemplate;
204
+ nitroConfig.alias["#content/virtual/config"] = virtualConfigTemplate;
205
+ nitroConfig.alias["#content/virtual/providers"] = virtualProvidersTemplate;
206
+ nitroConfig.alias["#content/virtual/cache-adapter"] = virtualCacheAdapterTemplate;
207
+ });
208
+ };
209
+
210
+ const registerContentDevRuntime = (nuxt, options, contentContext) => {
211
+ const isIgnored = makeIgnored(contentContext.ignores);
212
+ nuxt.hook("nitro:init", async (nitro) => {
213
+ if (!options.watch || !options.watch.ws) {
214
+ return;
215
+ }
216
+ const ws = createWebSocket();
217
+ const { server, url } = await listen(() => "Ginko", options.watch.ws);
218
+ const unwatch = await nitro.storage.watch(async (event, key) => {
219
+ if (!key.startsWith(MOUNT_PREFIX) || isIgnored(key)) {
220
+ return;
221
+ }
222
+ key = key.substring(MOUNT_PREFIX.length);
223
+ await nitro.storage.removeItem("cache:content:_manifest.json");
224
+ await nitro.storage.removeItem("cache:content:_nav.json");
225
+ await nitro.storage.removeItem("cache:content:_meta.json");
226
+ ws.broadcast({ event, key });
227
+ });
228
+ nitro.hooks.hook("close", async () => {
229
+ await unwatch();
230
+ await ws.close();
231
+ await server.close();
232
+ });
233
+ server.on("upgrade", ws.serve);
234
+ nitro.options.runtimeConfig.public.content.wsUrl = url.replace("http", "ws");
235
+ await nitro.storage.removeItem("cache:content:_manifest.json");
236
+ await nitro.storage.removeItem("cache:content:_nav.json");
237
+ await nitro.storage.removeItem("cache:content:_meta.json");
238
+ });
239
+ };
240
+
241
+ const registerRuntimeImports = (resolveRuntimeModule) => {
242
+ addImports([
243
+ // Unified query API (ADR-0016) — app wrappers bind the Nuxt content context explicitly.
244
+ { name: "one", as: "one", from: resolveRuntimeModule("./app/composables/query-api.js") },
245
+ { name: "many", as: "many", from: resolveRuntimeModule("./app/composables/query-api.js") },
246
+ { name: "paginate", as: "paginate", from: resolveRuntimeModule("./app/composables/query-api.js") },
247
+ { name: "backlinks", as: "backlinks", from: resolveRuntimeModule("./app/composables/query-api.js") },
248
+ { name: "resolveOne", as: "resolveOne", from: resolveRuntimeModule("./app/composables/query-api.js") },
249
+ { name: "variants", as: "variants", from: resolveRuntimeModule("./app/composables/query-api.js") },
250
+ { name: "tree", as: "tree", from: resolveRuntimeModule("./app/composables/query-api.js") },
251
+ { name: "neighbors", as: "neighbors", from: resolveRuntimeModule("./app/composables/query-api.js") },
252
+ { name: "getCollectionPath", as: "getCollectionPath", from: resolveRuntimeModule("./query/routes.js") },
253
+ // Vue composables — reactive wrappers over the same options shape.
254
+ { name: "useContentPage", as: "useContentPage", from: resolveRuntimeModule("./app/composables/use-content.js") },
255
+ { name: "useContentOne", as: "useContentOne", from: resolveRuntimeModule("./app/composables/use-content.js") },
256
+ { name: "useContentMany", as: "useContentMany", from: resolveRuntimeModule("./app/composables/use-content.js") },
257
+ { name: "useContentPagination", as: "useContentPagination", from: resolveRuntimeModule("./app/composables/use-content.js") },
258
+ { name: "useContentBacklinks", as: "useContentBacklinks", from: resolveRuntimeModule("./app/composables/use-content.js") },
259
+ { name: "useContentResolveOne", as: "useContentResolveOne", from: resolveRuntimeModule("./app/composables/use-content.js") },
260
+ { name: "useContentVariants", as: "useContentVariants", from: resolveRuntimeModule("./app/composables/use-content.js") },
261
+ { name: "useContentTree", as: "useContentTree", from: resolveRuntimeModule("./app/composables/use-content.js") },
262
+ { name: "useContentNeighbors", as: "useContentNeighbors", from: resolveRuntimeModule("./app/composables/use-content.js") },
263
+ { name: "useContentLocaleSwitch", as: "useContentLocaleSwitch", from: resolveRuntimeModule("./app/composables/use-content.js") },
264
+ // Search & site data — kept (out of scope for ADR-0016).
265
+ { name: "useContentSearchData", as: "useContentSearchData", from: resolveRuntimeModule("./app/composables/search.js") },
266
+ { name: "useContentSearchResults", as: "useContentSearchResults", from: resolveRuntimeModule("./app/composables/search.js") },
267
+ { name: "querySiteData", as: "querySiteData", from: resolveRuntimeModule("./app/composables/site-data.js") }
268
+ ]);
269
+ addServerImports([
270
+ { name: "one", as: "one", from: resolveRuntimeModule("./server/index.js") },
271
+ { name: "many", as: "many", from: resolveRuntimeModule("./server/index.js") },
272
+ { name: "paginate", as: "paginate", from: resolveRuntimeModule("./server/index.js") },
273
+ { name: "backlinks", as: "backlinks", from: resolveRuntimeModule("./server/index.js") },
274
+ { name: "resolveOne", as: "resolveOne", from: resolveRuntimeModule("./server/index.js") },
275
+ { name: "variants", as: "variants", from: resolveRuntimeModule("./server/index.js") },
276
+ { name: "tree", as: "tree", from: resolveRuntimeModule("./server/index.js") },
277
+ { name: "neighbors", as: "neighbors", from: resolveRuntimeModule("./server/index.js") },
278
+ { name: "getCollectionPath", as: "getCollectionPath", from: resolveRuntimeModule("./server/index.js") },
279
+ { name: "queryCollectionsSitemapEntries", as: "queryCollectionsSitemapEntries", from: resolveRuntimeModule("./server/index.js") }
280
+ ]);
281
+ };
282
+ const registerRuntimeComponents = (resolve) => {
283
+ addComponentsDir({
284
+ path: resolve("./runtime/app/components"),
285
+ pathPrefix: false,
286
+ prefix: "",
287
+ global: true,
288
+ ignore: ["Prose/**", "internal/**"]
289
+ });
290
+ };
291
+ const registerContentI18nTemplate = (addTemplateImpl, hasNuxtI18nModule) => {
292
+ addTemplateImpl({
293
+ filename: "content-i18n.mjs",
294
+ write: true,
295
+ getContents: () => hasNuxtI18nModule ? [
296
+ "export { useRouteBaseName, useSetI18nParams, useSwitchLocalePath } from '#i18n'"
297
+ ].join("\n") : [
298
+ "const routeNameLocaleRE = /___([^_]+)$/",
299
+ "const resolveName = (value) => {",
300
+ " if (typeof value === 'string') {",
301
+ " return value",
302
+ " }",
303
+ " if (value && typeof value === 'object' && 'name' in value) {",
304
+ " return value.name",
305
+ " }",
306
+ " return undefined",
307
+ "}",
308
+ "export const useRouteBaseName = () => (value) => {",
309
+ " const name = resolveName(value)",
310
+ " return typeof name === 'string' ? name.replace(routeNameLocaleRE, '') : undefined",
311
+ "}",
312
+ "export const useSetI18nParams = () => () => {}",
313
+ "export const useSwitchLocalePath = () => () => ''"
314
+ ].join("\n")
315
+ });
316
+ addTemplateImpl({
317
+ filename: "content-i18n.d.mts",
318
+ write: true,
319
+ getContents: () => [
320
+ "export function useRouteBaseName(): (route: { name?: unknown } | unknown) => string | undefined",
321
+ "export function useSetI18nParams(): (params: Record<string, unknown>) => void",
322
+ "export function useSwitchLocalePath(): (locale: string) => string"
323
+ ].join("\n")
324
+ });
325
+ addTypeTemplate({
326
+ filename: "types/content-i18n.d.ts",
327
+ getContents: () => [
328
+ "declare module '#build/content-i18n.mjs' {",
329
+ " export function useRouteBaseName(): (route: { name?: unknown } | unknown) => string | undefined",
330
+ " export function useSetI18nParams(): (params: Record<string, unknown>) => void",
331
+ " export function useSwitchLocalePath(): (locale: string) => string",
332
+ "}"
333
+ ].join("\n")
334
+ });
335
+ };
336
+ const registerUserContentComponents = async (nuxt, resolve) => {
337
+ const layers = [...nuxt.options._layers];
338
+ for (const layer of layers) {
339
+ const srcDir = layer.config.srcDir;
340
+ const globalComponents = resolve(srcDir, "components/content");
341
+ const dirStat = await fs.promises.stat(globalComponents).catch((error) => {
342
+ if (error.code === "ENOENT") {
343
+ return null;
344
+ }
345
+ throw error;
346
+ });
347
+ if (dirStat && dirStat.isDirectory()) {
348
+ nuxt.hook("components:dirs", (dirs) => {
349
+ dirs.unshift({
350
+ path: globalComponents,
351
+ global: false,
352
+ pathPrefix: false,
353
+ prefix: ""
354
+ });
355
+ });
356
+ }
357
+ }
358
+ };
359
+ const registerGeneratedTypes = (contentConfigPath, resolveRuntimeModuleRoot) => {
360
+ return addTypeTemplate({
361
+ filename: "types/content.d.ts",
362
+ getContents: () => [
363
+ contentConfigPath ? `import type contentConfig from ${JSON.stringify(contentConfigPath)}` : "type __ContentConfig = { collections?: {} }",
364
+ "import type { StrictParsedContent } from '@lupinum/ginko-content'",
365
+ "import type { CollectionSchema } from '@lupinum/ginko-content/config'",
366
+ contentConfigPath ? "type __ContentConfig = typeof contentConfig" : "",
367
+ "type __ContentCollections = NonNullable<__ContentConfig['collections']>",
368
+ "type __GeneratedContentCollectionMap = {",
369
+ " [K in keyof __ContentCollections & string]: StrictParsedContent & CollectionSchema<__ContentCollections[K]>",
370
+ "}",
371
+ "type __GeneratedI18nCollectionNames = {",
372
+ " [K in keyof __ContentCollections & string]: NonNullable<__ContentCollections[K]['i18n']> extends never ? never : K",
373
+ "}[keyof __ContentCollections & string]",
374
+ "declare module '@lupinum/ginko-content' {",
375
+ " interface ContentCollectionMap extends __GeneratedContentCollectionMap {}",
376
+ " interface ContentCollectionI18nMap extends Pick<__GeneratedContentCollectionMap, __GeneratedI18nCollectionNames> {}",
377
+ "}",
378
+ "declare module '#content/server' {",
379
+ ` const one: typeof import('${resolveRuntimeModuleRoot("./server")}').one`,
380
+ ` const many: typeof import('${resolveRuntimeModuleRoot("./server")}').many`,
381
+ ` const paginate: typeof import('${resolveRuntimeModuleRoot("./server")}').paginate`,
382
+ ` const backlinks: typeof import('${resolveRuntimeModuleRoot("./server")}').backlinks`,
383
+ ` const resolveOne: typeof import('${resolveRuntimeModuleRoot("./server")}').resolveOne`,
384
+ ` const variants: typeof import('${resolveRuntimeModuleRoot("./server")}').variants`,
385
+ ` const tree: typeof import('${resolveRuntimeModuleRoot("./server")}').tree`,
386
+ ` const neighbors: typeof import('${resolveRuntimeModuleRoot("./server")}').neighbors`,
387
+ ` const queryCollectionsSitemapEntries: typeof import('${resolveRuntimeModuleRoot("./server")}').queryCollectionsSitemapEntries`,
388
+ ` const contentCacheHeaders: typeof import('${resolveRuntimeModuleRoot("./server")}').contentCacheHeaders`,
389
+ ` const noopContentCache: typeof import('${resolveRuntimeModuleRoot("./server")}').noopContentCache`,
390
+ ` const vercelContentCache: typeof import('${resolveRuntimeModuleRoot("./server")}').vercelContentCache`,
391
+ ` const clearContentCacheHint: typeof import('${resolveRuntimeModuleRoot("./server")}').clearContentCacheHint`,
392
+ ` const collectContentCacheHint: typeof import('${resolveRuntimeModuleRoot("./server")}').collectContentCacheHint`,
393
+ ` const getContentCacheHint: typeof import('${resolveRuntimeModuleRoot("./server")}').getContentCacheHint`,
394
+ ` const withContentCache: typeof import('${resolveRuntimeModuleRoot("./server")}').withContentCache`,
395
+ ` const createContentProviderError: typeof import('${resolveRuntimeModuleRoot("./server")}').createContentProviderError`,
396
+ ` type ContentCacheAdapter = import('${resolveRuntimeModuleRoot("./server")}').ContentCacheAdapter`,
397
+ ` type ContentCacheHint = import('${resolveRuntimeModuleRoot("./server")}').ContentCacheHint`,
398
+ ` type ContentCacheHintInput = import('${resolveRuntimeModuleRoot("./server")}').ContentCacheHintInput`,
399
+ ` type ContentCacheInvalidateInput = import('${resolveRuntimeModuleRoot("./server")}').ContentCacheInvalidateInput`,
400
+ ` type ContentProvider = import('${resolveRuntimeModuleRoot("./server")}').ContentProvider`,
401
+ ` type ContentProviderCapabilities = import('${resolveRuntimeModuleRoot("./server")}').ContentProviderCapabilities`,
402
+ ` type ContentProviderResult<T> = import('${resolveRuntimeModuleRoot("./server")}').ContentProviderResult<T>`,
403
+ ` type MaybeContentProviderResult<T> = import('${resolveRuntimeModuleRoot("./server")}').MaybeContentProviderResult<T>`,
404
+ ` type ContentProviderErrorCode = import('${resolveRuntimeModuleRoot("./server")}').ContentProviderErrorCode`,
405
+ ` type VercelContentCacheOptions = import('${resolveRuntimeModuleRoot("./server")}').VercelContentCacheOptions`,
406
+ "}"
407
+ ].filter(Boolean).join("\n")
408
+ });
409
+ };
410
+ const registerDevRuntimePlugin = (resolveRuntimeModule) => {
411
+ addPlugin(resolveRuntimeModule("./app/plugins/ws.js"));
412
+ };
413
+
414
+ const registerContentServerHandlers = (nuxt, options, resolveRuntimeModule, buildIntegrity) => {
415
+ addServerHandler({
416
+ method: "get",
417
+ route: `${options.api.baseURL}/query/**:params`,
418
+ handler: resolveRuntimeModule("./server/api/query.js")
419
+ });
420
+ addServerHandler({
421
+ method: "get",
422
+ route: `${options.api.baseURL}/query`,
423
+ handler: resolveRuntimeModule("./server/api/query.js")
424
+ });
425
+ addServerHandler({
426
+ method: "get",
427
+ route: `${options.api.baseURL}/locales/:collection`,
428
+ handler: resolveRuntimeModule("./server/api/locales.js")
429
+ });
430
+ addServerHandler({
431
+ method: "get",
432
+ route: `${options.api.baseURL}/site-data`,
433
+ handler: resolveRuntimeModule("./server/api/site-data.js")
434
+ });
435
+ if (options.revalidate && options.revalidate !== false && options.revalidate.token) {
436
+ addServerHandler({
437
+ method: "post",
438
+ route: `${options.api.baseURL}/revalidate`,
439
+ handler: resolveRuntimeModule("./server/api/revalidate.js")
440
+ });
441
+ }
442
+ addServerHandler({
443
+ method: "get",
444
+ route: nuxt.options.dev ? `${options.api.baseURL}/cache.json` : `${options.api.baseURL}/cache.${buildIntegrity}.json`,
445
+ handler: resolveRuntimeModule("./server/api/cache.js")
446
+ });
447
+ if (options.sitemap !== false) {
448
+ addServerHandler({
449
+ method: "get",
450
+ route: `${options.api.baseURL}${options.sitemap.path || "/sitemap"}`,
451
+ handler: resolveRuntimeModule("./server/api/sitemap.js")
452
+ });
453
+ }
454
+ if (options.navigation) {
455
+ addServerHandler({
456
+ method: "get",
457
+ route: `${options.api.baseURL}/navigation/**:params`,
458
+ handler: resolveRuntimeModule("./server/api/navigation.js")
459
+ });
460
+ addServerHandler({
461
+ method: "get",
462
+ route: `${options.api.baseURL}/navigation`,
463
+ handler: resolveRuntimeModule("./server/api/navigation.js")
464
+ });
465
+ }
466
+ };
467
+ const registerContentSearchServerHandlers = (apiBaseURL, search, resolveRuntimeModule) => {
468
+ const searchBaseURL = search.apiBaseURL || `${apiBaseURL.replace(/\/$/, "")}/search`;
469
+ const indexURL = `${searchBaseURL.replace(/\/$/, "")}/index.json`;
470
+ addServerHandler({
471
+ method: "get",
472
+ route: searchBaseURL,
473
+ handler: resolveRuntimeModule("./server/api/search.js")
474
+ });
475
+ if (search.engine !== "cms") {
476
+ addServerHandler({
477
+ method: "get",
478
+ route: indexURL,
479
+ handler: resolveRuntimeModule("./server/api/search-index.js")
480
+ });
481
+ }
482
+ };
483
+
484
+ const SITEMAP_INDEX = "sitemap_index.xml";
485
+ const assert = (condition, message) => {
486
+ if (!condition) {
487
+ throw new Error(message);
488
+ }
489
+ };
490
+ const countTag = (xml, tag) => (xml.match(new RegExp(`<${tag}>`, "g")) || []).length;
491
+ const extractLocValues = (xml) => {
492
+ return Array.from(xml.matchAll(/<loc>([^<]+)<\/loc>/g), (match) => match[1]);
493
+ };
494
+ const toLocalPath = (value) => {
495
+ try {
496
+ return new URL(value).pathname;
497
+ } catch {
498
+ return value;
499
+ }
500
+ };
501
+ const discoverSitemapsFromDisk = async (outputPublicDir) => {
502
+ const indexPath = join$1(outputPublicDir, SITEMAP_INDEX);
503
+ try {
504
+ const sitemapIndex = await readFile(indexPath, "utf8");
505
+ const locValues = extractLocValues(sitemapIndex);
506
+ const discovered = locValues.map(toLocalPath).filter((path) => path.endsWith(".xml") && path !== "/sitemap.xml" && path !== "/sitemap_index.xml").map((path) => {
507
+ const normalizedPath = path.replace(/^\/+/, "");
508
+ return {
509
+ name: basename(normalizedPath, ".xml"),
510
+ path: join$1(outputPublicDir, normalizedPath)
511
+ };
512
+ });
513
+ if (discovered.length > 0) {
514
+ return Promise.all(discovered.map(async (target) => ({
515
+ ...target,
516
+ xml: await readFile(target.path, "utf8")
517
+ })));
518
+ }
519
+ } catch {
520
+ }
521
+ const children = [];
522
+ const sitemapDir = join$1(outputPublicDir, "__sitemap__");
523
+ try {
524
+ const sitemapFiles = (await readdir(sitemapDir, { withFileTypes: true })).filter((entry) => entry.isFile() && entry.name.endsWith(".xml")).map((entry) => ({
525
+ name: basename(entry.name, ".xml"),
526
+ path: join$1(sitemapDir, entry.name)
527
+ }));
528
+ children.push(...await Promise.all(sitemapFiles.map(async (target) => ({
529
+ ...target,
530
+ xml: await readFile(target.path, "utf8")
531
+ }))));
532
+ } catch {
533
+ }
534
+ if (children.length > 0) {
535
+ return children;
536
+ }
537
+ const rootSitemapPath = join$1(outputPublicDir, "sitemap.xml");
538
+ const rootSitemapXml = await readFile(rootSitemapPath, "utf8");
539
+ assert(
540
+ countTag(rootSitemapXml, "url") > 0 || rootSitemapXml.includes("<urlset"),
541
+ `Content sitemap assertion failed: no child sitemap files were discovered in ${indexPath} or ${sitemapDir}, and ${rootSitemapPath} is not a urlset sitemap.`
542
+ );
543
+ return [{
544
+ name: "sitemap",
545
+ path: rootSitemapPath,
546
+ xml: rootSitemapXml
547
+ }];
548
+ };
549
+ const normalizeContentSitemapAssertOptions = (options) => ({
550
+ enabled: options?.enabled ?? false,
551
+ mode: options?.mode ?? "generate",
552
+ allowEmpty: options?.allowEmpty ?? false,
553
+ minUrlsPerSitemap: options?.minUrlsPerSitemap ?? 1,
554
+ requireImages: options?.requireImages ?? false,
555
+ requiredCollections: options?.requiredCollections ?? [],
556
+ sitemaps: options?.sitemaps ?? {}
557
+ });
558
+ const shouldRunSitemapAssertionOnCompiled = (options, nitro) => {
559
+ const isStaticLikeBuild = nitro.options.static || nitro.options.preset === "static";
560
+ if (!options.enabled || isStaticLikeBuild) {
561
+ return false;
562
+ }
563
+ return options.mode === "build" || options.mode === "both";
564
+ };
565
+ const shouldRunSitemapAssertionOnPrerenderedSitemaps = (options) => options.enabled && options.mode !== "build";
566
+ async function assertGeneratedSitemaps({
567
+ options,
568
+ collectionRouteCounts,
569
+ outputPublicDir,
570
+ targets,
571
+ logger
572
+ }) {
573
+ const discoveredSitemaps = targets || (outputPublicDir ? await discoverSitemapsFromDisk(outputPublicDir) : []);
574
+ assert(discoveredSitemaps.length > 0, "Content sitemap assertion failed: no sitemap targets were available for validation.");
575
+ const targetMap = new Map(discoveredSitemaps.map((target) => [target.name, target]));
576
+ const failures = [];
577
+ for (const sitemapName of Object.keys(options.sitemaps)) {
578
+ if (!targetMap.has(sitemapName)) {
579
+ const sourceDescription = outputPublicDir ? join$1(outputPublicDir, SITEMAP_INDEX) : "prerendered sitemap_index.xml";
580
+ failures.push(`- Missing sitemap "${sitemapName}" in ${sourceDescription}`);
581
+ }
582
+ }
583
+ for (const target of targetMap.values()) {
584
+ const overrides = options.sitemaps[target.name] || {};
585
+ const allowEmpty = overrides.allowEmpty ?? options.allowEmpty;
586
+ const minUrls = overrides.minUrls ?? options.minUrlsPerSitemap;
587
+ const requireImages = overrides.requireImages ?? options.requireImages;
588
+ const urlCount = countTag(target.xml, "url");
589
+ const imageCount = countTag(target.xml, "image:image");
590
+ if (!allowEmpty && urlCount < minUrls) {
591
+ failures.push(`- ${target.name}: ${urlCount} URLs, expected at least ${minUrls}`);
592
+ }
593
+ if (requireImages && imageCount === 0) {
594
+ failures.push(`- ${target.name}: expected image entries but found none`);
595
+ }
596
+ }
597
+ const missingCollections = options.requiredCollections.filter((collection) => (collectionRouteCounts[collection] || 0) === 0);
598
+ if (missingCollections.length) {
599
+ failures.push(`- Missing content sitemap routes for collections: ${missingCollections.join(", ")}`);
600
+ }
601
+ if (failures.length) {
602
+ throw new Error(`Content sitemap assertion failed:
603
+ ${failures.join("\n")}`);
604
+ }
605
+ logger?.info(`Content sitemap assertion passed for ${targetMap.size} sitemap${targetMap.size === 1 ? "" : "s"}.`);
606
+ }
607
+ const createSitemapAssertionTargetsFromPrerenderedSitemaps = (sitemaps) => {
608
+ const targets = sitemaps.map((sitemap) => {
609
+ const path = toLocalPath(sitemap.name);
610
+ const name = basename(path, ".xml");
611
+ return {
612
+ name,
613
+ path,
614
+ xml: sitemap.content
615
+ };
616
+ }).filter((target) => {
617
+ if (target.name === "sitemap_index") {
618
+ return false;
619
+ }
620
+ if (target.name === "sitemap") {
621
+ return target.xml.includes("<urlset");
622
+ }
623
+ return true;
624
+ });
625
+ assert(targets.length > 0, "Content sitemap assertion failed: no sitemap urlsets were available from sitemap:prerender:done.");
626
+ return targets;
627
+ };
628
+
629
+ function hasNuxtModule(modules = [], name) {
630
+ return modules.some((entry) => {
631
+ if (typeof entry === "string") {
632
+ return entry === name;
633
+ }
634
+ if (Array.isArray(entry) && typeof entry[0] === "string") {
635
+ return entry[0] === name;
636
+ }
637
+ return false;
638
+ });
639
+ }
640
+ function hasNuxtI18nModule(modules = []) {
641
+ return hasNuxtModule(modules, "@nuxtjs/i18n");
642
+ }
643
+ function hasNuxtSitemapModule(modules = []) {
644
+ return hasNuxtModule(modules, "@nuxtjs/sitemap");
645
+ }
646
+ function resolveNuxtSitemapPrerenderRoutes(nuxt) {
647
+ if (!hasNuxtSitemapModule(nuxt.options.modules)) {
648
+ return [];
649
+ }
650
+ const nuxtI18n = nuxt.options.i18n || {};
651
+ if (!hasNuxtI18nModule(nuxt.options.modules) || !Array.isArray(nuxtI18n.locales) || nuxtI18n.locales.length === 0) {
652
+ return [];
653
+ }
654
+ const childRoutes = nuxtI18n.locales.map((locale) => typeof locale === "string" ? locale : locale.language || locale.code).filter(Boolean).map((locale) => `/__sitemap__/${locale}.xml`);
655
+ return Array.from(/* @__PURE__ */ new Set(["/sitemap_index.xml", ...childRoutes]));
656
+ }
657
+ function resolveModuleI18nOptions(options, nuxt) {
658
+ if (options.i18n === false) {
659
+ return {
660
+ locales: [],
661
+ defaultLocale: void 0,
662
+ fallback: {},
663
+ translatedSlugs: false,
664
+ strictTranslatedSlugs: false
665
+ };
666
+ }
667
+ const moduleI18n = options.i18n === true ? {} : options.i18n || {};
668
+ const nuxtI18n = nuxt.options.i18n || {};
669
+ const nuxtLocales = Array.isArray(nuxtI18n.locales) ? nuxtI18n.locales.map((locale) => typeof locale === "string" ? locale : locale.code).filter(Boolean) : [];
670
+ const locales = Array.from(new Set([
671
+ moduleI18n.defaultLocale,
672
+ nuxtI18n.defaultLocale,
673
+ ...moduleI18n.locales || [],
674
+ ...nuxtLocales
675
+ ].filter(Boolean)));
676
+ const defaultLocale = moduleI18n.defaultLocale || nuxtI18n.defaultLocale || locales[0];
677
+ return {
678
+ locales,
679
+ defaultLocale,
680
+ fallback: defu({}, moduleI18n.fallback),
681
+ translatedSlugs: moduleI18n.translatedSlugs ?? false,
682
+ strictTranslatedSlugs: moduleI18n.strictTranslatedSlugs ?? false
683
+ };
684
+ }
685
+ function normalizeSitemapOptions(options) {
686
+ if (options.sitemap === false) {
687
+ return false;
688
+ }
689
+ const sitemap = options.sitemap === true ? {} : options.sitemap;
690
+ return {
691
+ path: sitemap.path || "/sitemap",
692
+ include: sitemap.include,
693
+ exclude: sitemap.exclude || [],
694
+ includeDrafts: sitemap.includeDrafts,
695
+ assert: normalizeContentSitemapAssertOptions(sitemap.assert)
696
+ };
697
+ }
698
+ function normalizeSearchOptions(options) {
699
+ if (options.search === false) {
700
+ return false;
701
+ }
702
+ return {
703
+ engine: options.search?.engine || "minisearch",
704
+ ignoredTags: options.search?.ignoredTags || ["script", "style", "pre"],
705
+ filterQuery: options.search?.filterQuery || { _draft: false, _partial: false },
706
+ collections: options.search?.collections,
707
+ extraFields: options.search?.extraFields || [],
708
+ apiBaseURL: options.search?.apiBaseURL,
709
+ minisearch: normalizeMiniSearchOptions(options.search?.minisearch)
710
+ };
711
+ }
712
+ const defaultMiniSearchOptions = {
713
+ fields: ["title", "content", "headings"],
714
+ storeFields: ["path", "title", "excerpt", "anchor", "locale"],
715
+ boost: {
716
+ title: 4,
717
+ headings: 2,
718
+ content: 1
719
+ },
720
+ fuzzy: 0.2,
721
+ prefix: true
722
+ };
723
+ const requiredMiniSearchStoreFields = ["path", "title", "excerpt"];
724
+ function normalizeMiniSearchOptions(options = {}) {
725
+ const fields = options?.fields?.filter((field) => typeof field === "string" && field.length > 0);
726
+ const storeFields = options?.storeFields?.filter((field) => typeof field === "string" && field.length > 0);
727
+ const boost = Object.fromEntries(
728
+ Object.entries(options?.boost || {}).filter((entry) => typeof entry[0] === "string" && entry[0].length > 0 && typeof entry[1] === "number" && Number.isFinite(entry[1]))
729
+ );
730
+ const resolvedFields = fields?.length ? fields : [...defaultMiniSearchOptions.fields];
731
+ const resolvedStoreFields = storeFields?.length ? storeFields : defaultMiniSearchOptions.storeFields;
732
+ return {
733
+ fields: resolvedFields,
734
+ storeFields: Array.from(/* @__PURE__ */ new Set([...requiredMiniSearchStoreFields, ...resolvedStoreFields])),
735
+ boost: Object.keys(boost).length ? boost : { ...defaultMiniSearchOptions.boost },
736
+ fuzzy: typeof options?.fuzzy === "boolean" || typeof options?.fuzzy === "number" ? options.fuzzy : defaultMiniSearchOptions.fuzzy,
737
+ prefix: typeof options?.prefix === "boolean" ? options.prefix : defaultMiniSearchOptions.prefix
738
+ };
739
+ }
740
+ function createSearchRuntimeConfig(search, apiBaseURL) {
741
+ const resolvedApiBaseURL = search.apiBaseURL || `${apiBaseURL.replace(/\/$/, "")}/search`;
742
+ return {
743
+ apiBaseURL: resolvedApiBaseURL,
744
+ indexURL: `${resolvedApiBaseURL.replace(/\/$/, "")}/index.json`,
745
+ engine: search.engine || "minisearch",
746
+ minisearch: normalizeMiniSearchOptions(search.minisearch)
747
+ };
748
+ }
749
+
750
+ const resolveNuxtSiteUrl = (nuxt) => {
751
+ const publicRuntime = nuxt.options.runtimeConfig.public;
752
+ const configuredSiteUrl = publicRuntime.siteUrl;
753
+ if (typeof configuredSiteUrl === "string" && configuredSiteUrl.length > 0) {
754
+ return configuredSiteUrl;
755
+ }
756
+ const nuxtSite = nuxt.options.site;
757
+ return typeof nuxtSite?.url === "string" && nuxtSite.url.length > 0 ? nuxtSite.url : void 0;
758
+ };
759
+ const applyContentRuntimeConfig = (nuxt, options, contentContext, runtimeCollections, buildIntegrity, cacheIntegrity) => {
760
+ const searchRuntime = contentContext.search === false ? false : {
761
+ apiBaseURL: contentContext.search.apiBaseURL || `${options.api.baseURL.replace(/\/$/, "")}/search`,
762
+ indexURL: `${(contentContext.search.apiBaseURL || `${options.api.baseURL.replace(/\/$/, "")}/search`).replace(/\/$/, "")}/index.json`,
763
+ engine: contentContext.search.engine || "minisearch",
764
+ minisearch: normalizeMiniSearchOptions(contentContext.search.minisearch)
765
+ };
766
+ const contentRuntime = defu(nuxt.options.runtimeConfig.public.content, {
767
+ locales: contentContext.locales,
768
+ provider: contentContext.provider || "filesystem",
769
+ providers: contentContext.providers || {},
770
+ defaultLocale: contentContext.defaultLocale || void 0,
771
+ localeFallback: contentContext.localeFallback || {},
772
+ translatedSlugs: contentContext.translatedSlugs ?? false,
773
+ strictTranslatedSlugs: contentContext.strictTranslatedSlugs ?? false,
774
+ collections: runtimeCollections,
775
+ integrity: buildIntegrity,
776
+ experimental: {
777
+ stripQueryParameters: options.experimental.stripQueryParameters
778
+ },
779
+ respectPathCase: options.respectPathCase ?? false,
780
+ api: {
781
+ baseURL: options.api.baseURL
782
+ },
783
+ markdown: {
784
+ plugins: contentContext.markdown.plugins,
785
+ tags: contentContext.markdown.tags,
786
+ anchorLinks: contentContext.markdown.anchorLinks,
787
+ image: contentContext.markdown.image || "auto"
788
+ },
789
+ sitemap: contentContext.sitemap ? {
790
+ path: contentContext.sitemap.path || "/sitemap",
791
+ ...contentContext.sitemap.include?.length ? { include: contentContext.sitemap.include } : {},
792
+ ...contentContext.sitemap.exclude?.length ? { exclude: contentContext.sitemap.exclude } : {},
793
+ ...typeof contentContext.sitemap.includeDrafts === "boolean" ? { includeDrafts: contentContext.sitemap.includeDrafts } : {}
794
+ } : false,
795
+ search: searchRuntime,
796
+ navigation: contentContext.navigation,
797
+ wsUrl: "",
798
+ contentHead: options.contentHead ?? true
799
+ });
800
+ const siteUrl = resolveNuxtSiteUrl(nuxt);
801
+ if (siteUrl) {
802
+ nuxt.options.runtimeConfig.public.siteUrl = siteUrl;
803
+ }
804
+ nuxt.options.runtimeConfig.public.content = contentRuntime;
805
+ nuxt.options.runtimeConfig.content = defu(nuxt.options.runtimeConfig.content, {
806
+ cacheVersion: CACHE_VERSION,
807
+ cacheIntegrity,
808
+ revalidate: options.revalidate && options.revalidate !== false && options.revalidate.token ? {
809
+ token: options.revalidate.token,
810
+ allowUnsigned: options.revalidate.allowUnsigned === true
811
+ } : false,
812
+ ...contentContext,
813
+ collections: runtimeCollections
814
+ });
815
+ };
816
+
817
+ const registerContentComponentsTemplate = (addTemplateImpl) => {
818
+ addTemplateImpl({
819
+ filename: "content-components.mjs",
820
+ getContents({ app, nuxt }) {
821
+ const componentsMap = app.components.filter((component) => {
822
+ if (component.island) {
823
+ return false;
824
+ }
825
+ if (component.filePath.endsWith(".css")) {
826
+ return false;
827
+ }
828
+ if (component.pascalName === "ClientOnly" || component.filePath.includes("nuxt/dist/") || component.filePath.includes("NuxtWelcome")) {
829
+ return false;
830
+ }
831
+ return true;
832
+ }).reduce((map, component) => {
833
+ const importPath = isAbsolute(component.filePath) ? "./" + relative(nuxt.options.buildDir, component.filePath).replace(/\b\.(?!vue)\w+$/g, "") : component.filePath.replace(/\b\.(?!vue)\w+$/g, "");
834
+ map[component.pascalName] = map[component.pascalName] || [
835
+ component.pascalName,
836
+ importPath,
837
+ component.global,
838
+ component.export || "default"
839
+ ];
840
+ return map;
841
+ }, {});
842
+ const componentsList = Object.values(componentsMap);
843
+ const globalComponents = componentsList.filter((component) => component[2]).map((component) => component[0]);
844
+ const localComponents = componentsList.filter((component) => !component[2]);
845
+ return [
846
+ "const pickExport = (mod, exportName, componentName, path) => {",
847
+ " const resolved = exportName === 'default' ? mod?.default || mod : mod?.[exportName]",
848
+ " if (!resolved) {",
849
+ ' throw new Error(`[nuxt-content] Missing export "${exportName}" for component "${componentName}" in "${path}".`)',
850
+ " }",
851
+ " return resolved",
852
+ "}",
853
+ "export const localComponentLoaders = {",
854
+ ...localComponents.map(([pascalName, path, , exp]) => {
855
+ const pathLiteral = JSON.stringify(path);
856
+ const exportLiteral = JSON.stringify(exp);
857
+ const nameLiteral = JSON.stringify(pascalName);
858
+ return ` ${pascalName}: () => import(${pathLiteral}).then(mod => pickExport(mod, ${exportLiteral}, ${nameLiteral}, ${pathLiteral})),`;
859
+ }),
860
+ "}",
861
+ `export const globalComponents = ${JSON.stringify(globalComponents)}`,
862
+ `export const localComponents = ${JSON.stringify(localComponents.map((component) => component[0]))}`
863
+ ].join("\n");
864
+ }
865
+ });
866
+ };
867
+
868
+ const appendHook = (hooks, name, handler) => {
869
+ const existing = hooks[name];
870
+ if (!existing) {
871
+ hooks[name] = handler;
872
+ return;
873
+ }
874
+ hooks[name] = Array.isArray(existing) ? [...existing, handler] : [existing, handler];
875
+ };
876
+ const resolveSitemapCollections = (collections, sitemap) => {
877
+ if (!sitemap || sitemap === false) {
878
+ return [];
879
+ }
880
+ const include = sitemap.include?.length ? sitemap.include : Object.keys(collections);
881
+ const excluded = new Set(sitemap.exclude || []);
882
+ return include.filter((collection) => !excluded.has(collection) && collections[collection]?.sitemap !== false);
883
+ };
884
+ const numericSlugSegmentPattern = /^(\d+)\.[^*?[\]{}()]+(.*)$/;
885
+ const toTranslatedSlugSourcePattern = (source) => {
886
+ return source.split("/").map((segment) => {
887
+ const match = segment.match(numericSlugSegmentPattern);
888
+ return match ? `${match[1]}.*${match[2] || ""}` : segment;
889
+ }).join("/");
890
+ };
891
+ const parseCollectionFiles = async (rootDir, collections, collectionNames, contentContext) => {
892
+ const contentDir = resolve$1(rootDir, "content");
893
+ const patterns = Array.from(new Set(
894
+ collectionNames.flatMap((name) => {
895
+ const source = collections[name]?.source;
896
+ if (!source) {
897
+ return [];
898
+ }
899
+ const sources = normalizeCollectionSources(source);
900
+ const excludes = normalizeCollectionExcludes(collections[name]?.exclude);
901
+ const localeSources = contentContext.translatedSlugs ? Array.from(new Set(sources.flatMap((pattern) => [
902
+ pattern,
903
+ toTranslatedSlugSourcePattern(pattern)
904
+ ]))) : sources;
905
+ const localePatterns = (contentContext.locales || []).flatMap((locale) => localeSources.map((pattern) => `${locale}/${pattern}`));
906
+ const excludePatterns = excludes.flatMap((pattern) => [
907
+ `!${pattern}`,
908
+ ...(contentContext.locales || []).map((locale) => `!${locale}/${pattern}`)
909
+ ]);
910
+ return [...sources, ...localePatterns, ...excludePatterns];
911
+ }).filter(Boolean)
912
+ ));
913
+ const ids = await globby(patterns, {
914
+ cwd: contentDir,
915
+ onlyFiles: true,
916
+ dot: false
917
+ });
918
+ const documents = [];
919
+ for (const id of ids) {
920
+ const file = resolve$1(contentDir, id);
921
+ const content = await readFile(file, "utf8");
922
+ const normalizedId = `content:${relative$1(contentDir, file).replaceAll("\\", "/")}`;
923
+ const parsed = await transformContent(normalizedId, content, {
924
+ markdown: contentContext.markdown,
925
+ yaml: contentContext.yaml,
926
+ csv: contentContext.csv,
927
+ pathMeta: {
928
+ locales: contentContext.locales,
929
+ defaultLocale: contentContext.defaultLocale,
930
+ translatedSlugs: contentContext.translatedSlugs,
931
+ respectPathCase: contentContext.respectPathCase,
932
+ collections,
933
+ collectionResolver: (filePath) => resolveCollection(filePath, collections, contentContext.locales || [])
934
+ }
935
+ });
936
+ const collection = parsed._collection ? collections[parsed._collection] : void 0;
937
+ documents.push(...expandDataLocaleVariants(parsed, collection?.i18n));
938
+ }
939
+ return documents;
940
+ };
941
+ const collectPrerenderRoutes = async (rootDir, contentContext) => {
942
+ const collections = contentContext.collections || {};
943
+ if (!contentContext.sitemap || contentContext.sitemap === false) {
944
+ return [];
945
+ }
946
+ const includeCollections = resolveSitemapCollections(collections, contentContext.sitemap);
947
+ if (!includeCollections.length) {
948
+ return [];
949
+ }
950
+ const documents = await parseCollectionFiles(rootDir, collections, includeCollections, contentContext);
951
+ const graph = buildContentGraph(documents, {
952
+ locales: contentContext.locales,
953
+ defaultLocale: contentContext.defaultLocale
954
+ });
955
+ const routes = /* @__PURE__ */ new Set();
956
+ for (const collection of includeCollections) {
957
+ const { defaultLocale } = resolveCollectionI18n(collection, contentContext);
958
+ const includeDrafts = contentContext.sitemap && contentContext.sitemap !== false ? Boolean(contentContext.sitemap.includeDrafts) : false;
959
+ const seenCanonicalKeys = /* @__PURE__ */ new Set();
960
+ for (const contentId of graph.byCollection[collection] || []) {
961
+ const document = graph.byId[contentId];
962
+ if (!document || !document._canonicalKey || document._partial || document._navigation) {
963
+ continue;
964
+ }
965
+ if (document._draft && !includeDrafts) {
966
+ continue;
967
+ }
968
+ if (seenCanonicalKeys.has(document._canonicalKey)) {
969
+ continue;
970
+ }
971
+ seenCanonicalKeys.add(document._canonicalKey);
972
+ const variants = graph.byCanonical[document._canonicalKey] || {};
973
+ for (const [locale, variant] of Object.entries(variants)) {
974
+ if (!variant.path) {
975
+ continue;
976
+ }
977
+ const routeLocale = (contentContext.locales || []).includes(locale) ? locale : void 0;
978
+ routes.add(prefixPathWithLocale(variant.path, routeLocale, defaultLocale));
979
+ }
980
+ }
981
+ }
982
+ return Array.from(routes).sort();
983
+ };
984
+ const collectSitemapCollectionRouteCounts = async (rootDir, contentContext) => {
985
+ const collections = contentContext.collections || {};
986
+ const includedCollections = resolveSitemapCollections(collections, contentContext.sitemap);
987
+ if (!includedCollections.length) {
988
+ return {};
989
+ }
990
+ const documents = await parseCollectionFiles(rootDir, collections, includedCollections, contentContext);
991
+ const graph = buildContentGraph(documents, {
992
+ locales: contentContext.locales,
993
+ defaultLocale: contentContext.defaultLocale
994
+ });
995
+ const counts = Object.fromEntries(includedCollections.map((collection) => [collection, 0]));
996
+ const includeDrafts = contentContext.sitemap && contentContext.sitemap !== false ? Boolean(contentContext.sitemap.includeDrafts) : false;
997
+ for (const collection of includedCollections) {
998
+ const seenCanonicalKeys = /* @__PURE__ */ new Set();
999
+ for (const contentId of graph.byCollection[collection] || []) {
1000
+ const document = graph.byId[contentId];
1001
+ if (!document || !document._canonicalKey || document._partial || document._navigation) {
1002
+ continue;
1003
+ }
1004
+ if (document._draft && !includeDrafts) {
1005
+ continue;
1006
+ }
1007
+ if (seenCanonicalKeys.has(document._canonicalKey)) {
1008
+ continue;
1009
+ }
1010
+ const variants = Object.values(graph.byCanonical[document._canonicalKey] || {});
1011
+ if (!variants.some((variant) => variant.path)) {
1012
+ continue;
1013
+ }
1014
+ seenCanonicalKeys.add(document._canonicalKey);
1015
+ counts[collection] += 1;
1016
+ }
1017
+ }
1018
+ return counts;
1019
+ };
1020
+ const registerContentNitroIntegrationHooks = (nitroConfig, options, contentContext) => {
1021
+ if (contentContext.provider && contentContext.provider !== "filesystem") {
1022
+ return;
1023
+ }
1024
+ nitroConfig.hooks ||= {};
1025
+ if (contentContext.sitemap?.assert?.enabled) {
1026
+ appendHook(nitroConfig.hooks, "compiled", async (nitro) => {
1027
+ const assertOptions = contentContext.sitemap?.assert;
1028
+ if (!assertOptions || !shouldRunSitemapAssertionOnCompiled(assertOptions, nitro)) {
1029
+ return;
1030
+ }
1031
+ try {
1032
+ await assertGeneratedSitemaps({
1033
+ outputPublicDir: nitro.options.output.publicDir,
1034
+ options: assertOptions,
1035
+ collectionRouteCounts: await collectSitemapCollectionRouteCounts(options.rootDir, contentContext),
1036
+ logger: nitro.logger
1037
+ });
1038
+ } catch (error) {
1039
+ if (error?.code === "ENOENT") {
1040
+ return;
1041
+ }
1042
+ throw error;
1043
+ }
1044
+ });
1045
+ }
1046
+ appendHook(nitroConfig.hooks, "prerender:routes", async (routes) => {
1047
+ for (const route of await collectPrerenderRoutes(options.rootDir, contentContext)) {
1048
+ routes.add(route);
1049
+ }
1050
+ for (const route of options.sitemapPrerenderRoutes || []) {
1051
+ routes.add(route);
1052
+ }
1053
+ });
1054
+ };
1055
+
1056
+ const module$1 = defineNuxtModule({
1057
+ meta: {
1058
+ name,
1059
+ version,
1060
+ configKey: "content",
1061
+ compatibility: {
1062
+ nuxt: ">=4.0.0"
1063
+ }
1064
+ },
1065
+ moduleDependencies: {
1066
+ "@nuxt/ui": {
1067
+ optional: true,
1068
+ defaults: {
1069
+ content: true,
1070
+ prose: true
1071
+ }
1072
+ }
1073
+ },
1074
+ defaults: {
1075
+ api: {
1076
+ baseURL: "/api/_content"
1077
+ },
1078
+ i18n: true,
1079
+ sitemap: true,
1080
+ search: {
1081
+ engine: "minisearch",
1082
+ ignoredTags: ["script", "style", "pre"],
1083
+ filterQuery: { _draft: false, _partial: false },
1084
+ extraFields: [],
1085
+ minisearch: {
1086
+ fields: ["title", "content", "headings"],
1087
+ storeFields: ["path", "title", "excerpt", "anchor", "locale"],
1088
+ boost: {
1089
+ title: 4,
1090
+ headings: 2,
1091
+ content: 1
1092
+ },
1093
+ fuzzy: 0.2,
1094
+ prefix: true
1095
+ }
1096
+ },
1097
+ watch: {
1098
+ ws: {
1099
+ port: {
1100
+ port: 4e3,
1101
+ portRange: [4e3, 4040]
1102
+ },
1103
+ hostname: "localhost",
1104
+ showURL: false
1105
+ }
1106
+ },
1107
+ sources: {},
1108
+ ignores: [],
1109
+ collections: {},
1110
+ markdown: {
1111
+ plugins: [],
1112
+ tags: {
1113
+ code: "ProseCode",
1114
+ img: "ProseImg",
1115
+ pre: "ProsePre"
1116
+ },
1117
+ anchorLinks: {
1118
+ depth: 4,
1119
+ exclude: [1]
1120
+ },
1121
+ image: "auto"
1122
+ },
1123
+ yaml: {},
1124
+ csv: {
1125
+ delimiter: ",",
1126
+ json: true
1127
+ },
1128
+ navigation: {
1129
+ fields: []
1130
+ },
1131
+ contentHead: true,
1132
+ respectPathCase: false,
1133
+ experimental: {
1134
+ stripQueryParameters: false
1135
+ }
1136
+ },
1137
+ async setup(options, nuxt) {
1138
+ const { resolve, resolvePath } = createResolver(import.meta.url);
1139
+ const logger = useLogger(name);
1140
+ const resolveRuntimeModule = (path) => resolve("./runtime", path);
1141
+ const runtimeInlineDependencies = ["comark", "@comark/vue"];
1142
+ validateRemovedMarkdownOptions(options);
1143
+ nuxt.options.build.transpile ||= [];
1144
+ for (const dependency of runtimeInlineDependencies) {
1145
+ if (!nuxt.options.build.transpile.includes(dependency)) {
1146
+ nuxt.options.build.transpile.push(dependency);
1147
+ }
1148
+ }
1149
+ nuxt.options.vite = nuxt.options.vite || {};
1150
+ nuxt.options.vite.ssr = defu(nuxt.options.vite.ssr || {}, {
1151
+ noExternal: runtimeInlineDependencies
1152
+ });
1153
+ const contentConfigPath = resolveContentConfigPath(nuxt);
1154
+ const appContentConfig = await loadContentConfig(nuxt);
1155
+ if (!contentConfigPath || !appContentConfig.collections || !Object.keys(appContentConfig.collections).length) {
1156
+ throw new Error("@lupinum/ginko-content requires a content.config.ts with at least one collection. Define collections with defineContentConfig({ collections: { ... } }).");
1157
+ }
1158
+ const resolvedI18n = resolveModuleI18nOptions(options, nuxt);
1159
+ const resolvedSitemap = normalizeSitemapOptions(options);
1160
+ const resolvedSearch = normalizeSearchOptions(options);
1161
+ options.collections = Object.fromEntries(Object.entries(appContentConfig.collections).map(([name2, collection]) => [
1162
+ name2,
1163
+ {
1164
+ ...collection,
1165
+ i18n: resolveCollectionI18nConfig(
1166
+ collection,
1167
+ resolvedI18n.defaultLocale && resolvedI18n.locales.length ? { defaultLocale: resolvedI18n.defaultLocale, locales: resolvedI18n.locales } : void 0,
1168
+ { warnMissingGlobal: true }
1169
+ )
1170
+ }
1171
+ ]));
1172
+ options.provider = appContentConfig.provider || options.provider || "filesystem";
1173
+ options.providers = {
1174
+ ...options.providers || {},
1175
+ ...appContentConfig.providers || {}
1176
+ };
1177
+ const buildIntegrity = nuxt.options.dev ? void 0 : Date.now();
1178
+ const contentContext = {
1179
+ ...options,
1180
+ transformers: [],
1181
+ locales: resolvedI18n.locales,
1182
+ defaultLocale: resolvedI18n.defaultLocale,
1183
+ localeFallback: resolvedI18n.fallback,
1184
+ translatedSlugs: resolvedI18n.translatedSlugs,
1185
+ strictTranslatedSlugs: resolvedI18n.strictTranslatedSlugs,
1186
+ sitemap: resolvedSitemap,
1187
+ search: resolvedSearch
1188
+ };
1189
+ if (resolvedSitemap && resolvedSitemap.assert.enabled) {
1190
+ nuxt.hook("sitemap:prerender:done", async ({ sitemaps }) => {
1191
+ const assertOptions = contentContext.sitemap?.assert;
1192
+ if (!assertOptions || !shouldRunSitemapAssertionOnPrerenderedSitemaps(assertOptions)) {
1193
+ return;
1194
+ }
1195
+ await assertGeneratedSitemaps({
1196
+ options: assertOptions,
1197
+ targets: createSitemapAssertionTargetsFromPrerenderedSitemaps(sitemaps),
1198
+ collectionRouteCounts: await collectSitemapCollectionRouteCounts(nuxt.options.rootDir, contentContext),
1199
+ logger
1200
+ });
1201
+ });
1202
+ }
1203
+ const { transformersTemplate, virtualConfigTemplate, virtualProvidersTemplate, virtualCacheAdapterTemplate } = createVirtualContentTemplates(contentContext, nuxt, contentConfigPath, addTemplate);
1204
+ registerVirtualContentAliases(nuxt, transformersTemplate, virtualConfigTemplate, virtualProvidersTemplate, virtualCacheAdapterTemplate, resolveRuntimeModule);
1205
+ registerContentServerHandlers(nuxt, options, resolveRuntimeModule, buildIntegrity);
1206
+ registerContentI18nTemplate(addTemplate, hasNuxtI18nModule(nuxt.options.modules));
1207
+ registerRuntimeImports(resolveRuntimeModule);
1208
+ registerRuntimeComponents(resolve);
1209
+ registerContentComponentsTemplate(addTemplate);
1210
+ registerGeneratedTypes(contentConfigPath, resolveRuntimeModule);
1211
+ await registerUserContentComponents(nuxt, resolve);
1212
+ const getSearchRuntime = () => contentContext.search === false ? false : createSearchRuntimeConfig(contentContext.search, options.api.baseURL);
1213
+ nuxt.hook("nitro:config", (nitroConfig) => {
1214
+ const searchRuntime = getSearchRuntime();
1215
+ nitroConfig.prerender = nitroConfig.prerender || {};
1216
+ nitroConfig.prerender.routes = nitroConfig.prerender.routes || [];
1217
+ const usesFilesystemProvider = !contentContext.provider || contentContext.provider === "filesystem";
1218
+ if (!nuxt.options.dev && usesFilesystemProvider) {
1219
+ nitroConfig.prerender.routes.unshift(`${options.api.baseURL}/cache.${buildIntegrity}.json`);
1220
+ }
1221
+ const sources = useContentMounts(nuxt, contentContext.sources);
1222
+ nitroConfig.devStorage = Object.assign(nitroConfig.devStorage || {}, sources);
1223
+ nitroConfig.devStorage["cache:content"] = {
1224
+ driver: "fs",
1225
+ base: resolve(nuxt.options.buildDir, "content-cache")
1226
+ };
1227
+ for (const source of Object.values(sources)) {
1228
+ if (source.driver === "fs" && source.base.includes(nuxt.options.srcDir)) {
1229
+ const wildcard = join(source.base, "**/*").replace(withTrailingSlash(nuxt.options.srcDir), "");
1230
+ nuxt.options.ignore.push(
1231
+ // Remove `srcDir` from the path
1232
+ wildcard,
1233
+ `!${wildcard}.vue`
1234
+ );
1235
+ }
1236
+ }
1237
+ nitroConfig.bundledStorage = nitroConfig.bundledStorage || [];
1238
+ nitroConfig.bundledStorage.push("cache:content");
1239
+ nitroConfig.externals = defu(typeof nitroConfig.externals === "object" ? nitroConfig.externals : {}, {
1240
+ inline: [
1241
+ resolve("./runtime"),
1242
+ ...runtimeInlineDependencies
1243
+ ]
1244
+ });
1245
+ if (searchRuntime !== false && searchRuntime.engine !== "cms" && usesFilesystemProvider) {
1246
+ nitroConfig.routeRules = nitroConfig.routeRules || {};
1247
+ nitroConfig.routeRules[searchRuntime.indexURL] = {
1248
+ prerender: true,
1249
+ headers: { "Content-Type": "application/json; charset=utf-8" }
1250
+ };
1251
+ }
1252
+ if (contentContext.sitemap !== false) {
1253
+ nitroConfig.plugins ||= [];
1254
+ const sitemapPlugin = resolveRuntimeModule("server/plugins/sitemap.js");
1255
+ if (!nitroConfig.plugins.includes(sitemapPlugin)) {
1256
+ nitroConfig.plugins.push(sitemapPlugin);
1257
+ }
1258
+ }
1259
+ if (contentContext.cache && contentContext.cache !== false) {
1260
+ nitroConfig.plugins ||= [];
1261
+ const cachePlugin = resolveRuntimeModule("server/plugins/cache.js");
1262
+ if (!nitroConfig.plugins.includes(cachePlugin)) {
1263
+ nitroConfig.plugins.push(cachePlugin);
1264
+ }
1265
+ }
1266
+ registerContentNitroIntegrationHooks(nitroConfig, {
1267
+ rootDir: nuxt.options.rootDir,
1268
+ sitemapPrerenderRoutes: contentContext.sitemap === false ? [] : resolveNuxtSitemapPrerenderRoutes(nuxt)
1269
+ }, {
1270
+ collections: contentContext.collections,
1271
+ locales: contentContext.locales,
1272
+ defaultLocale: contentContext.defaultLocale,
1273
+ translatedSlugs: contentContext.translatedSlugs,
1274
+ strictTranslatedSlugs: contentContext.strictTranslatedSlugs,
1275
+ respectPathCase: contentContext.respectPathCase,
1276
+ markdown: contentContext.markdown,
1277
+ yaml: contentContext.yaml,
1278
+ csv: contentContext.csv,
1279
+ sitemap: contentContext.sitemap,
1280
+ provider: contentContext.provider
1281
+ });
1282
+ });
1283
+ if (!nuxt.options.dev) {
1284
+ nuxt.hook("nitro:build:before", (nitro) => {
1285
+ nitro.hooks.hook("prerender:init", (prerenderer) => {
1286
+ prerenderer.hooks.hook("compiled", async () => {
1287
+ const searchRuntime = getSearchRuntime();
1288
+ if (searchRuntime === false || searchRuntime.engine === "cms" || contentContext.provider && contentContext.provider !== "filesystem") {
1289
+ return;
1290
+ }
1291
+ const publicDir = nitro.options.output.publicDir || nuxt.options.nitro.output?.publicDir || resolve$1(nuxt.options.rootDir, ".output/public");
1292
+ const serverFilename = typeof prerenderer.options.rollupConfig?.output?.entryFileNames === "string" ? prerenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
1293
+ const serverEntrypoint = resolve$1(prerenderer.options.output.serverDir, serverFilename);
1294
+ const { localFetch } = await import(pathToFileURL(serverEntrypoint).href);
1295
+ const response = await localFetch(searchRuntime.indexURL);
1296
+ if (!response.ok) {
1297
+ throw new Error(`Failed to generate search index: [${response.status}] ${response.statusText}`);
1298
+ }
1299
+ const json = await response.text();
1300
+ const indexPath = join(publicDir, searchRuntime.indexURL.replace(/^\//, ""));
1301
+ mkdirSync(dirname(indexPath), { recursive: true });
1302
+ writeFileSync(indexPath, json, "utf8");
1303
+ if (searchRuntime.engine === "pagefind") {
1304
+ const records = JSON.parse(json);
1305
+ const { writePagefindIndex } = await import(resolveRuntimeModule("./server/pagefind.js"));
1306
+ await writePagefindIndex(records, resolve$1(publicDir, "pagefind"));
1307
+ }
1308
+ });
1309
+ });
1310
+ });
1311
+ }
1312
+ nuxt.hook("modules:done", async () => {
1313
+ await nuxt.callHook("content:context", contentContext);
1314
+ if (contentContext.search !== false) {
1315
+ registerContentSearchServerHandlers(options.api.baseURL, contentContext.search, resolveRuntimeModule);
1316
+ }
1317
+ contentContext.defaultLocale = contentContext.defaultLocale || contentContext.locales[0];
1318
+ contentContext.markdown = processMarkdownOptions(contentContext.markdown);
1319
+ await validateBuiltinMarkdownPlugins(contentContext.markdown.plugins, resolvePath);
1320
+ const runtimeCollections = Object.fromEntries(Object.entries(options.collections || {}).map(([name2, collection]) => [
1321
+ name2,
1322
+ {
1323
+ ...collection.source ? { source: collection.source } : {},
1324
+ ...collection.exclude ? { exclude: collection.exclude } : {},
1325
+ strict: collection.strict ?? true,
1326
+ ...collection.route ? { route: collection.route } : {},
1327
+ ...typeof collection.sitemap === "boolean" ? { sitemap: collection.sitemap } : {},
1328
+ ...collection.i18n && collection.i18n !== true ? { i18n: collection.i18n } : {}
1329
+ }
1330
+ ]));
1331
+ const cacheIntegrity = hash({
1332
+ locales: contentContext.locales,
1333
+ defaultLocale: contentContext.defaultLocale,
1334
+ localeFallback: contentContext.localeFallback,
1335
+ translatedSlugs: contentContext.translatedSlugs,
1336
+ strictTranslatedSlugs: contentContext.strictTranslatedSlugs,
1337
+ respectPathCase: contentContext.respectPathCase,
1338
+ collections: runtimeCollections,
1339
+ markdown: contentContext.markdown,
1340
+ yaml: contentContext.yaml,
1341
+ csv: contentContext.csv
1342
+ });
1343
+ applyContentRuntimeConfig(nuxt, options, contentContext, runtimeCollections, buildIntegrity, cacheIntegrity);
1344
+ });
1345
+ if (nuxt.options.dev) {
1346
+ registerDevRuntimePlugin(resolveRuntimeModule);
1347
+ registerContentDevRuntime(nuxt, options, contentContext);
1348
+ }
1349
+ }
1350
+ });
1351
+ function validateRemovedMarkdownOptions(options) {
1352
+ if (options.highlight !== void 0) {
1353
+ throw new Error("`content.highlight` was removed. Enable syntax highlighting with `content.markdown.plugins`, for example `[['highlight', { ...options }]]`.");
1354
+ }
1355
+ const markdown = options.markdown || {};
1356
+ const removedOptions = ["mdc", "remarkPlugins", "rehypePlugins", "toc"];
1357
+ const removed = removedOptions.filter((key) => typeof markdown[key] !== "undefined");
1358
+ if (removed.length) {
1359
+ throw new Error(`Removed markdown options: ${removed.map((option) => `content.markdown.${String(option)}`).join(", ")}. Use ordered \`content.markdown.plugins\` entries instead.`);
1360
+ }
1361
+ }
1362
+ async function validateBuiltinMarkdownPlugins(plugins, resolvePath) {
1363
+ for (const plugin of plugins) {
1364
+ const peerDependency = BUILTIN_PLUGIN_PEER_DEPS[plugin.name];
1365
+ if (!peerDependency) {
1366
+ continue;
1367
+ }
1368
+ try {
1369
+ await resolvePath(peerDependency);
1370
+ } catch (error) {
1371
+ throw new Error(`Markdown plugin "${plugin.name}" requires "${peerDependency}" to be installed.`, { cause: error });
1372
+ }
1373
+ }
1374
+ }
1375
+ const BUILTIN_PLUGIN_PEER_DEPS = {
1376
+ highlight: "shiki",
1377
+ math: "katex",
1378
+ mermaid: "beautiful-mermaid"
1379
+ };
1380
+
1381
+ export { module$1 as default };