@lupinum/ginko-content 0.1.6 → 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.
- package/compatibility.json +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/cms-contract/build.js +15 -20
- package/dist/cms-contract/types.d.ts +12 -7
- package/dist/core/content/document +1 -0
- package/dist/core/content/document.d.ts +16 -0
- package/dist/core/content/document.js +2 -0
- package/dist/core/content/graph.d.ts +3 -1
- package/dist/core/content/graph.js +21 -20
- package/dist/core/content/locale.d.ts +6 -1
- package/dist/core/content/locale.js +17 -6
- package/dist/core/content/path.d.ts +5 -5
- package/dist/core/content/path.js +8 -8
- package/dist/core/content/snapshot +1 -0
- package/dist/core/content/snapshot.d.ts +25 -0
- package/dist/core/content/snapshot.js +99 -0
- package/dist/core/provider-errors.d.ts +1 -1
- package/dist/core/provider-errors.js +1 -0
- package/dist/core/query/builder.js +3 -3
- package/dist/core/query/execute.js +75 -36
- package/dist/core/query/filter.js +2 -2
- package/dist/core/query/lower.js +79 -3
- package/dist/core/query/params.js +7 -7
- package/dist/core/query/plan.d.ts +18 -0
- package/dist/core/query/plan.js +7 -0
- package/dist/core/references/resolve.js +6 -9
- package/dist/features/agent/agent-markdown +1 -0
- package/dist/features/agent/agent-markdown.d.ts +116 -0
- package/dist/features/agent/agent-markdown.js +138 -0
- package/dist/features/agent/walker +1 -0
- package/dist/features/agent/walker.d.ts +10 -0
- package/dist/features/agent/walker.js +174 -0
- package/dist/features/collections/resolve.d.ts +2 -2
- package/dist/features/collections/resolve.js +19 -16
- package/dist/features/localization/links.js +1 -1
- package/dist/features/localization/results.d.ts +3 -3
- package/dist/features/localization/results.js +46 -41
- package/dist/features/localization/translated-slugs.js +5 -5
- package/dist/features/navigation/build.d.ts +2 -2
- package/dist/features/navigation/build.js +23 -26
- package/dist/features/navigation/canonical.d.ts +10 -11
- package/dist/features/navigation/canonical.js +26 -21
- package/dist/features/navigation/resolve.js +4 -4
- package/dist/features/navigation/tree.js +3 -3
- package/dist/{runtime → features}/query/backlinks.js +3 -5
- package/dist/{runtime → features}/query/documents.js +1 -1
- package/dist/{runtime → features}/query/localized-docs.d.ts +1 -1
- package/dist/{runtime → features}/query/localized-docs.js +3 -6
- package/dist/{runtime → features}/query/navigation.d.ts +1 -1
- package/dist/{runtime → features}/query/navigation.js +8 -8
- package/dist/{runtime → features}/query/populate.js +6 -14
- package/dist/{runtime → features}/query/unified.d.ts +4 -4
- package/dist/{runtime → features}/query/unified.js +4 -2
- package/dist/{runtime → features}/query/variants.js +4 -4
- package/dist/features/search/navigation.js +2 -2
- package/dist/features/search/sections.d.ts +1 -1
- package/dist/features/search/sections.js +1 -1
- package/dist/features/sitemap/query.d.ts +5 -5
- package/dist/features/sitemap/query.js +6 -6
- package/dist/integrations/nitro/ingest.js +9 -20
- package/dist/integrations/nitro/storage.d.ts +1 -0
- package/dist/integrations/nitro/storage.js +22 -8
- package/dist/module.d.mts +135 -812
- package/dist/module.json +1 -1
- package/dist/module.mjs +70 -27
- package/dist/parsers/csv.js +3 -3
- package/dist/parsers/index.js +3 -3
- package/dist/parsers/json.js +8 -6
- package/dist/parsers/markdown-plugins.js +9 -5
- package/dist/parsers/markdown.js +7 -6
- package/dist/parsers/path-meta.js +21 -19
- package/dist/parsers/reserved +1 -0
- package/dist/parsers/reserved.d.ts +15 -0
- package/dist/parsers/reserved.js +35 -0
- package/dist/parsers/yaml.js +6 -4
- package/dist/public/agent +1 -0
- package/dist/public/agent.d.ts +17 -0
- package/dist/public/agent.js +34 -0
- package/dist/public/client.d.ts +2 -3
- package/dist/public/client.js +1 -2
- package/dist/public/provider-query +1 -0
- package/dist/public/provider-query.d.ts +58 -0
- package/dist/public/provider-query.js +5 -0
- package/dist/public/provider.d.ts +8 -3
- package/dist/public/provider.js +2 -0
- package/dist/public/server.d.ts +7 -12
- package/dist/public/server.js +5 -36
- package/dist/runtime/app/components/ContentRenderer.d.vue.ts +3 -3
- package/dist/runtime/app/components/ContentRenderer.vue +2 -2
- package/dist/runtime/app/components/ContentRenderer.vue.d.ts +3 -3
- package/dist/runtime/app/components/ContentRendererInline.d.vue.ts +1 -1
- package/dist/runtime/app/components/ContentRendererInline.vue.d.ts +1 -1
- package/dist/runtime/app/components/Prose/ProseImg.d.vue.ts +4 -4
- package/dist/runtime/app/components/Prose/ProseImg.vue.d.ts +4 -4
- package/dist/runtime/app/components/Prose/ProsePre.d.vue.ts +1 -1
- package/dist/runtime/app/components/Prose/ProsePre.vue.d.ts +1 -1
- package/dist/runtime/app/components/internal/ContentRendererMarkdown.d.vue.ts +1 -1
- package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue +4 -4
- package/dist/runtime/app/components/internal/ContentRendererMarkdown.vue.d.ts +1 -1
- package/dist/runtime/app/components/internal/MarkdownRenderer.d.ts +3 -3
- package/dist/runtime/app/composables/preview.d.ts +1 -1
- package/dist/runtime/app/composables/query-api.d.ts +5 -5
- package/dist/runtime/app/composables/query-api.js +5 -3
- package/dist/runtime/app/composables/route.d.ts +1 -1
- package/dist/runtime/app/composables/route.js +4 -4
- package/dist/runtime/app/composables/search.js +1 -1
- package/dist/runtime/app/composables/use-content-document.js +1 -1
- package/dist/runtime/app/composables/use-content-list.js +1 -1
- package/dist/runtime/app/composables/use-content-navigation.js +2 -2
- package/dist/runtime/app/composables/use-content-page.js +4 -4
- package/dist/runtime/app/pages/content.vue +2 -1
- package/dist/runtime/markdown/plugins.js +6 -8
- package/dist/runtime/server/agent-markdown.d.ts +5 -65
- package/dist/runtime/server/agent-markdown.js +40 -315
- package/dist/runtime/server/agent-site.js +1 -1
- package/dist/runtime/server/api/agent-raw.js +1 -1
- package/dist/runtime/server/api/cache.d.ts +1 -1
- package/dist/runtime/server/api/cache.js +43 -4
- package/dist/runtime/server/api/locales.js +3 -3
- package/dist/runtime/server/api/navigation.d.ts +1 -1
- package/dist/runtime/server/api/navigation.js +3 -1
- package/dist/runtime/server/api/query.js +2 -2
- package/dist/runtime/server/api/search-index.d.ts +1 -1
- package/dist/runtime/server/api/sitemap.d.ts +1 -1
- package/dist/runtime/server/cache-adapters.d.ts +18 -0
- package/dist/runtime/server/cache-adapters.js +12 -0
- package/dist/runtime/server/collection-helpers.d.ts +2 -2
- package/dist/runtime/server/collection-helpers.js +15 -11
- package/dist/runtime/server/index.d.ts +6 -4
- package/dist/runtime/server/index.js +10 -3
- package/dist/runtime/server/middleware/agent-link-headers.js +1 -1
- package/dist/runtime/server/middleware/agent-markdown.js +1 -1
- package/dist/runtime/server/navigation-query.d.ts +2 -2
- package/dist/runtime/server/navigation-query.js +52 -7
- package/dist/runtime/server/navigation.d.ts +1 -1
- package/dist/runtime/server/provider-document +1 -0
- package/dist/runtime/server/provider-document.d.ts +59 -0
- package/dist/runtime/server/provider-document.js +48 -0
- package/dist/runtime/server/provider-query-wire +1 -0
- package/dist/runtime/server/provider-query-wire.d.ts +32 -0
- package/dist/runtime/server/provider-query-wire.js +27 -0
- package/dist/runtime/server/provider-query.d.ts +18 -9
- package/dist/runtime/server/provider-query.js +62 -28
- package/dist/runtime/server/provider-result.d.ts +4 -4
- package/dist/runtime/server/providers/filesystem.js +3 -11
- package/dist/runtime/server/providers/index.d.ts +18 -1
- package/dist/runtime/server/providers/index.js +72 -20
- package/dist/runtime/server/query-api.d.ts +5 -5
- package/dist/runtime/server/query-api.js +9 -6
- package/dist/runtime/server/query-executor.d.ts +3 -3
- package/dist/runtime/server/query-executor.js +43 -59
- package/dist/runtime/server/search.d.ts +1 -1
- package/dist/runtime/server/search.js +4 -4
- package/dist/runtime/server/sitemap.js +5 -5
- package/dist/runtime/server/storage-access.d.ts +4 -1
- package/dist/runtime/server/storage-access.js +27 -2
- package/dist/runtime/transformers/component-resolver.d.ts +1 -1
- package/dist/storage/content.d.ts +2 -6
- package/dist/storage/content.js +19 -8
- package/dist/storage/contents.d.ts +9 -1
- package/dist/storage/contents.js +26 -19
- package/dist/storage/driver.d.ts +2 -2
- package/dist/storage/driver.js +2 -1
- package/dist/storage/graph.js +4 -0
- package/dist/storage/manifest.js +3 -1
- package/dist/storage/references.js +9 -5
- package/dist/storage/snapshot-runtime +1 -0
- package/dist/storage/snapshot-runtime.d.ts +11 -0
- package/dist/storage/snapshot-runtime.js +46 -0
- package/dist/storage/validation.d.ts +1 -1
- package/dist/storage/validation.js +47 -102
- package/dist/testing/provider-contract.d.ts +14 -4
- package/dist/testing/provider-contract.js +121 -68
- package/dist/testing/provider-fixture.d.ts +1 -1
- package/dist/testing/provider-fixture.js +124 -120
- package/dist/types/config.d.ts +8 -4
- package/dist/types/content.d.ts +104 -70
- package/dist/types/fields.js +1 -1
- package/dist/types/module.d.ts +1 -1
- package/dist/types/query-parts/public.d.ts +14 -5
- package/dist/types/query-parts/results.d.ts +6 -2
- package/dist/types/query-parts/transport.d.ts +19 -0
- package/dist/types/virtual.d.ts +6 -0
- package/dist/types.d.mts +2 -2
- package/dist/web-types.json +1 -1
- package/package.json +39 -9
- package/dist/runtime/app/plugins/markdown-components +0 -1
- package/dist/runtime/app/plugins/markdown-components.d.ts +0 -2
- package/dist/runtime/app/plugins/markdown-components.js +0 -19
- /package/dist/{runtime → features/agent}/agent-paths +0 -0
- /package/dist/{runtime → features/agent}/agent-paths.d.ts +0 -0
- /package/dist/{runtime → features/agent}/agent-paths.js +0 -0
- /package/dist/{runtime → features}/query/backlinks +0 -0
- /package/dist/{runtime → features}/query/backlinks.d.ts +0 -0
- /package/dist/{runtime → features}/query/context +0 -0
- /package/dist/{runtime → features}/query/context.d.ts +0 -0
- /package/dist/{runtime → features}/query/context.js +0 -0
- /package/dist/{runtime → features}/query/documents +0 -0
- /package/dist/{runtime → features}/query/documents.d.ts +0 -0
- /package/dist/{runtime → features}/query/errors +0 -0
- /package/dist/{runtime → features}/query/errors.d.ts +0 -0
- /package/dist/{runtime → features}/query/errors.js +0 -0
- /package/dist/{runtime → features}/query/handles +0 -0
- /package/dist/{runtime → features}/query/handles.d.ts +0 -0
- /package/dist/{runtime → features}/query/handles.js +0 -0
- /package/dist/{runtime → features}/query/locale-options +0 -0
- /package/dist/{runtime → features}/query/locale-options.d.ts +0 -0
- /package/dist/{runtime → features}/query/locale-options.js +0 -0
- /package/dist/{runtime → features}/query/localized-docs +0 -0
- /package/dist/{runtime → features}/query/navigation +0 -0
- /package/dist/{runtime → features}/query/pagination +0 -0
- /package/dist/{runtime → features}/query/pagination.d.ts +0 -0
- /package/dist/{runtime → features}/query/pagination.js +0 -0
- /package/dist/{runtime → features}/query/populate +0 -0
- /package/dist/{runtime → features}/query/populate.d.ts +0 -0
- /package/dist/{runtime → features}/query/public-limits +0 -0
- /package/dist/{runtime → features}/query/public-limits.d.ts +0 -0
- /package/dist/{runtime → features}/query/public-limits.js +0 -0
- /package/dist/{runtime → features}/query/resolve +0 -0
- /package/dist/{runtime → features}/query/resolve.d.ts +0 -0
- /package/dist/{runtime → features}/query/resolve.js +0 -0
- /package/dist/{runtime → features}/query/responses +0 -0
- /package/dist/{runtime → features}/query/responses.d.ts +0 -0
- /package/dist/{runtime → features}/query/responses.js +0 -0
- /package/dist/{runtime → features}/query/routes +0 -0
- /package/dist/{runtime → features}/query/routes.d.ts +0 -0
- /package/dist/{runtime → features}/query/routes.js +0 -0
- /package/dist/{runtime → features}/query/unified +0 -0
- /package/dist/{runtime → features}/query/variants +0 -0
- /package/dist/{runtime → features}/query/variants.d.ts +0 -0
|
@@ -15,10 +15,10 @@ export default defineEventHandler(async (event) => {
|
|
|
15
15
|
collection,
|
|
16
16
|
exact: false
|
|
17
17
|
});
|
|
18
|
-
const locales = resolved ? resolved.variants.filter((doc) => doc.
|
|
18
|
+
const locales = resolved ? resolved.variants.filter((doc) => doc.canonicalKey === resolved.canonicalKey && typeof doc.locale === "string").sort((left, right) => String(left.locale).localeCompare(String(right.locale))).map((doc) => ({
|
|
19
19
|
canonicalKey: resolved.canonicalKey,
|
|
20
|
-
locale: String(doc.
|
|
21
|
-
...typeof doc.
|
|
20
|
+
locale: String(doc.locale),
|
|
21
|
+
...typeof doc.path === "string" ? { path: doc.path } : {}
|
|
22
22
|
})) : [];
|
|
23
23
|
if (!locales.length) {
|
|
24
24
|
throw createError({
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types").NavItem[]>>;
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types/content").NavItem[]>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineEventHandler, getQuery } from "h3";
|
|
2
2
|
import { getContentQuery } from "../../utils/query.js";
|
|
3
3
|
import { getContentProvider } from "../providers/index.js";
|
|
4
|
+
import { createProviderNavigationQuery } from "../provider-query.js";
|
|
4
5
|
import { createContentProviderError } from "../../../public/provider-errors";
|
|
5
6
|
export default defineEventHandler(async (event) => {
|
|
6
7
|
const query = getContentQuery(event);
|
|
@@ -17,5 +18,6 @@ export default defineEventHandler(async (event) => {
|
|
|
17
18
|
provider: provider.name
|
|
18
19
|
});
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
+
const { query: providerQuery, options } = createProviderNavigationQuery(query);
|
|
22
|
+
return await provider.navigationQuery(event, providerQuery, options);
|
|
21
23
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { defineEventHandler } from "h3";
|
|
2
2
|
import { getContentQuery } from "../../utils/query.js";
|
|
3
3
|
import { getContentProvider } from "../providers/index.js";
|
|
4
|
-
import { normalizeProviderQueryResponse } from "../provider-query.js";
|
|
4
|
+
import { createProviderQuery, normalizeProviderQueryResponse } from "../provider-query.js";
|
|
5
5
|
export default defineEventHandler(async (event) => {
|
|
6
6
|
const query = getContentQuery(event);
|
|
7
7
|
const provider = await getContentProvider(event);
|
|
8
|
-
return normalizeProviderQueryResponse(query, await provider.query(event, query), provider.name);
|
|
8
|
+
return normalizeProviderQueryResponse(query, await provider.query(event, createProviderQuery(query)), provider.name);
|
|
9
9
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types").ContentSearchIndexRecord[]>>;
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types/search").ContentSearchIndexRecord[]>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types").ContentSitemapEntry[]>>;
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<import("../../../types/query").ContentSitemapEntry[]>>;
|
|
2
2
|
export default _default;
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import type { ContentCacheAdapter, ContentCacheHint } from '../../public/provider';
|
|
2
|
+
/**
|
|
3
|
+
* Choosing a cache adapter:
|
|
4
|
+
* - `noopContentCache` — the default. Both `apply` and `invalidate` are intentionally
|
|
5
|
+
* inert: the runtime still computes and stores a cache hint per request, but nothing
|
|
6
|
+
* is written to the response and no upstream cache is purged. Use when caching is
|
|
7
|
+
* handled entirely outside this module (a CDN/edge config you own) or disabled.
|
|
8
|
+
* - `vercelContentCache` — `apply` is intentionally inert (Vercel ISR revalidation is a
|
|
9
|
+
* pull, not a per-response header this module sets); only `invalidate` does work,
|
|
10
|
+
* firing prerender-revalidate HEAD requests. Use on Vercel ISR deployments.
|
|
11
|
+
* - `headersContentCache` — the active-`apply` adapter: writes `Cache-Control`/`ETag`/
|
|
12
|
+
* `Last-Modified` onto every content response from the hint. Use when this module
|
|
13
|
+
* should own response cache headers directly (self-hosted / generic CDN).
|
|
14
|
+
*/
|
|
2
15
|
export declare const noopContentCache: () => ContentCacheAdapter;
|
|
16
|
+
/**
|
|
17
|
+
* Emits the per-request cache hint as HTTP response headers via {@link contentCacheHeaders}.
|
|
18
|
+
* `invalidate` is a no-op: header-based caching has no upstream store to purge.
|
|
19
|
+
*/
|
|
20
|
+
export declare const headersContentCache: () => ContentCacheAdapter;
|
|
3
21
|
export interface VercelContentCacheOptions {
|
|
4
22
|
origin: string;
|
|
5
23
|
bypassToken: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setHeader } from "h3";
|
|
1
2
|
export const noopContentCache = () => ({
|
|
2
3
|
name: "noop",
|
|
3
4
|
apply: () => {
|
|
@@ -5,6 +6,17 @@ export const noopContentCache = () => ({
|
|
|
5
6
|
invalidate: async () => {
|
|
6
7
|
}
|
|
7
8
|
});
|
|
9
|
+
export const headersContentCache = () => ({
|
|
10
|
+
name: "headers",
|
|
11
|
+
apply: (event, hint) => {
|
|
12
|
+
const headers = contentCacheHeaders(hint);
|
|
13
|
+
headers.forEach((value, key) => {
|
|
14
|
+
setHeader(event, key, value);
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
invalidate: async () => {
|
|
18
|
+
}
|
|
19
|
+
});
|
|
8
20
|
export const vercelContentCache = (options) => {
|
|
9
21
|
const origin = options.origin.replace(/\/$/, "");
|
|
10
22
|
const fetchImpl = options.fetch || globalThis.fetch;
|
|
@@ -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
|
-
"
|
|
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 ? {
|
|
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: () =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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("
|
|
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 '
|
|
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
|
|
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 "
|
|
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 {
|
|
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 "
|
|
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 "
|
|
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 {
|
|
4
|
-
export declare function resolveContentNavigation(event: H3Event,
|
|
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
|
-
|
|
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("
|
|
87
|
+
let contentsQuery = createServerContentQuery(event, sourceQuery).where("partial", "=", false).where("type", "=", "markdown").where("navigation", "!=", false);
|
|
43
88
|
if (locale) {
|
|
44
|
-
contentsQuery = contentsQuery.where("
|
|
89
|
+
contentsQuery = contentsQuery.where("locale", "=", locale);
|
|
45
90
|
}
|
|
46
|
-
let dirConfigsQuery = createServerContentQuery(event).where("
|
|
91
|
+
let dirConfigsQuery = createServerContentQuery(event).where("navigationFile", "=", true).where("partial", "=", true);
|
|
47
92
|
if (locale) {
|
|
48
|
-
dirConfigsQuery = dirConfigsQuery.where("
|
|
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.
|
|
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,
|
|
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 {
|
|
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("
|
|
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
|
-
|
|
26
|
-
_resolvedLocale?: string;
|
|
27
|
-
_fallback?: boolean;
|
|
28
|
-
_availableLocales?: string[];
|
|
29
|
-
_variantPaths?: Record<string, string>;
|
|
38
|
+
resolved?: ContentDocumentResolution;
|
|
30
39
|
}) | null>;
|