@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
@@ -2,10 +2,10 @@ import type { H3Event } from 'h3';
2
2
  import type { ParsedContent } from '../../types/content';
3
3
  import type { ContentCollectionItemSurroundingsOptions, ContentCollectionNavigationOptions, ContentCollectionPageOptions, ContentCollectionRouteMetaOptions, ContentCollectionSearchSectionsOptions, ContentPageResult, ContentSearchSection } from '../../types/query';
4
4
  export declare function queryFilesystemCollectionNavigation(event: H3Event, collection: string, fieldsOrOptions?: string[] | ContentCollectionNavigationOptions): Promise<any[]>;
5
- export declare function queryFilesystemCollectionItemSurroundings(event: H3Event, collection: string, path: string, opts?: ContentCollectionItemSurroundingsOptions): Promise<(import("../../types").NavItem | null)[]>;
5
+ export declare function queryFilesystemCollectionItemSurroundings(event: H3Event, collection: string, path: string, opts?: ContentCollectionItemSurroundingsOptions): Promise<(import("../../types/content").NavItem | null)[]>;
6
6
  export declare function queryFilesystemCollectionSearchSections(event: H3Event, collection: string, opts?: ContentCollectionSearchSectionsOptions): Promise<ContentSearchSection[]>;
7
7
  export declare function queryFilesystemCollectionPage<T = ParsedContent>(event: H3Event, collection: string, routeOrPath?: string, options?: ContentCollectionPageOptions): Promise<ContentPageResult<T> | null>;
8
- export declare function queryFilesystemCollectionRouteMeta(event: H3Event, collection: string, routeOrPath?: string, options?: ContentCollectionRouteMetaOptions): Promise<import("../../types").ContentRouteMeta | null>;
8
+ export declare function queryFilesystemCollectionRouteMeta(event: H3Event, collection: string, routeOrPath?: string, options?: ContentCollectionRouteMetaOptions): Promise<import("../../types/query").ContentRouteMeta | null>;
9
9
  export declare const queryCollectionNavigation: typeof queryFilesystemCollectionNavigation;
10
10
  export declare const queryCollectionItemSurroundings: typeof queryFilesystemCollectionItemSurroundings;
11
11
  export declare const queryCollectionSearchSections: typeof queryFilesystemCollectionSearchSections;
@@ -1,20 +1,21 @@
1
1
  import { resolveCollectionItemSurroundingsData, resolveCollectionNavigationData, resolveCollectionPageData, resolveCollectionRouteMetaData, resolveCollectionSearchSectionsData } from "../../features/collections/resolve";
2
2
  import { resolveContentNavigation } from "./navigation-query.js";
3
3
  import { executeFilesystemContentQuery } from "./query-executor.js";
4
+ import { createProviderNavigationQuery, createProviderQuery } from "./provider-query.js";
4
5
  import { serverQueryCollection } from "./storage.js";
5
6
  import { contentConfig } from "./storage-access.js";
6
7
  const isNotFoundError = (error) => {
7
8
  return error?.statusCode === 404;
8
9
  };
9
10
  const searchPageFields = (fields = []) => [
10
- "_path",
11
+ "path",
11
12
  "title",
12
13
  "description",
13
14
  "body",
14
15
  ...fields
15
16
  ];
