@lupinum/ginko-content 0.1.5 → 0.2.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 (230) hide show
  1. package/compatibility.json +1 -1
  2. package/dist/cli.mjs +2 -2
  3. package/dist/cms-contract/build.js +15 -20
  4. package/dist/cms-contract/types.d.ts +12 -7
  5. package/dist/core/content/document +1 -0
  6. package/dist/core/content/document.d.ts +16 -0
  7. package/dist/core/content/document.js +2 -0
  8. package/dist/core/content/graph.d.ts +3 -1
  9. package/dist/core/content/graph.js +21 -20
  10. package/dist/core/content/locale.d.ts +6 -1
  11. package/dist/core/content/locale.js +17 -6
  12. package/dist/core/content/path.d.ts +5 -5
  13. package/dist/core/content/path.js +8 -8
  14. package/dist/core/content/snapshot +1 -0
  15. package/dist/core/content/snapshot.d.ts +25 -0
  16. package/dist/core/content/snapshot.js +99 -0
  17. package/dist/core/provider-errors.d.ts +1 -1
  18. package/dist/core/provider-errors.js +1 -0
  19. package/dist/core/query/builder.js +3 -3
  20. package/dist/core/query/execute.js +75 -36
  21. package/dist/core/query/filter.js +2 -2
  22. package/dist/core/query/lower.js +79 -3
  23. package/dist/core/query/params.js +7 -7
  24. package/dist/core/query/plan.d.ts +18 -0
  25. package/dist/core/query/plan.js +7 -0
  26. package/dist/core/references/resolve.js +6 -9
  27. package/dist/features/agent/agent-markdown +1 -0
  28. package/dist/features/agent/agent-markdown.d.ts +116 -0
  29. package/dist/features/agent/agent-markdown.js +138 -0
  30. package/dist/features/agent/walker +1 -0
  31. package/dist/features/agent/walker.d.ts +10 -0
  32. package/dist/features/agent/walker.js +174 -0
  33. package/dist/features/collections/resolve.d.ts +2 -2
  34. package/dist/features/collections/resolve.js +19 -16
  35. package/dist/features/localization/links.js +1 -1
  36. package/dist/features/localization/results.d.ts +3 -3
  37. package/dist/features/localization/results.js +46 -41
  38. package/dist/features/localization/translated-slugs.js +5 -5
  39. package/dist/features/navigation/build.d.ts +2 -2
  40. package/dist/features/navigation/build.js +23 -26
  41. package/dist/features/navigation/canonical.d.ts +10 -11
  42. package/dist/features/navigation/canonical.js +26 -21
  43. package/dist/features/navigation/resolve.js +4 -4
  44. package/dist/features/navigation/tree.js +3 -3
  45. package/dist/{runtime → features}/query/backlinks.js +3 -5
  46. package/dist/{runtime → features}/query/documents.js +1 -1
  47. package/dist/{runtime → features}/query/localized-docs.d.ts +1 -1
  48. package/dist/{runtime → features}/query/localized-docs.js +3 -6
  49. package/dist/{runtime → features}/query/navigation.d.ts +1 -1
  50. package/dist/{runtime → features}/query/navigation.js +8 -8
  51. package/dist/{runtime → features}/query/populate.js +6 -14
  52. package/dist/{runtime → features}/query/unified.d.ts +4 -4
  53. package/dist/{runtime → features}/query/unified.js +4 -2
  54. package/dist/{runtime → features}/query/variants.js +4 -4
  55. package/dist/features/search/navigation.js +2 -2
  56. package/dist/features/search/sections.d.ts +1 -1
  57. package/dist/features/search/sections.js +1 -1
  58. package/dist/features/sitemap/query.d.ts +5 -5
  59. package/dist/features/sitemap/query.js +6 -6
  60. package/dist/integrations/nitro/ingest.js +9 -20
  61. package/dist/integrations/nitro/storage.d.ts +1 -0
  62. package/dist/integrations/nitro/storage.js +21 -34
  63. package/dist/module.d.mts +135 -803
  64. package/dist/module.json +1 -1
  65. package/dist/module.mjs +143 -51
  66. package/dist/parsers/csv.js +3 -3
  67. package/dist/parsers/index.js +3 -3
  68. package/dist/parsers/json.js +8 -6
  69. package/dist/parsers/markdown-plugins.js +9 -5
  70. package/dist/parsers/markdown.js +7 -6
  71. package/dist/parsers/path-meta.js +21 -19
  72. package/dist/parsers/reserved +1 -0
  73. package/dist/parsers/reserved.d.ts +15 -0
  74. package/dist/parsers/reserved.js +35 -0
  75. package/dist/parsers/yaml.js +6 -4
  76. package/dist/public/agent +1 -0
  77. package/dist/public/agent.d.ts +17 -0
  78. package/dist/public/agent.js +34 -0
  79. package/dist/public/client.d.ts +2 -3
  80. package/dist/public/client.js +1 -2
  81. package/dist/public/provider-query +1 -0
  82. package/dist/public/provider-query.d.ts +58 -0
  83. package/dist/public/provider-query.js +5 -0
  84. package/dist/public/provider.d.ts +8 -3
  85. package/dist/public/provider.js +2 -0
  86. package/dist/public/server.d.ts +7 -12
  87. package/dist/public/server.js +5 -36
  88. package/dist/runtime/app/components/ContentRenderer.d.vue.ts +3 -3
  89. package/dist/runtime/app/components/ContentRenderer.vue +2 -2
  90. package/dist/runtime/app/components/ContentRenderer.vue.d.ts +3 -3
  91. package/dist/runtime/app/components/ContentRendererInline.d.vue.ts +1 -1
  92. package/dist/runtime/app/components/ContentRendererInline.vue.d.ts +1 -1
  93. package/dist/runtime/app/components/Prose/ProseImg.d.vue.ts +4 -4
  94. package/dist/runtime/app/components/Prose/ProseImg.vue.d.ts +4 -4
  95. package/dist/runtime/app/components/Prose/ProsePre.d.vue.ts +1 -1
  96. package/dist/runtime/app/components/Prose/ProsePre.vue.d.ts +1 -1
  97. package/dist/runtime/app/components/internal/ContentRendererMarkdown.d.vue.ts +1 -1
  98. package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue +4 -4
  99. package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue.d.ts +1 -1
  100. package/dist/runtime/app/components/internal/MarkdownRenderer.d.ts +3 -3
  101. package/dist/runtime/app/composables/preview.d.ts +1 -1
  102. package/dist/runtime/app/composables/query-api.d.ts +5 -5
  103. package/dist/runtime/app/composables/query-api.js +5 -3
  104. package/dist/runtime/app/composables/route.d.ts +1 -1
  105. package/dist/runtime/app/composables/route.js +4 -4
  106. package/dist/runtime/app/composables/search.js +1 -1
  107. package/dist/runtime/app/composables/use-content-document.js +1 -1
  108. package/dist/runtime/app/composables/use-content-list.js +1 -1
  109. package/dist/runtime/app/composables/use-content-navigation.js +2 -2
  110. package/dist/runtime/app/composables/use-content-page.js +4 -4
  111. package/dist/runtime/app/pages/content.vue +2 -1
  112. package/dist/runtime/markdown/plugins.js +6 -8
  113. package/dist/runtime/server/agent-markdown.d.ts +5 -65
  114. package/dist/runtime/server/agent-markdown.js +40 -315
  115. package/dist/runtime/server/agent-site.js +9 -2
  116. package/dist/runtime/server/api/agent-raw.js +1 -1
  117. package/dist/runtime/server/api/cache.d.ts +1 -1
  118. package/dist/runtime/server/api/cache.js +43 -4
  119. package/dist/runtime/server/api/locales.js +3 -3
  120. package/dist/runtime/server/api/navigation.d.ts +1 -1
  121. package/dist/runtime/server/api/navigation.js +3 -1
  122. package/dist/runtime/server/api/query.js +2 -2
  123. package/dist/runtime/server/api/search-index.d.ts +1 -1
  124. package/dist/runtime/server/api/sitemap.d.ts +1 -1
  125. package/dist/runtime/server/cache-adapters.d.ts +18 -0
  126. package/dist/runtime/server/cache-adapters.js +12 -0
  127. package/dist/runtime/server/collection-helpers.d.ts +2 -2
  128. package/dist/runtime/server/collection-helpers.js +15 -11
  129. package/dist/runtime/server/index.d.ts +6 -4
  130. package/dist/runtime/server/index.js +10 -3
  131. package/dist/runtime/server/middleware/agent-link-headers.js +1 -1
  132. package/dist/runtime/server/middleware/agent-markdown.js +1 -1
  133. package/dist/runtime/server/navigation-query.d.ts +2 -2
  134. package/dist/runtime/server/navigation-query.js +52 -7
  135. package/dist/runtime/server/navigation.d.ts +1 -1
  136. package/dist/runtime/server/provider-document +1 -0
  137. package/dist/runtime/server/provider-document.d.ts +59 -0
  138. package/dist/runtime/server/provider-document.js +48 -0
  139. package/dist/runtime/server/provider-query-wire +1 -0
  140. package/dist/runtime/server/provider-query-wire.d.ts +32 -0
  141. package/dist/runtime/server/provider-query-wire.js +27 -0
  142. package/dist/runtime/server/provider-query.d.ts +18 -9
  143. package/dist/runtime/server/provider-query.js +62 -28
  144. package/dist/runtime/server/provider-result.d.ts +4 -4
  145. package/dist/runtime/server/providers/filesystem.js +3 -11
  146. package/dist/runtime/server/providers/index.d.ts +18 -1
  147. package/dist/runtime/server/providers/index.js +72 -20
  148. package/dist/runtime/server/query-api.d.ts +5 -5
  149. package/dist/runtime/server/query-api.js +9 -6
  150. package/dist/runtime/server/query-executor.d.ts +3 -3
  151. package/dist/runtime/server/query-executor.js +43 -59
  152. package/dist/runtime/server/search.d.ts +1 -1
  153. package/dist/runtime/server/search.js +4 -4
  154. package/dist/runtime/server/sitemap.js +5 -5
  155. package/dist/runtime/server/storage-access.d.ts +4 -1
  156. package/dist/runtime/server/storage-access.js +27 -2
  157. package/dist/runtime/transformers/component-resolver.d.ts +1 -1
  158. package/dist/storage/content.d.ts +2 -6
  159. package/dist/storage/content.js +19 -8
  160. package/dist/storage/contents.d.ts +9 -1
  161. package/dist/storage/contents.js +26 -19
  162. package/dist/storage/driver.d.ts +2 -2
  163. package/dist/storage/driver.js +2 -1
  164. package/dist/storage/graph.js +4 -0
  165. package/dist/storage/manifest.js +3 -1
  166. package/dist/storage/references.js +9 -5
  167. package/dist/storage/snapshot-runtime +1 -0
  168. package/dist/storage/snapshot-runtime.d.ts +11 -0
  169. package/dist/storage/snapshot-runtime.js +46 -0
  170. package/dist/storage/validation.d.ts +1 -1
  171. package/dist/storage/validation.js +79 -105
  172. package/dist/testing/provider-contract.d.ts +14 -4
  173. package/dist/testing/provider-contract.js +121 -68
  174. package/dist/testing/provider-fixture.d.ts +1 -1
  175. package/dist/testing/provider-fixture.js +124 -120
  176. package/dist/types/config.d.ts +17 -4
  177. package/dist/types/content.d.ts +104 -70
  178. package/dist/types/fields.js +1 -1
  179. package/dist/types/module.d.ts +1 -1
  180. package/dist/types/query-parts/public.d.ts +14 -5
  181. package/dist/types/query-parts/results.d.ts +6 -2
  182. package/dist/types/query-parts/transport.d.ts +19 -0
  183. package/dist/types/virtual.d.ts +6 -0
  184. package/dist/types.d.mts +2 -2
  185. package/dist/web-types.json +1 -1
  186. package/package.json +39 -9
  187. package/dist/runtime/app/plugins/markdown-components +0 -1
  188. package/dist/runtime/app/plugins/markdown-components.d.ts +0 -2
  189. package/dist/runtime/app/plugins/markdown-components.js +0 -19
  190. /package/dist/{runtime → features/agent}/agent-paths +0 -0
  191. /package/dist/{runtime → features/agent}/agent-paths.d.ts +0 -0
  192. /package/dist/{runtime → features/agent}/agent-paths.js +0 -0
  193. /package/dist/{runtime → features}/query/backlinks +0 -0
  194. /package/dist/{runtime → features}/query/backlinks.d.ts +0 -0
  195. /package/dist/{runtime → features}/query/context +0 -0
  196. /package/dist/{runtime → features}/query/context.d.ts +0 -0
  197. /package/dist/{runtime → features}/query/context.js +0 -0
  198. /package/dist/{runtime → features}/query/documents +0 -0
  199. /package/dist/{runtime → features}/query/documents.d.ts +0 -0
  200. /package/dist/{runtime → features}/query/errors +0 -0
  201. /package/dist/{runtime → features}/query/errors.d.ts +0 -0
  202. /package/dist/{runtime → features}/query/errors.js +0 -0
  203. /package/dist/{runtime → features}/query/handles +0 -0
  204. /package/dist/{runtime → features}/query/handles.d.ts +0 -0
  205. /package/dist/{runtime → features}/query/handles.js +0 -0
  206. /package/dist/{runtime → features}/query/locale-options +0 -0
  207. /package/dist/{runtime → features}/query/locale-options.d.ts +0 -0
  208. /package/dist/{runtime → features}/query/locale-options.js +0 -0
  209. /package/dist/{runtime → features}/query/localized-docs +0 -0
  210. /package/dist/{runtime → features}/query/navigation +0 -0
  211. /package/dist/{runtime → features}/query/pagination +0 -0
  212. /package/dist/{runtime → features}/query/pagination.d.ts +0 -0
  213. /package/dist/{runtime → features}/query/pagination.js +0 -0
  214. /package/dist/{runtime → features}/query/populate +0 -0
  215. /package/dist/{runtime → features}/query/populate.d.ts +0 -0
  216. /package/dist/{runtime → features}/query/public-limits +0 -0
  217. /package/dist/{runtime → features}/query/public-limits.d.ts +0 -0
  218. /package/dist/{runtime → features}/query/public-limits.js +0 -0
  219. /package/dist/{runtime → features}/query/resolve +0 -0
  220. /package/dist/{runtime → features}/query/resolve.d.ts +0 -0
  221. /package/dist/{runtime → features}/query/resolve.js +0 -0
  222. /package/dist/{runtime → features}/query/responses +0 -0
  223. /package/dist/{runtime → features}/query/responses.d.ts +0 -0
  224. /package/dist/{runtime → features}/query/responses.js +0 -0
  225. /package/dist/{runtime → features}/query/routes +0 -0
  226. /package/dist/{runtime → features}/query/routes.d.ts +0 -0
  227. /package/dist/{runtime → features}/query/routes.js +0 -0
  228. /package/dist/{runtime → features}/query/unified +0 -0
  229. /package/dist/{runtime → features}/query/variants +0 -0
  230. /package/dist/{runtime → features}/query/variants.d.ts +0 -0
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lupinum/ginko-content",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "configKey": "content",
5
5
  "compatibility": {
6
6
  "nuxt": ">=4.0.0"
package/dist/module.mjs CHANGED
@@ -22,15 +22,16 @@ import { transformContent } from '../dist/parsers/index';
22
22
  import { resolveCollectionI18n, prefixPathWithLocale } from '../dist/features/localization/path';
23
23
  import { resolveContentSitemapSource, GINKO_SITEMAP_SOURCE_NAME } from '../dist/runtime/utils/sitemap-source';
24
24
  import { normalizeRouteMounts, normalizeContentPath } from '../dist/core/content/path';
25
- import { mkdirSync, writeFileSync } from 'node:fs';
25
+ import { mkdirSync, writeFileSync, readFileSync } from 'node:fs';
26
26
  import { pathToFileURL } from 'node:url';
27
+ import { isContentSnapshot } from '../dist/core/content/snapshot';
27
28
  import { withTrailingSlash } from 'ufo';
28
29
  import { normalizeContentConfigCollectionNames } from '../dist/types/config';
29
30
  export { agentMetadataFields, defineAgentAppPage, defineAgentMarkdownPolicy, defineAgentMetadataFields, defineAgentSection, defineCollection, defineContentConfig, reference } from '../dist/types/config';
30
31
  import { collectTopLevelReferenceFieldsByTarget } from '../dist/core/references/schema';
31
32
 
32
33
  const name = "@lupinum/ginko-content";
33
- const version = "0.1.5";
34
+ const version = "0.2.0";
34
35
 
35
36
  const CONFIG_FILES = [
36
37
  "content.config.ts",
@@ -58,7 +59,7 @@ const createVirtualContentTemplates = (contentContext, nuxt, contentConfigPath,
58
59
  write: true,
59
60
  getContents: () => {
60
61
  const transformers = contentContext.transformers.map((transformer) => {
61
- const name = genSafeVariableName(relative(nuxt.options.rootDir, transformer)).replace(/_(45|46|47)/g, "_") + "_" + hash(transformer);
62
+ const name = genSafeVariableName(relative(nuxt.options.rootDir, transformer)).replace(/_(45|46|47)/g, "_") + "_" + hash(transformer).replace(/[^a-z0-9_$]/gi, "_");
62
63
  return { name, import: genImport(transformer, name) };
63
64
  });
64
65
  return [
@@ -73,10 +74,15 @@ const createVirtualContentTemplates = (contentContext, nuxt, contentConfigPath,
73
74
  const virtualConfigTemplate = addTemplateImpl({
74
75
  filename: "content/virtual-config.mjs",
75
76
  write: true,
76
- getContents: () => contentConfigPath ? [
77
- `import config from ${JSON.stringify(contentConfigPath)}`,
78
- "export default config || {}"
79
- ].join("\n") : "export default {}"
77
+ getContents: () => {
78
+ if (!contentConfigPath) {
79
+ return "export default {}";
80
+ }
81
+ return [
82
+ `import config from ${JSON.stringify(contentConfigPath)}`,
83
+ "export default config"
84
+ ].join("\n");
85
+ }
80
86
  }).dst;
81
87
  const virtualProvidersTemplate = addTemplateImpl({
82
88
  filename: "content/virtual-providers.mjs",
@@ -260,10 +266,14 @@ const generatedContentServerValueNames = [
260
266
  "contentCacheHeaders",
261
267
  "noopContentCache",
262
268
  "vercelContentCache",
269
+ "headersContentCache",
263
270
  "clearContentCacheHint",
264
271
  "collectContentCacheHint",
265
272
  "getContentCacheHint",
266
273
  "withContentCache",
274
+ "PROVIDER_QUERY_VERSION",
275
+ "toContentProviderQuery",
276
+ "toContentProviderNavigationQuery",
267
277
  "createContentProviderError"
268
278
  ];
269
279
  const generatedContentServerTypeSpecs = [
@@ -273,6 +283,8 @@ const generatedContentServerTypeSpecs = [
273
283
  { local: "ContentCacheInvalidateInput", exported: "ContentCacheInvalidateInput" },
274
284
  { local: "ContentProvider", exported: "ContentProvider" },
275
285
  { local: "ContentProviderCapabilities", exported: "ContentProviderCapabilities" },
286
+ { local: "ContentProviderQuery", exported: "ContentProviderQuery" },
287
+ { local: "ContentProviderNavigationOptions", exported: "ContentProviderNavigationOptions" },
276
288
  { local: "ContentProviderResult<T>", exported: "ContentProviderResult<T>" },
277
289
  { local: "MaybeContentProviderResult<T>", exported: "MaybeContentProviderResult<T>" },
278
290
  { local: "ContentProviderErrorCode", exported: "ContentProviderErrorCode" },
@@ -393,11 +405,12 @@ const registerGeneratedTypes = (contentConfigPath, resolveRuntimeModuleRoot, col
393
405
  const key = JSON.stringify(name);
394
406
  return ` ${key}: StrictParsedContent & __GeneratedCollectionSchema<__ContentCollectionExport<${key}>>`;
395
407
  });
408
+ const serverModuleLiteral = JSON.stringify(resolveRuntimeModuleRoot("./server"));
396
409
  const contentServerValueDeclarations = generatedContentServerValueNames.map(
397
- (name) => ` const ${name}: typeof import('${resolveRuntimeModuleRoot("./server")}').${name}`
410
+ (name) => ` const ${name}: typeof import(${serverModuleLiteral}).${name}`
398
411
  );
399
412
  const contentServerTypeDeclarations = generatedContentServerTypeSpecs.map(
400
- (spec) => ` type ${spec.local} = import('${resolveRuntimeModuleRoot("./server")}').${spec.exported}`
413
+ (spec) => ` type ${spec.local} = import(${serverModuleLiteral}).${spec.exported}`
401
414
  );
402
415
  return addTypeTemplate({
403
416
  filename: "types/content.d.ts",
@@ -635,7 +648,7 @@ const registerContentComponentsTemplate = (addTemplateImpl) => {
635
648
  const pathLiteral = JSON.stringify(path);
636
649
  const exportLiteral = JSON.stringify(exp);
637
650
  const nameLiteral = JSON.stringify(pascalName);
638
- return ` ${pascalName}: () => import(${pathLiteral}).then(mod => pickExport(mod, ${exportLiteral}, ${nameLiteral}, ${pathLiteral})),`;
651
+ return ` ${nameLiteral}: () => import(${pathLiteral}).then(mod => pickExport(mod, ${exportLiteral}, ${nameLiteral}, ${pathLiteral})),`;
639
652
  }),
640
653
  "}",
641
654
  `export const globalComponents = ${JSON.stringify(globalComponents)}`,
@@ -891,7 +904,7 @@ const parseDerivedCollectionFiles = async (rootDir, collections, collectionNames
891
904
  collectionResolver: (filePath) => resolveCollection(filePath, collections, contentContext.locales || [])
892
905
  }
893
906
  });
894
- const collection = typeof parsed._collection === "string" ? collections[parsed._collection] : void 0;
907
+ const collection = typeof parsed.collection === "string" ? collections[parsed.collection] : void 0;
895
908
  documents.push(...expandDataLocaleVariants(parsed, collection?.i18n === true ? void 0 : collection?.i18n));
896
909
  }
897
910
  return documents;
@@ -924,17 +937,17 @@ const collectDerivedPrerenderRoutes = async (rootDir, contentContext) => {
924
937
  const seenCanonicalKeys = /* @__PURE__ */ new Set();
925
938
  for (const contentId of graph.byCollection[collection] || []) {
926
939
  const document = graph.byId[contentId];
927
- if (!document || !document._canonicalKey || document._partial || document._navigation) {
940
+ if (!document || !document.canonicalKey || document.partial || document.navigationFile) {
928
941
  continue;
929
942
  }
930
- if (document._draft && !includeDrafts) {
943
+ if (document.draft && !includeDrafts) {
931
944
  continue;
932
945
  }
933
- if (seenCanonicalKeys.has(document._canonicalKey)) {
946
+ if (seenCanonicalKeys.has(document.canonicalKey)) {
934
947
  continue;
935
948
  }
936
- seenCanonicalKeys.add(document._canonicalKey);
937
- const variants = graph.byCanonical[document._canonicalKey] || {};
949
+ seenCanonicalKeys.add(document.canonicalKey);
950
+ const variants = graph.byCanonical[document.canonicalKey] || {};
938
951
  for (const [locale, variant] of Object.entries(variants)) {
939
952
  if (!variant.path) {
940
953
  continue;
@@ -957,20 +970,20 @@ const collectSitemapCollectionRouteCounts = async (rootDir, contentContext) => {
957
970
  const seenCanonicalKeys = /* @__PURE__ */ new Set();
958
971
  for (const contentId of graph.byCollection[collection] || []) {
959
972
  const document = graph.byId[contentId];
960
- if (!document || !document._canonicalKey || document._partial || document._navigation) {
973
+ if (!document || !document.canonicalKey || document.partial || document.navigationFile) {
961
974
  continue;
962
975
  }
963
- if (document._draft && !includeDrafts) {
976
+ if (document.draft && !includeDrafts) {
964
977
  continue;
965
978
  }
966
- if (seenCanonicalKeys.has(document._canonicalKey)) {
979
+ if (seenCanonicalKeys.has(document.canonicalKey)) {
967
980
  continue;
968
981
  }
969
- const variants = Object.values(graph.byCanonical[document._canonicalKey] || {});
982
+ const variants = Object.values(graph.byCanonical[document.canonicalKey] || {});
970
983
  if (!variants.some((variant) => variant.path)) {
971
984
  continue;
972
985
  }
973
- seenCanonicalKeys.add(document._canonicalKey);
986
+ seenCanonicalKeys.add(document.canonicalKey);
974
987
  counts[collection] += 1;
975
988
  }
976
989
  }
@@ -1135,13 +1148,23 @@ function normalizeSearchOptions(options) {
1135
1148
  return {
1136
1149
  engine: options.search?.engine || "minisearch",
1137
1150
  ignoredTags: options.search?.ignoredTags || ["script", "style", "pre"],
1138
- filterQuery: options.search?.filterQuery || { _draft: false, _partial: false },
1151
+ filterQuery: options.search?.filterQuery || { draft: false, partial: false },
1139
1152
  collections: options.search?.collections,
1140
1153
  extraFields: options.search?.extraFields || [],
1141
1154
  apiBaseURL: options.search?.apiBaseURL,
1142
1155
  minisearch: normalizeMiniSearchOptions(options.search?.minisearch)
1143
1156
  };
1144
1157
  }
1158
+ async function assertPagefindAvailable(search, importPagefind = () => import('pagefind')) {
1159
+ if (search === false || search.engine !== "pagefind") {
1160
+ return;
1161
+ }
1162
+ try {
1163
+ await importPagefind();
1164
+ } catch {
1165
+ throw new Error('Content search engine "pagefind" is enabled but the optional "pagefind" package is not installed. Install it: pnpm add -D pagefind');
1166
+ }
1167
+ }
1145
1168
  const defaultMiniSearchOptions = {
1146
1169
  fields: ["title", "content", "headings"],
1147
1170
  storeFields: ["path", "title", "excerpt", "anchor", "locale", "collection"],
@@ -1331,6 +1354,19 @@ const collectRawMarkdownRoutesFromGeneratedFrontmatter = (markdown) => {
1331
1354
  };
1332
1355
  const publicOutputPath = (publicDir, route) => join(publicDir, normalizeStaticRoutePath(route).replace(/^\//, ""));
1333
1356
 
1357
+ const assertPrerenderedContentSnapshot = (buildDir) => {
1358
+ const snapshotPath = resolve$1(buildDir, "content-cache/snapshot.json");
1359
+ let raw;
1360
+ try {
1361
+ raw = readFileSync(snapshotPath, "utf8");
1362
+ } catch {
1363
+ throw new Error("[content] production snapshot missing from prerendered content cache. Ensure the content cache route is prerendered.");
1364
+ }
1365
+ const snapshot = JSON.parse(raw);
1366
+ if (!isContentSnapshot(snapshot)) {
1367
+ throw new Error("[content] production snapshot is invalid in prerendered content cache.");
1368
+ }
1369
+ };
1334
1370
  const hookNuxtBoundary$2 = (nuxt, name, callback) => {
1335
1371
  const hook = nuxt.hook;
1336
1372
  hook(name, callback);
@@ -1346,6 +1382,12 @@ const registerStaticOutputGeneration = ({
1346
1382
  }) => {
1347
1383
  if (nuxt.options.dev) return;
1348
1384
  hookNuxtBoundary$2(nuxt, "nitro:build:before", (nitro) => {
1385
+ const usesFilesystemProvider = !contentContext.provider || contentContext.provider === "filesystem";
1386
+ if (usesFilesystemProvider) {
1387
+ nitro.hooks.hook("prerender:done", () => {
1388
+ assertPrerenderedContentSnapshot(nuxt.options.buildDir);
1389
+ });
1390
+ }
1349
1391
  nitro.hooks.hook("prerender:init", (prerenderer) => {
1350
1392
  prerenderer.hooks.hook("compiled", async () => {
1351
1393
  const searchRuntime = getSearchRuntime();
@@ -1353,7 +1395,7 @@ const registerStaticOutputGeneration = ({
1353
1395
  const serverFilename = typeof prerenderer.options.rollupConfig?.output?.entryFileNames === "string" ? prerenderer.options.rollupConfig.output.entryFileNames : "index.mjs";
1354
1396
  const serverEntrypoint = resolve$1(prerenderer.options.output.serverDir, serverFilename);
1355
1397
  const { localFetch } = await import(pathToFileURL(serverEntrypoint).href);
1356
- if (searchRuntime !== false && searchRuntime.engine !== "cms" && (!contentContext.provider || contentContext.provider === "filesystem")) {
1398
+ if (searchRuntime !== false && searchRuntime.engine !== "cms" && usesFilesystemProvider) {
1357
1399
  const response = await localFetch(searchRuntime.indexURL);
1358
1400
  if (!response.ok) {
1359
1401
  throw new Error(`Failed to generate search index: [${response.status}] ${response.statusText}`);
@@ -1499,15 +1541,6 @@ const registerContentNitroConfig = ({
1499
1541
  nitroConfig.prerender.routes.push(`/${locale}/llms.txt`, `/${locale}/llms-full.txt`);
1500
1542
  }
1501
1543
  }
1502
- for (const page of appContentConfig.agent.pages || []) {
1503
- const routes = typeof page.route === "string" ? [page.route] : Object.values(page.route);
1504
- for (const route of routes) {
1505
- const normalized = route === "/" ? "/" : `/${route.replace(/^\/+|\/+$/g, "")}`;
1506
- nitroConfig.prerender.routes.push(
1507
- normalized === "/" ? "/raw/index.md" : `/raw${normalized}.md`
1508
- );
1509
- }
1510
- }
1511
1544
  }
1512
1545
  });
1513
1546
  };
@@ -1565,7 +1598,7 @@ const contentModuleDefaults = {
1565
1598
  search: {
1566
1599
  engine: "minisearch",
1567
1600
  ignoredTags: ["script", "style", "pre"],
1568
- filterQuery: { _draft: false, _partial: false },
1601
+ filterQuery: { draft: false, partial: false },
1569
1602
  extraFields: [],
1570
1603
  minisearch: {
1571
1604
  fields: [...defaultMiniSearchOptions.fields],
@@ -1664,7 +1697,55 @@ const sanitizePrivateMarkdownPlugins = (plugins) => plugins.map((plugin) => ({
1664
1697
  name: plugin.name,
1665
1698
  options: sanitizePrivateMarkdownPluginValue(plugin.options || {})
1666
1699
  }));
1667
- const applyContentRuntimeConfig = (nuxt, options, contentContext, runtimeCollections, buildIntegrity, cacheIntegrity) => {
1700
+ const localizedValue = (value, locale, fallback = "") => {
1701
+ if (typeof value === "string") return value;
1702
+ if (!value) return fallback;
1703
+ return value[locale] || Object.values(value)[0] || fallback;
1704
+ };
1705
+ const resolveAgentAppPageValue = async (value, ctx) => {
1706
+ if (typeof value === "function") {
1707
+ return await value(ctx);
1708
+ }
1709
+ return localizedValue(value, ctx.locale);
1710
+ };
1711
+ const sanitizeAgentConfig = async (agent, contentContext, siteUrl) => {
1712
+ if (!agent) {
1713
+ return void 0;
1714
+ }
1715
+ const defaultLocale = agent.site?.defaultLocale || contentContext.defaultLocale || contentContext.locales?.[0] || "en";
1716
+ const locales = agent.site?.locales?.length ? agent.site.locales : contentContext.locales?.length ? contentContext.locales : [defaultLocale];
1717
+ const agentSiteUrl = siteUrl || agent.site?.url || "http://localhost:3000";
1718
+ const pages = await Promise.all((agent.pages || []).map(async (page) => {
1719
+ const title = {};
1720
+ const description = {};
1721
+ const markdown = {};
1722
+ for (const locale of locales) {
1723
+ const ctx = { locale, defaultLocale, siteUrl: agentSiteUrl };
1724
+ title[locale] = await resolveAgentAppPageValue(page.title, ctx);
1725
+ description[locale] = await resolveAgentAppPageValue(page.description, ctx);
1726
+ markdown[locale] = await page.render(ctx);
1727
+ }
1728
+ return {
1729
+ id: page.id,
1730
+ route: page.route,
1731
+ section: page.section,
1732
+ title,
1733
+ description,
1734
+ updated: page.updated,
1735
+ includeInIndex: page.includeInIndex,
1736
+ includeInFull: page.includeInFull,
1737
+ metadata: page.metadata,
1738
+ markdown
1739
+ };
1740
+ }));
1741
+ return {
1742
+ ...agent.site ? { site: agent.site } : {},
1743
+ ...agent.markdown ? { markdown: agent.markdown } : {},
1744
+ ...agent.sections ? { sections: agent.sections } : {},
1745
+ ...pages.length ? { pages } : {}
1746
+ };
1747
+ };
1748
+ const applyContentRuntimeConfig = async (nuxt, options, contentContext, appContentConfig, runtimeCollections, privateRuntimeCollections, buildIntegrity, cacheIntegrity) => {
1668
1749
  const revalidate = options.revalidate === false ? void 0 : options.revalidate;
1669
1750
  const searchRuntime = contentContext.search === false ? false : {
1670
1751
  apiBaseURL: contentContext.search.apiBaseURL || `${options.api.baseURL.replace(/\/$/, "")}/search`,
@@ -1708,8 +1789,10 @@ const applyContentRuntimeConfig = (nuxt, options, contentContext, runtimeCollect
1708
1789
  navigation: contentContext.navigation,
1709
1790
  contentHead: options.contentHead ?? true
1710
1791
  });
1792
+ const runtimeAgent = await sanitizeAgentConfig(appContentConfig.agent, contentContext, siteUrl);
1711
1793
  const privateContentRuntime = {
1712
1794
  ...contentContext,
1795
+ ...runtimeAgent ? { agent: runtimeAgent } : {},
1713
1796
  markdown: {
1714
1797
  ...contentContext.markdown,
1715
1798
  plugins: sanitizePrivateMarkdownPlugins(contentContext.markdown.plugins)
@@ -1724,13 +1807,14 @@ const applyContentRuntimeConfig = (nuxt, options, contentContext, runtimeCollect
1724
1807
  allowUnsigned: revalidate.allowUnsigned === true
1725
1808
  } : false,
1726
1809
  ...privateContentRuntime,
1727
- collections: runtimeCollections
1810
+ collections: privateRuntimeCollections
1728
1811
  });
1729
1812
  };
1730
1813
 
1731
1814
  const registerContentContextFinalization = ({
1732
1815
  nuxt,
1733
1816
  options,
1817
+ appContentConfig,
1734
1818
  contentContext,
1735
1819
  buildIntegrity,
1736
1820
  resolvePath,
@@ -1751,22 +1835,28 @@ const registerContentContextFinalization = ({
1751
1835
  };
1752
1836
  onResolved(resolvedContentContext);
1753
1837
  await validateBuiltinMarkdownPlugins(resolvedContentContext.markdown.plugins, resolvePath);
1754
- const runtimeCollections = Object.fromEntries(Object.entries(options.collections || {}).map(([name, collection]) => {
1838
+ const collectionEntries = Object.entries(options.collections || {}).map(([name, collection]) => {
1755
1839
  const references = collectTopLevelReferenceFieldsByTarget(collection.schema);
1756
- return [
1757
- name,
1758
- {
1759
- ...collection.source ? { source: collection.source } : {},
1760
- ...collection.exclude ? { exclude: collection.exclude } : {},
1761
- ...collection.type ? { type: collection.type } : {},
1762
- strict: collection.strict ?? true,
1763
- ...collection.route ? { route: collection.route } : {},
1764
- ...typeof collection.sitemap === "boolean" ? { sitemap: collection.sitemap } : {},
1765
- ...collection.i18n && collection.i18n !== true ? { i18n: collection.i18n } : {},
1766
- ...Object.keys(references).length ? { references } : {}
1767
- }
1768
- ];
1769
- }));
1840
+ const runtimeCollection = {
1841
+ ...collection.source ? { source: collection.source } : {},
1842
+ ...collection.exclude ? { exclude: collection.exclude } : {},
1843
+ ...collection.type ? { type: collection.type } : {},
1844
+ strict: collection.strict ?? true,
1845
+ ...collection.route ? { route: collection.route } : {},
1846
+ ...typeof collection.translatedSlugs === "boolean" ? { translatedSlugs: collection.translatedSlugs } : {},
1847
+ ...typeof collection.sitemap === "boolean" ? { sitemap: collection.sitemap } : {},
1848
+ ...collection.i18n && collection.i18n !== true ? { i18n: collection.i18n } : {},
1849
+ ...collection.cms ? { cms: collection.cms } : {},
1850
+ ...collection.agent ? { agent: collection.agent } : {},
1851
+ ...Object.keys(references).length ? { references } : {}
1852
+ };
1853
+ return [name, runtimeCollection, collection];
1854
+ });
1855
+ const runtimeCollections = Object.fromEntries(collectionEntries.map(([name, runtimeCollection]) => [name, runtimeCollection]));
1856
+ const privateRuntimeCollections = Object.fromEntries(collectionEntries.map(([name, runtimeCollection]) => [
1857
+ name,
1858
+ runtimeCollection
1859
+ ]));
1770
1860
  const cacheIntegrity = hash({
1771
1861
  locales: resolvedContentContext.locales,
1772
1862
  defaultLocale: resolvedContentContext.defaultLocale,
@@ -1779,7 +1869,7 @@ const registerContentContextFinalization = ({
1779
1869
  yaml: resolvedContentContext.yaml,
1780
1870
  csv: resolvedContentContext.csv
1781
1871
  });
1782
- applyContentRuntimeConfig(nuxt, options, resolvedContentContext, runtimeCollections, buildIntegrity, cacheIntegrity);
1872
+ await applyContentRuntimeConfig(nuxt, options, resolvedContentContext, appContentConfig, runtimeCollections, privateRuntimeCollections, buildIntegrity, cacheIntegrity);
1783
1873
  });
1784
1874
  };
1785
1875
 
@@ -1835,6 +1925,7 @@ const module$1 = defineNuxtModule({
1835
1925
  const resolvedI18n = resolveModuleI18nOptions(options, nuxt);
1836
1926
  const resolvedSitemap = normalizeSitemapOptions(options);
1837
1927
  const resolvedSearch = normalizeSearchOptions(options);
1928
+ await assertPagefindAvailable(resolvedSearch);
1838
1929
  validateCollectionNames(appContentConfig.collections);
1839
1930
  if (!hasAgentSurface(appContentConfig)) {
1840
1931
  options.agent = false;
@@ -1939,6 +2030,7 @@ const module$1 = defineNuxtModule({
1939
2030
  registerContentContextFinalization({
1940
2031
  nuxt,
1941
2032
  options,
2033
+ appContentConfig,
1942
2034
  contentContext,
1943
2035
  buildIntegrity,
1944
2036
  resolvePath,
@@ -22,7 +22,7 @@ function toJsonArray(tree) {
22
22
  export default defineTransformer({
23
23
  name: "csv",
24
24
  extensions: [".csv"],
25
- parse: async (_id, content, options = {}) => {
25
+ parse: async (id, content, options = {}) => {
26
26
  const csvOptions = typeof options === "object" && options !== null ? options : {};
27
27
  const tree = fromCSV(String(content ?? ""), {
28
28
  delimiter: ",",
@@ -31,8 +31,8 @@ export default defineTransformer({
31
31
  });
32
32
  const result = csvOptions.json === false ? toJsonArray(tree) : toJsonObject(tree);
33
33
  return {
34
- _id,
35
- _type: "csv",
34
+ id,
35
+ type: "csv",
36
36
  body: result
37
37
  };
38
38
  }
@@ -27,15 +27,15 @@ function getTransformers(ext, additionalTransformers = []) {
27
27
  }
28
28
  export async function transformContent(id, content, options = {}) {
29
29
  const { transformers = [] } = options;
30
- const file = { _id: id, body: content };
30
+ const file = { id, body: content };
31
31
  const ext = extname(id);
32
32
  const parser = getParser(ext, transformers);
33
33
  if (!parser) {
34
34
  console.warn(`${ext} files are not supported, "${id}" storing body as null`);
35
- return { _id: file._id, body: null };
35
+ return { id: file.id, body: null, missing: true };
36
36
  }
37
37
  const parserOptions = options[camelCase(parser.name)] || {};
38
- const parsed = await parser.parse(file._id, file.body, parserOptions);
38
+ const parsed = await parser.parse(file.id, file.body, parserOptions);
39
39
  const matchedTransformers = getTransformers(ext, transformers);
40
40
  const result = await matchedTransformers.reduce(async (prev, cur) => {
41
41
  const next = await prev || parsed;
@@ -1,29 +1,31 @@
1
1
  import { destr } from "destr";
2
2
  import { defineTransformer } from "./utils.js";
3
+ import { stripReservedContentKeys } from "./reserved.js";
3
4
  export default defineTransformer({
4
5
  name: "Json",
5
6
  extensions: [".json", ".json5"],
6
- parse: async (_id, content) => {
7
+ parse: async (id, content) => {
7
8
  let parsed;
8
9
  if (typeof content === "string") {
9
- if (_id.endsWith("json5")) {
10
+ if (id.endsWith("json5")) {
10
11
  parsed = (await import("json5").then((m) => m.default || m)).parse(content);
11
- } else if (_id.endsWith("json")) {
12
+ } else if (id.endsWith("json")) {
12
13
  parsed = destr(content);
13
14
  }
14
15
  } else {
15
16
  parsed = content;
16
17
  }
17
18
  if (Array.isArray(parsed)) {
18
- console.warn(`JSON array is not supported in ${_id}, moving the array into the \`body\` key`);
19
+ console.warn(`JSON array is not supported in ${id}, moving the array into the \`body\` key`);
19
20
  parsed = {
20
21
  body: parsed
21
22
  };
22
23
  }
24
+ parsed = stripReservedContentKeys(parsed, id);
23
25
  return {
24
26
  ...parsed,
25
- _id,
26
- _type: "json"
27
+ id,
28
+ type: "json"
27
29
  };
28
30
  }
29
31
  });
@@ -82,10 +82,10 @@ const resolveMarkdownPluginOptions = async (plugin) => {
82
82
  };
83
83
  const builtinMarkdownPlugins = {
84
84
  breaks: {
85
- load: () => loadModule("comark/plugins/breaks")
85
+ load: () => loadBuiltinModule(() => import("comark/plugins/breaks"))
86
86
  },
87
87
  emoji: {
88
- load: () => loadModule("comark/plugins/emoji")
88
+ load: () => loadBuiltinModule(() => import("comark/plugins/emoji"))
89
89
  },
90
90
  footnotes: {
91
91
  load: async () => footnotesPlugin
@@ -94,7 +94,7 @@ const builtinMarkdownPlugins = {
94
94
  load: async () => highlightPlugin
95
95
  },
96
96
  "json-render": {
97
- load: () => loadModule("comark/plugins/json-render")
97
+ load: () => loadBuiltinModule(() => import("comark/plugins/json-render"))
98
98
  },
99
99
  math: {
100
100
  load: () => loadModule("comark/plugins/math")
@@ -103,10 +103,10 @@ const builtinMarkdownPlugins = {
103
103
  load: () => loadModule("comark/plugins/mermaid")
104
104
  },
105
105
  punctuation: {
106
- load: () => loadModule("comark/plugins/punctuation")
106
+ load: () => loadBuiltinModule(() => import("comark/plugins/punctuation"))
107
107
  },
108
108
  security: {
109
- load: () => loadModule("comark/plugins/security")
109
+ load: () => loadBuiltinModule(() => import("comark/plugins/security"))
110
110
  },
111
111
  summary: {
112
112
  load: async () => summaryPlugin
@@ -135,6 +135,10 @@ async function loadModule(specifier) {
135
135
  );
136
136
  return resolveModule(imported);
137
137
  }
138
+ async function loadBuiltinModule(loader) {
139
+ const imported = await loader();
140
+ return resolveModule(imported);
141
+ }
138
142
  function resolveModule(imported) {
139
143
  return imported.default || imported;
140
144
  }
@@ -3,16 +3,18 @@ import { isRelative } from "ufo";
3
3
  import { defineTransformer } from "./utils.js";
4
4
  import { generatePath } from "./path-meta.js";
5
5
  import { resolveMarkdownPlugins } from "./markdown-plugins.js";
6
+ import { stripReservedContentKeys } from "./reserved.js";
6
7
  import { mapMarkdownNodes, toMarkdownRoot } from "../core/markdown/tree";
7
8
  export default defineTransformer({
8
9
  name: "markdown",
9
10
  extensions: [".md"],
10
- parse: async (_id, content, options = {}) => {
11
+ parse: async (id, content, options = {}) => {
11
12
  const config = { ...typeof options === "object" && options !== null ? options : {} };
12
13
  const plugins = await resolveMarkdownPlugins(config.plugins || []);
13
14
  const tree = await parse(content, {
14
15
  plugins
15
16
  });
17
+ const frontmatter = stripReservedContentKeys(tree.frontmatter, id);
16
18
  const body = normalizeMarkdownBody({
17
19
  ...toMarkdownRoot(tree.nodes),
18
20
  toc: tree.meta?.toc
@@ -21,13 +23,12 @@ export default defineTransformer({
21
23
  ...toMarkdownRoot(tree.meta.summary)
22
24
  }) : void 0;
23
25
  return {
24
- ...tree.frontmatter,
25
- _empty: body.children.length === 0,
26
- description: typeof tree.frontmatter.description === "string" ? tree.frontmatter.description : "",
26
+ ...frontmatter,
27
+ description: typeof frontmatter.description === "string" ? frontmatter.description : "",
27
28
  excerpt,
28
29
  body,
29
- _type: "markdown",
30
- _id
30
+ type: "markdown",
31
+ id
31
32
  };
32
33
  }
33
34
  });
@@ -5,32 +5,34 @@ export default defineTransformer({
5
5
  extensions: [".*"],
6
6
  transform(content, options = {}) {
7
7
  const { locales = [], defaultLocale = "en", respectPathCase = false, translatedSlugs = false } = options;
8
- const { _source, _file, _path, _extension, _basename } = describeId(content._id);
9
- const parts = _path.split("/");
10
- const _locale = locales.includes(parts[0]) ? parts.shift() : defaultLocale;
11
- const isNavigation = _basename === ".navigation";
8
+ const { source, file, path, extension, basename } = describeId(content.id);
9
+ const parts = path.split("/");
10
+ const locale = locales.includes(parts[0]) ? parts.shift() : defaultLocale;
11
+ const isNavigation = basename === ".navigation";
12
12
  const rawPath = isNavigation ? parts.slice(0, -1).join("/") : parts.join("/");
13
13
  const filePath = generatePath(rawPath, { respectPathCase });
14
- const _canonicalKey = generateCanonicalKey(isNavigation ? parts.slice(0, -1) : parts, { translatedSlugs, respectPathCase });
15
- const _collection = options.collectionResolver?.(_file);
14
+ const canonicalKey = generateCanonicalKey(isNavigation ? parts.slice(0, -1) : parts, { translatedSlugs, respectPathCase });
15
+ const collection = options.collectionResolver?.(file);
16
16
  return {
17
17
  ...content,
18
18
  // Fallback title synthesis lives here (not in the markdown parser) so it
19
19
  // applies uniformly to every parser output. Moving it into the markdown
20
20
  // parser would duplicate the logic in the yaml / json / csv parsers.
21
- title: content.title || (isNavigation ? void 0 : generateTitle(refineUrlPart(_basename))),
22
- _path: filePath,
23
- _dir: filePath.split("/").slice(-2)[0],
24
- _draft: content.draft || isDraftPath(_path),
25
- _partial: isNavigation || isPartialPath(_path),
26
- _locale,
27
- _canonicalKey,
28
- _collection,
29
- _navigation: isNavigation,
30
- _source,
31
- _file,
32
- _stem: _path,
33
- _extension
21
+ title: content.title || (isNavigation ? void 0 : generateTitle(refineUrlPart(basename))),
22
+ path: filePath,
23
+ draft: content.draft || isDraftPath(path),
24
+ partial: isNavigation || isPartialPath(path),
25
+ locale,
26
+ canonicalKey,
27
+ collection,
28
+ navigationFile: isNavigation,
29
+ file: {
30
+ source,
31
+ path: file,
32
+ stem: path,
33
+ dir: filePath.split("/").slice(-2)[0],
34
+ extension
35
+ }
34
36
  };
35
37
  }
36
38
  });
@@ -0,0 +1 @@
1
+ export * from './reserved.js'
@@ -0,0 +1,15 @@
1
+ /**
2
+ * System-computed identity keys on the content envelope. User frontmatter may
3
+ * not define these: the system value always wins and a dev/build warning is
4
+ * emitted so authors notice the shadowed key.
5
+ *
6
+ * The former user-facing "explicit id" alias has been retired — authors who
7
+ * want a stable, rename-proof alias for internal links should use `ref`.
8
+ */
9
+ export declare const RESERVED_CONTENT_KEYS: readonly ["id", "collection", "locale", "path", "canonicalKey", "type", "file", "resolved", "variants", "localePaths", "unprefixedPath", "dir"];
10
+ /**
11
+ * Strip reserved system keys from raw user frontmatter/data. Identity keys are
12
+ * stamped later by path-meta; derived localization keys would otherwise be
13
+ * trusted as system state.
14
+ */
15
+ export declare const stripReservedContentKeys: <T extends Record<string, unknown>>(source: Record<string, unknown> | null | undefined, fileId: string) => Partial<T>;