16
17
  const mergeFilterQuery = (filterQuery, locale) => {
17
- const localeFilter = locale ? { _locale: locale } : void 0;
18
+ const localeFilter = locale ? { locale } : void 0;
18
19
  if (filterQuery && localeFilter) {
19
20
  return { $and: [filterQuery, localeFilter] };
20
21
  }
@@ -25,12 +26,15 @@ export async function queryFilesystemCollectionNavigation(event, collection, fie
25
26
  const locale = options.locale;
26
27
  return await resolveCollectionNavigationData(collection, contentConfig(), {
27
28
  ...options,
28
- loadNavigation: () => resolveContentNavigation(event, {
29
- collection,
30
- ...options.fields?.length ? { navigationFields: options.fields } : {},
31
- ...typeof options.canonical === "boolean" ? { canonical: options.canonical } : {},
32
- ...locale ? { resolveLocale: { locale, fallback: true } } : {}
33
- })
29
+ loadNavigation: () => {
30
+ const { query, options: navigationOptions } = createProviderNavigationQuery({
31
+ collection,
32
+ ...options.fields?.length ? { navigationFields: options.fields } : {},
33
+ ...typeof options.canonical === "boolean" ? { canonical: options.canonical } : {},
34
+ ...locale ? { resolveLocale: { locale, fallback: true } } : {}
35
+ });
36
+ return resolveContentNavigation(event, query, navigationOptions);
37
+ }
34
38
  });
35
39
  }
36
40
  export async function queryFilesystemCollectionItemSurroundings(event, collection, path, opts = {}) {
@@ -57,7 +61,7 @@ export async function queryFilesystemCollectionPage(event, collection, routeOrPa
57
61
  ...options,
58
62
  loadVariantPage: async (input) => {
59
63
  try {
60
- const response = await executeFilesystemContentQuery(event, {
64
+ const response = await executeFilesystemContentQuery(event, createProviderQuery({
61
65
  collection,
62
66
  first: true,
63
67
  resolveVariant: {
@@ -65,7 +69,7 @@ export async function queryFilesystemCollectionPage(event, collection, routeOrPa
65
69
  locale: input.locale,
66
70
  fallback: input.fallback
67
71
  }
68
- });
72
+ }).plan);
69
73
  return response.result || null;
70
74
  } catch (error) {
71
75
  if (isNotFoundError(error)) {
@@ -76,7 +80,7 @@ export async function queryFilesystemCollectionPage(event, collection, routeOrPa
76
80
  },
77
81
  loadPathPage: async (path) => {
78
82
  try {
79
- return await serverQueryCollection(event, collection).where("_path", "=", path).first();
83
+ return await serverQueryCollection(event, collection).where("path", "=", path).first();
80
84
  } catch (error) {
81
85
  if (isNotFoundError(error)) {
82
86
  return null;
@@ -1,9 +1,11 @@
1
1
  export { one, many, paginate, backlinks, resolveOne, variants, tree, neighbors, createServerContentQueryContext } from './query-api';
2
- export { getCollectionPath } from '../query/routes';
2
+ export { getCollectionPath } from '../../features/query/routes';
3
3
  export { queryCollectionsSitemapEntries } from './sitemap-provider';
4
- export { contentCacheHeaders, noopContentCache, vercelContentCache, type VercelContentCacheOptions } from './cache-adapters';
4
+ export { contentCacheHeaders, noopContentCache, vercelContentCache, headersContentCache, type VercelContentCacheOptions } from './cache-adapters';
5
5
  export { clearContentCacheHint, collectContentCacheHint, getContentCacheHint } from './cache-hints';
6
6
  export { createContentProviderError } from '../../public/provider-errors';
7
- export { withContentCache } from '../../public/provider';
8
- export type { ContentCacheAdapter, ContentCacheHint, ContentCacheHintInput, ContentCacheInvalidateInput, ContentProvider, ContentProviderCapabilities, ContentProviderResult, MaybeContentProviderResult } from '../../public/provider';
7
+ export { PROVIDER_QUERY_VERSION, toContentProviderNavigationQuery, toContentProviderQuery, withContentCache } from '../../public/provider';
8
+ export { normalizeProviderDocument, shapeProviderDocument } from './provider-document';
9
+ export type { ProviderDocumentInput, ShapeProviderDocumentOptions } from './provider-document';
10
+ export type { ContentCacheAdapter, ContentCacheHint, ContentCacheHintInput, ContentCacheInvalidateInput, ContentProvider, ContentProviderCapabilities, ContentProviderNavigationOptions, ContentProviderQuery, ContentProviderResult, MaybeContentProviderResult } from '../../public/provider';
9
11
  export type { ContentProviderErrorCode } from '../../public/provider-errors';
@@ -1,10 +1,11 @@
1
1
  export { one, many, paginate, backlinks, resolveOne, variants, tree, neighbors, createServerContentQueryContext } from "./query-api.js";
2
- export { getCollectionPath } from "../query/routes.js";
2
+ export { getCollectionPath } from "../../features/query/routes";
3
3
  export { queryCollectionsSitemapEntries } from "./sitemap-provider.js";
4
4
  export {
5
5
  contentCacheHeaders,
6
6
  noopContentCache,
7
- vercelContentCache
7
+ vercelContentCache,
8
+ headersContentCache
8
9
  } from "./cache-adapters.js";
9
10
  export {
10
11
  clearContentCacheHint,
@@ -12,4 +13,10 @@ export {
12
13
  getContentCacheHint
13
14
  } from "./cache-hints.js";
14
15
  export { createContentProviderError } from "../../public/provider-errors";
15
- export { withContentCache } from "../../public/provider";
16
+ export {
17
+ PROVIDER_QUERY_VERSION,
18
+ toContentProviderNavigationQuery,
19
+ toContentProviderQuery,
20
+ withContentCache
21
+ } from "../../public/provider";
22
+ export { normalizeProviderDocument, shapeProviderDocument } from "./provider-document.js";
@@ -1,6 +1,6 @@
1
1
  import { defineEventHandler, getRequestURL, setHeader } from "h3";
2
2
  import { getAgentLocales, localeFromAgentPath, resolveMarkdownForPublicRoute } from "../agent-site.js";
3
- import { agentRawPathForRoute, normalizeAgentRoutePath } from "../../agent-paths.js";
3
+ import { agentRawPathForRoute, normalizeAgentRoutePath } from "../../../features/agent/agent-paths";
4
4
  import { appendResponseHeader } from "../agent-http.js";
5
5
  import { contentConfig } from "../storage-access.js";
6
6
  const shouldAdvertise = (pathname) => !pathname.startsWith("/_") && !pathname.startsWith("/api/") && !pathname.endsWith(".css") && !pathname.endsWith(".js") && !pathname.endsWith(".png") && !pathname.endsWith(".jpg") && !pathname.endsWith(".jpeg") && !pathname.endsWith(".webp") && !pathname.endsWith(".svg") && !pathname.endsWith(".ico");
@@ -7,7 +7,7 @@ import {
7
7
  resolveMarkdownForPublicRoute
8
8
  } from "../agent-site.js";
9
9
  import { acceptsMarkdown, addVaryHeader, setAgentMarkdownHeaders } from "../agent-http.js";
10
- import { isUnsafeAgentRoutePath, normalizeAgentRoutePath } from "../../agent-paths.js";
10
+ import { isUnsafeAgentRoutePath, normalizeAgentRoutePath } from "../../../features/agent/agent-paths";
11
11
  const shouldSkip = (pathname) => pathname.startsWith("/_") || pathname.startsWith("/api/") || pathname.startsWith("/raw/") || pathname === "/robots.txt" || pathname === "/sitemap.xml" || pathname.endsWith(".txt") || pathname.endsWith(".xml") || pathname.endsWith(".json") || pathname.endsWith(".ico") || pathname.endsWith(".png") || pathname.endsWith(".jpg") || pathname.endsWith(".jpeg") || pathname.endsWith(".webp") || pathname.endsWith(".svg") || pathname.endsWith(".css") || pathname.endsWith(".js");
12
12
  export default defineEventHandler(async (event) => {
13
13
  const { pathname } = getRequestURL(event);
@@ -1,4 +1,4 @@
1
1
  import type { H3Event } from 'h3';
2
2
  import type { NavItem } from '../../types/content';
3
- import type { ContentQueryBuilderParams } from '../../types/query';
4
- export declare function resolveContentNavigation(event: H3Event, inputQuery?: ContentQueryBuilderParams): Promise<NavItem[]>;
3
+ import type { ContentProviderNavigationOptions, ContentProviderQuery } from '../../public/provider-query';
4
+ export declare function resolveContentNavigation(event: H3Event, query: ContentProviderQuery, navigationOptions?: ContentProviderNavigationOptions): Promise<NavItem[]>;
@@ -1,3 +1,4 @@
1
+ import { isPlanRegex } from "../../core/query/plan";
1
2
  import { resolveContentNavigationData } from "../../features/navigation/query";
2
3
  import { buildCanonicalNavigation } from "../../features/navigation/build";
3
4
  import { markCollectionNavigationRoot, projectNavigationTree } from "../../features/navigation/canonical";
@@ -7,7 +8,51 @@ import { isPreview } from "./preview.js";
7
8
  import { cacheStorage } from "./storage-access.js";
8
9
  import { createServerContentQuery } from "./storage.js";
9
10
  import { resolveLocaleChain } from "./manifest.js";
10
- export async function resolveContentNavigation(event, inputQuery = {}) {
11
+ const reviveFilterValue = (value) => isPlanRegex(value) ? new RegExp(value.source, value.flags) : value;
12
+ const conditionsToWhereCondition = (conditions) => {
13
+ if (!conditions.length) return {};
14
+ if (conditions.length === 1) return conditions[0];
15
+ return { $and: conditions };
16
+ };
17
+ const filterToWhereConditions = (filter) => {
18
+ switch (filter.type) {
19
+ case "true":
20
+ return [];
21
+ case "compare":
22
+ return [
23
+ filter.operator === "eq" ? { [filter.field]: reviveFilterValue(filter.value) } : { [filter.field]: { [`$${filter.operator}`]: reviveFilterValue(filter.value) } }
24
+ ];
25
+ case "and":
26
+ return filter.clauses.flatMap(filterToWhereConditions);
27
+ case "or":
28
+ return [{ $or: filter.clauses.map((clause) => conditionsToWhereCondition(filterToWhereConditions(clause))) }];
29
+ case "not":
30
+ return [{ $not: conditionsToWhereCondition(filterToWhereConditions(filter.clause)) }];
31
+ default:
32
+ throw new TypeError(`Unknown query filter node: ${filter.type}`);
33
+ }
34
+ };
35
+ const sortClausesToBuilder = (sort) => sort.map((clause) => ({
36
+ [clause.field]: clause.direction,
37
+ ...clause.locale ? { $locale: clause.locale } : {},
38
+ ...typeof clause.numeric === "boolean" ? { $numeric: clause.numeric } : {},
39
+ ...clause.caseFirst ? { $caseFirst: clause.caseFirst } : {},
40
+ ...clause.sensitivity ? { $sensitivity: clause.sensitivity } : {}
41
+ }));
42
+ const providerQueryToNavigationParams = (query, options) => {
43
+ const where = filterToWhereConditions(query.plan.filter);
44
+ const sort = sortClausesToBuilder(query.plan.sort);
45
+ return {
46
+ ...query.collection ? { collection: query.collection } : {},
47
+ ...where.length ? { where } : {},
48
+ ...sort.length ? { sort } : {},
49
+ ...options.resolveLocale ? { resolveLocale: options.resolveLocale } : {},
50
+ ...options.fields?.length ? { only: options.fields } : {},
51
+ ...options.canonical ? { canonical: true } : {}
52
+ };
53
+ };
54
+ export async function resolveContentNavigation(event, query, navigationOptions = {}) {
55
+ const inputQuery = providerQueryToNavigationParams(query, navigationOptions);
11
56
  const runtimeConfig = getContentRuntimeConfig();
12
57
  const requestedFields = [
13
58
  ...Array.isArray(inputQuery.only) ? inputQuery.only.map(String) : [],
@@ -39,18 +84,18 @@ export async function resolveContentNavigation(event, inputQuery = {}) {
39
84
  return cached;
40
85
  },
41
86
  loadLocaleNavigation: async (locale) => {
42
- let contentsQuery = createServerContentQuery(event, sourceQuery).where("_partial", "=", false).where("_type", "=", "markdown").where("navigation", "!=", false);
87
+ let contentsQuery = createServerContentQuery(event, sourceQuery).where("partial", "=", false).where("type", "=", "markdown").where("navigation", "!=", false);
43
88
  if (locale) {
44
- contentsQuery = contentsQuery.where("_locale", "=", locale);
89
+ contentsQuery = contentsQuery.where("locale", "=", locale);
45
90
  }
46
- let dirConfigsQuery = createServerContentQuery(event).where("_navigation", "=", true).where("_partial", "=", true);
91
+ let dirConfigsQuery = createServerContentQuery(event).where("navigationFile", "=", true).where("partial", "=", true);
47
92
  if (locale) {
48
- dirConfigsQuery = dirConfigsQuery.where("_locale", "=", locale);
93
+ dirConfigsQuery = dirConfigsQuery.where("locale", "=", locale);
49
94
  }
50
95
  const contents = await contentsQuery.all();
51
96
  const dirConfigs = await dirConfigsQuery.all();
52
97
  const configs = dirConfigs.reduce((accumulator, config) => {
53
- accumulator[config._path || "/"] = {
98
+ accumulator[config.path || "/"] = {
54
99
  ...config,
55
100
  ...config.body
56
101
  };
@@ -60,7 +105,7 @@ export async function resolveContentNavigation(event, inputQuery = {}) {
60
105
  return buildCanonicalNavigation(contents, configs, [.../* @__PURE__ */ new Set([...configuredFields, ...requestedFields])]);
61
106
  },
62
107
  resolveLocaleChain,
63
- localizeNavigation: async (items, locale, _fallback = [], collection, canonical) => {
108
+ localizeNavigation: async (items, locale, _unusedFallback = [], collection, canonical) => {
64
109
  const collectionI18n = collection ? runtimeConfig.content.collections?.[collection]?.i18n : void 0;
65
110
  const collectionLocales = collectionI18n && typeof collectionI18n === "object" ? collectionI18n.locales : void 0;
66
111
  const collectionDefault = collectionI18n && typeof collectionI18n === "object" ? collectionI18n.defaultLocale : void 0;
@@ -1,2 +1,2 @@
1
1
  import type { ParsedContentMeta } from '../../types/content';
2
- export declare function createNav(contents: ParsedContentMeta[], configs: Record<string, ParsedContentMeta>): import("../../types").NavItem[];
2
+ export declare function createNav(contents: ParsedContentMeta[], configs: Record<string, ParsedContentMeta>): import("../../types/content").NavItem[];
@@ -0,0 +1 @@
1
+ export * from './provider-document.js'
@@ -0,0 +1,59 @@
1
+ import type { ContentFileMeta, ParsedContent } from '../../types/content';
2
+ import type { ContentPageResult } from '../../types/query';
3
+ import { type RouteMounts } from '../../features/localization/path';
4
+ /**
5
+ * Minimal document a third-party provider must emit. Only `collection`,
6
+ * `locale`, `path` and `body` are strictly required — `id`, `canonicalKey` and
7
+ * `type` are derived when omitted, and `file` is optional (absent for providers
8
+ * with no backing file, e.g. CMS-backed documents). Any additional frontmatter
9
+ * fields are passed through untouched.
10
+ */
11
+ export interface ProviderDocumentInput extends Record<string, unknown> {
12
+ /** Collection the document belongs to. */
13
+ collection: string;
14
+ /** Locale code for this concrete variant. */
15
+ locale: string;
16
+ /** Canonical (source-agnostic) route path this variant serves at. */
17
+ path: string;
18
+ /** Parsed body payload (`null` for documents with no renderable body). */
19
+ body: ParsedContent['body'];
20
+ /** Fully-qualified system id. Derived from `locale` + `path` when omitted. */
21
+ id?: string;
22
+ /**
23
+ * Opaque, locale-agnostic identity join key. Derived from `collection` +
24
+ * `path` when omitted. Never parse or render it as a URL.
25
+ */
26
+ canonicalKey?: string;
27
+ /** Document kind. Defaults to `'markdown'`. */
28
+ type?: ParsedContent['type'];
29
+ /** Optional file provenance. Absent for providers with no backing file. */
30
+ file?: ContentFileMeta;
31
+ }
32
+ /**
33
+ * Options describing the provider's locale/route configuration so core can
34
+ * derive the localized route envelope. For single-locale providers these can be
35
+ * omitted entirely.
36
+ */
37
+ export interface ShapeProviderDocumentOptions {
38
+ /** Default locale of the site (defaults to the document's own locale). */
39
+ defaultLocale?: string;
40
+ /** All configured locales (defaults to the document's own locale). */
41
+ locales?: string[];
42
+ /** Route mount(s) for the collection, used to project localized paths. */
43
+ route?: string | Record<string, string>;
44
+ /** Pre-computed route mounts (takes precedence over `route`). */
45
+ routeMounts?: RouteMounts;
46
+ }
47
+ /**
48
+ * Normalize a provider's raw document into the canonical content envelope,
49
+ * filling in the derivable identity fields (`id`, `canonicalKey`, `type`) while
50
+ * leaving `file` absent unless the provider supplied it.
51
+ */
52
+ export declare const normalizeProviderDocument: (input: ProviderDocumentInput) => ParsedContent;
53
+ /**
54
+ * Normalize a provider's raw document and derive the full route envelope
55
+ * (`path`, `variants`, `localePaths`, `resolved`). The result is the canonical
56
+ * `ContentPageResult` route helpers return, so a provider can back its `page`,
57
+ * `routeMeta` and `query` methods from the minimal document set alone.
58
+ */
59
+ export declare const shapeProviderDocument: <T = ParsedContent>(input: ProviderDocumentInput, options?: ShapeProviderDocumentOptions) => ContentPageResult<T>;
@@ -0,0 +1,48 @@
1
+ import { normalizeRouteMounts } from "../../features/localization/path";
2
+ import { localizePageResult } from "../../features/localization/results";
3
+ const trimSlashes = (value) => value.replace(/^\/+|\/+$/g, "");
4
+ const extensionForType = (type) => {
5
+ switch (type) {
6
+ case "yaml":
7
+ return "yml";
8
+ case "json":
9
+ return "json";
10
+ case "csv":
11
+ return "csv";
12
+ default:
13
+ return "md";
14
+ }
15
+ };
16
+ export const normalizeProviderDocument = (input) => {
17
+ const collection = input.collection;
18
+ const locale = input.locale;
19
+ const path = input.path;
20
+ const type = input.type ?? "markdown";
21
+ const canonicalKey = input.canonicalKey ?? `${collection}:${trimSlashes(path) || "index"}`;
22
+ const extension = input.file?.extension ?? extensionForType(type);
23
+ const id = input.id ?? `content:${locale}:${trimSlashes(path).replace(/\//g, ":") || "index"}.${extension}`;
24
+ return {
25
+ ...input,
26
+ id,
27
+ collection,
28
+ locale,
29
+ path,
30
+ canonicalKey,
31
+ type,
32
+ ...input.file ? { file: input.file } : {},
33
+ body: input.body
34
+ };
35
+ };
36
+ export const shapeProviderDocument = (input, options = {}) => {
37
+ const document = normalizeProviderDocument(input);
38
+ const defaultLocale = options.defaultLocale ?? input.locale;
39
+ const locales = options.locales ?? [input.locale];
40
+ const routeMounts = options.routeMounts ?? normalizeRouteMounts(options.route, locales, defaultLocale);
41
+ return localizePageResult(
42
+ document,
43
+ input.locale,
44
+ defaultLocale,
45
+ locales,
46
+ routeMounts
47
+ );
48
+ };
@@ -0,0 +1 @@
1
+ export * from './provider-query-wire.js'
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Builder-params → provider-wire lowering seam.
3
+ *
4
+ * These helpers translate the internal query IR (`ContentQueryBuilderParams`,
5
+ * see `../../types/query-parts/transport.ts`) into the closed, JSON-pure
6
+ * `ContentProviderQuery` wire envelope. They live in the runtime adapter layer
7
+ * — NOT in the `public/` facade — because the IR is internal plumbing: keeping
8
+ * its name out of `src/public/` is what makes the IR "not public" while the
9
+ * lowering functions themselves stay part of the exported surface (re-exported
10
+ * from `../../public/provider-query`).
11
+ */
12
+ import type { ContentQueryBuilderParams } from '../../types/query';
13
+ import type { ContentProviderNavigationOptions, ContentProviderQuery } from '../../public/provider-query';
14
+ export declare const PROVIDER_QUERY_VERSION: 1;
15
+ /**
16
+ * Lower builder params into the wire envelope. This is the single place the
17
+ * builder → plan translation happens before the provider boundary; providers
18
+ * receive only the closed, JSON-pure plan.
19
+ */
20
+ export declare const toContentProviderQuery: (params: ContentQueryBuilderParams) => ContentProviderQuery;
21
+ /**
22
+ * Split builder params into the navigation wire pair (CS-5): the query plan
23
+ * (collection + user filter/sort) plus the navigation-only options
24
+ * (`fields` = `only` ∪ `navigationFields`, `canonical`, and the raw
25
+ * `resolveLocale`). The nav-only keys are stripped before lowering so they do
26
+ * not leak into the plan. Pure — the single navigation builder-params → wire
27
+ * seam, usable by providers and their conformance suites.
28
+ */
29
+ export declare const toContentProviderNavigationQuery: (params: ContentQueryBuilderParams) => {
30
+ query: ContentProviderQuery;
31
+ options: ContentProviderNavigationOptions;
32
+ };
@@ -0,0 +1,27 @@
1
+ import { lowerQueryPlan } from "../../core/query/lower";
2
+ export const PROVIDER_QUERY_VERSION = 1;
3
+ export const toContentProviderQuery = (params) => ({
4
+ v: PROVIDER_QUERY_VERSION,
5
+ collection: params.collection ?? null,
6
+ plan: lowerQueryPlan(params)
7
+ });
8
+ export const toContentProviderNavigationQuery = (params) => {
9
+ const fields = [
10
+ ...Array.isArray(params.only) ? params.only.map(String) : [],
11
+ ...Array.isArray(params.navigationFields) ? params.navigationFields.map(String) : []
12
+ ];
13
+ const canonical = params.canonical === true;
14
+ const resolveLocale = params.resolveLocale;
15
+ const planParams = { ...params };
16
+ delete planParams.only;
17
+ delete planParams.navigationFields;
18
+ delete planParams.canonical;
19
+ return {
20
+ query: toContentProviderQuery(planParams),
21
+ options: {
22
+ ...fields.length ? { fields } : {},
23
+ ...canonical ? { canonical: true } : {},
24
+ ...resolveLocale ? { resolveLocale } : {}
25
+ }
26
+ };
27
+ };
@@ -1,8 +1,21 @@
1
1
  import type { H3Event } from 'h3';
2
- import type { ContentCollectionMap } from '@lupinum/ginko-content';
3
- import type { ParsedContent } from '../../types/content';
2
+ import type { ContentDocumentResolution, ParsedContent } from '../../types/content';
4
3
  import type { ContentQueryResponse } from '../../types/api';
5
- import type { CollectionQueryBuilder, ContentQueryBuilderParams, ContentQueryRequest, ResolveContentReferenceOptions } from '../../types/query';
4
+ import type { CollectionQueryBuilder, ContentCollectionMap, ContentQueryBuilderParams, ContentQueryRequest, ResolveContentReferenceOptions } from '../../types/query';
5
+ import { type ContentProviderQuery } from '../../public/provider-query';
6
+ export { toContentProviderNavigationQuery as createProviderNavigationQuery } from '../../public/provider-query';
7
+ /**
8
+ * Build the provider wire query (CS-5) from builder params: reject
9
+ * globally-invalid operators and malformed `$options` up front (so callers see
10
+ * a clean typed error rather than a raw lowering `TypeError`), apply the shared
11
+ * content-query normalization (default sort, locale injection, `fallback: true`
12
+ * → chain expansion), then lower to a JSON-pure `ContentQueryPlan`.
13
+ *
14
+ * This is the single builder-params → plan seam before the provider boundary.
15
+ * Provider-specific policy (draft hiding, limit clamps, regex rejection) lives
16
+ * inside each provider, applied to the plan it receives.
17
+ */
18
+ export declare const createProviderQuery: (params: ContentQueryBuilderParams) => ContentProviderQuery;
6
19
  export declare const normalizeProviderQueryResult: <T>(response: ContentQueryResponse<T>) => T[];
7
20
  export declare const normalizeProviderQueryResponse: <T>(params: ContentQueryBuilderParams, response: unknown, providerName?: string) => ContentQueryResponse<T>;
8
21
  export declare const resolveProviderContentVariants: (event: H3Event, identity: string, options: ResolveContentReferenceOptions) => Promise<{
@@ -18,13 +31,9 @@ export declare const resolveProviderContentVariants: (event: H3Event, identity:
18
31
  fallback: boolean;
19
32
  } | null>;
20
33
  export declare const createServerProviderQueryFetch: <T = ParsedContent>(event: H3Event) => (query: ContentQueryRequest) => Promise<ContentQueryResponse<T>>;
21
- export declare const createServerContentQuery: <T = ParsedContent>(event: H3Event, query?: string | ContentQueryBuilderParams, ...pathParts: string[]) => import("@lupinum/ginko-content").ContentQueryBuilder<T>;
34
+ export declare const createServerContentQuery: <T = ParsedContent>(event: H3Event, query?: string | ContentQueryBuilderParams, ...pathParts: string[]) => import("../../types/query").ContentQueryBuilder<T>;
22
35
  export declare function serverQueryCollection<K extends keyof ContentCollectionMap & string>(event: H3Event, collection: K): CollectionQueryBuilder<ContentCollectionMap[K]>;
23
36
  export declare function serverQueryCollection<T = ParsedContent>(event: H3Event, collection: string): CollectionQueryBuilder<T>;
24
37
  export declare const resolveContentReference: <T = ParsedContent>(event: H3Event, reference: string, options?: ResolveContentReferenceOptions) => Promise<(T & {
25
- _requestedLocale?: string;
26
- _resolvedLocale?: string;
27
- _fallback?: boolean;
28
- _availableLocales?: string[];
29
- _variantPaths?: Record<string, string>;
38
+ resolved?: ContentDocumentResolution;
30
39
  }) | null>;
@@ -1,10 +1,35 @@
1
1
  import { joinURL, withLeadingSlash } from "ufo";
2
2
  import { createQuery, wrapQueryBuilder } from "../../core/query/builder";
3
3
  import { normalizeContentQueryParams } from "../../core/query/params";
4
+ import { containsStandaloneRegexOptions, findUnsupportedQueryOperator } from "../../core/query/operators";
4
5
  import { normalizeI18nConfig, resolveRuntimeCollectionI18nConfig } from "../../features/localization/config";
6
+ import { sortLocalesCanonically } from "../../core/content/locale";
5
7
  import { normalizeReferenceValue } from "../../core/references/resolve";
6
8
  import { getContentRuntimeConfig } from "./runtime-config.js";
7
9
  import { createContentProviderError } from "../../public/provider-errors";
10
+ import { toContentProviderQuery } from "../../public/provider-query";
11
+ export { toContentProviderNavigationQuery as createProviderNavigationQuery } from "../../public/provider-query";
12
+ export const createProviderQuery = (params) => {
13
+ const unsupported = findUnsupportedQueryOperator(params.where);
14
+ if (unsupported) {
15
+ throw createContentProviderError("unsupported_query_operator", `Unsupported query operator: ${unsupported}`, {
16
+ operator: unsupported
17
+ });
18
+ }
19
+ if (containsStandaloneRegexOptions(params.where)) {
20
+ throw createContentProviderError("unsupported_query_shape", "Query operator $options requires $regex.", {
21
+ operator: "$options"
22
+ });
23
+ }
24
+ const config = getContentRuntimeConfig().content || {};
25
+ const normalized = normalizeContentQueryParams(params, {
26
+ collectionI18n: params.collection ? config.collections?.[params.collection]?.i18n : void 0,
27
+ defaultLocale: config.defaultLocale,
28
+ localeFallback: config.localeFallback,
29
+ includeDraftFilter: false
30
+ });
31
+ return toContentProviderQuery(normalized);
32
+ };
8
33
  const isObject = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
9
34
  const isProviderFindResponse = (response) => isObject(response) && Array.isArray(response.result) && typeof response.skip === "number" && typeof response.limit === "number" && typeof response.total === "number";
10
35
  export const normalizeProviderQueryResult = (response) => {
@@ -55,7 +80,7 @@ const identityMatchesDocument = (document, identity) => {
55
80
  if (!normalizedIdentity) {
56
81
  return false;
57
82
  }
58
- return [document._canonicalKey, document._path, document.ref].filter((value) => typeof value === "string").some((value) => normalizeReferenceValue(value) === normalizedIdentity);
83
+ return [document.canonicalKey, document.path, document.ref].filter((value) => typeof value === "string").some((value) => normalizeReferenceValue(value) === normalizedIdentity);
59
84
  };
60
85
  export const resolveProviderContentVariants = async (event, identity, options) => {
61
86
  if (!options.collection) {
@@ -77,38 +102,43 @@ export const resolveProviderContentVariants = async (event, identity, options) =
77
102
  const provider = await getContentProvider(event);
78
103
  const baseQuery = {
79
104
  collection: options.collection,
80
- only: ["_path", "_canonicalKey", "_locale", "ref", "title", "description", "body"]
105
+ only: ["path", "canonicalKey", "locale", "ref", "title", "description", "body"]
81
106
  };
82
107
  const documents = localesToQuery.length ? (await Promise.all(
83
- localesToQuery.map(
84
- async (locale) => normalizeProviderQueryResult(
85
- normalizeProviderQueryResponse({
86
- ...baseQuery,
87
- resolveLocale: { locale, exact: true }
88
- }, await provider.query(event, {
89
- ...baseQuery,
90
- resolveLocale: { locale, exact: true }
91
- }), provider.name)
92
- )
93
- )
94
- )).flat() : normalizeProviderQueryResult(normalizeProviderQueryResponse(baseQuery, await provider.query(event, baseQuery), provider.name));
108
+ localesToQuery.map(async (locale) => {
109
+ const localeQuery = { ...baseQuery, resolveLocale: { locale, exact: true } };
110
+ return normalizeProviderQueryResult(
111
+ normalizeProviderQueryResponse(
112
+ localeQuery,
113
+ await provider.query(event, createProviderQuery(localeQuery)),
114
+ provider.name
115
+ )
116
+ );
117
+ })
118
+ )).flat() : normalizeProviderQueryResult(normalizeProviderQueryResponse(baseQuery, await provider.query(event, createProviderQuery(baseQuery)), provider.name));
95
119
  const matched = documents.find((document) => identityMatchesDocument(document, normalizedReference));
96
- const canonicalKey = matched?._canonicalKey;
120
+ const canonicalKey = matched?.canonicalKey;
97
121
  if (!canonicalKey) {
98
122
  return null;
99
123
  }
100
- const variants = documents.filter((document) => document._canonicalKey === canonicalKey);
124
+ const variants = documents.filter((document) => document.canonicalKey === canonicalKey);
101
125
  if (!variants.length) {
102
126
  return null;
103
127
  }
104
- const selectByLocale = (locale) => locale ? variants.find((document) => document._locale === locale) : void 0;
128
+ const selectByLocale = (locale) => locale ? variants.find((document) => document.locale === locale) : void 0;
105
129
  const selected = selectByLocale(options.locale) || (!options.exact ? fallbackLocales.map(selectByLocale).find(Boolean) : void 0) || (!options.exact ? selectByLocale(collectionI18n?.defaultLocale || runtimeContent.defaultLocale) : void 0) || (!options.exact ? variants[0] : void 0);
106
130
  if (!selected) {
107
131
  return null;
108
132
  }
109
- const availableLocales = Array.from(new Set(variants.map((document) => document._locale).filter(Boolean)));
133
+ const availableLocales = sortLocalesCanonically(
134
+ Array.from(new Set(variants.map((document) => document.locale).filter(Boolean))),
135
+ {
136
+ defaultLocale: collectionI18n?.defaultLocale || runtimeContent.defaultLocale,
137
+ locales: collectionI18n?.locales
138
+ }
139
+ );
110
140
  const variantPaths = Object.fromEntries(
111
- variants.filter((document) => document._locale && document._path).map((document) => [document._locale, document._path])
141
+ variants.filter((document) => document.locale && document.path).map((document) => [document.locale, document.path])
112
142
  );
113
143
  return {
114
144
  canonicalKey,
@@ -117,16 +147,17 @@ export const resolveProviderContentVariants = async (event, identity, options) =
117
147
  availableLocales,
118
148
  variantPaths,
119
149
  requestedLocale: options.locale,
120
- resolvedLocale: selected._locale,
121
- fallback: Boolean(options.locale && selected._locale && selected._locale !== options.locale)
150
+ resolvedLocale: selected.locale,
151
+ fallback: Boolean(options.locale && selected.locale && selected.locale !== options.locale)
122
152
  };
123
153
  };
124
154
  export const createServerProviderQueryFetch = (event) => {
125
155
  return async (query) => {
126
156
  const { getContentProvider } = await import("./providers/index.js");
127
157
  const provider = await getContentProvider(event);
128
- const response = await provider.query(event, query.params());
129
- return normalizeProviderQueryResponse(query.params(), response, provider.name);
158
+ const params = query.params();
159
+ const response = await provider.query(event, createProviderQuery(params));
160
+ return normalizeProviderQueryResponse(params, response, provider.name);
130
161
  };
131
162
  };
132
163
  const getServerCollectionI18n = (collection) => {
@@ -164,10 +195,13 @@ export const resolveContentReference = async (event, reference, options = {}) =>
164
195
  }
165
196
  return {
166
197
  ...resolved.selected,
167
- _requestedLocale: resolved.requestedLocale,
168
- _resolvedLocale: resolved.resolvedLocale,
169
- _fallback: resolved.fallback,
170
- _availableLocales: resolved.availableLocales,
171
- _variantPaths: resolved.variantPaths
198
+ resolved: {
199
+ ...resolved.selected.resolved || {},
200
+ requestedLocale: resolved.requestedLocale,
201
+ locale: resolved.resolvedLocale,
202
+ fallback: resolved.fallback,
203
+ availableLocales: resolved.availableLocales,
204
+ variantPaths: resolved.variantPaths
205
+ }
172
206
  };
173
207
  };