@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.
- 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 +21 -34
- package/dist/module.d.mts +135 -803
- package/dist/module.json +1 -1
- package/dist/module.mjs +143 -51
- 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 +9 -2
- 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 +79 -105
- 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 +17 -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
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { ContentQueryResponse } from '../../types/api';
|
|
3
3
|
import type { NavItem, ParsedContent } from '../../types/content';
|
|
4
|
-
import type { ContentCollectionItemSurroundingsOptions, ContentCollectionNavigationOptions, ContentCollectionPageOptions, ContentCollectionRouteMetaOptions, ContentCollectionSearchSectionsOptions, ContentPageResult,
|
|
4
|
+
import type { ContentCollectionItemSurroundingsOptions, ContentCollectionNavigationOptions, ContentCollectionPageOptions, ContentCollectionRouteMetaOptions, ContentCollectionSearchSectionsOptions, ContentPageResult, ContentRouteMeta, ContentSearchSection, ContentSitemapEntry } from '../../types/query';
|
|
5
5
|
import type { QueryCollectionsSitemapEntriesOptions } from '../../features/sitemap/query';
|
|
6
|
-
import type { ContentProvider, ContentProviderResult, ContentProviderSiteDataRequest, ContentProviderSiteDataResponse, MaybeContentProviderResult } from '../../public/provider';
|
|
6
|
+
import type { ContentProvider, ContentProviderNavigationOptions, ContentProviderQuery, ContentProviderResult, ContentProviderSiteDataRequest, ContentProviderSiteDataResponse, MaybeContentProviderResult } from '../../public/provider';
|
|
7
7
|
import type { ContentProviderSearchRequest, ContentSearchResult } from '../../types/search';
|
|
8
8
|
export declare const isContentProviderResult: <T = unknown>(value: unknown) => value is ContentProviderResult<T>;
|
|
9
9
|
export declare const unwrapContentProviderResult: <T>(event: H3Event, result: MaybeContentProviderResult<T>) => T;
|
|
10
10
|
export interface RuntimeContentProvider extends Omit<ContentProvider, 'query' | 'navigationQuery' | 'navigation' | 'surroundings' | 'searchSections' | 'search' | 'siteData' | 'page' | 'routeMeta' | 'sitemapEntries'> {
|
|
11
|
-
query: <T = ParsedContent>(event: H3Event, query:
|
|
12
|
-
navigationQuery?: (event: H3Event, query:
|
|
11
|
+
query: <T = ParsedContent>(event: H3Event, query: ContentProviderQuery) => Promise<ContentQueryResponse<T>>;
|
|
12
|
+
navigationQuery?: (event: H3Event, query: ContentProviderQuery, options?: ContentProviderNavigationOptions) => Promise<NavItem[]>;
|
|
13
13
|
navigation?: (event: H3Event, collection: string, options?: string[] | ContentCollectionNavigationOptions) => Promise<NavItem[]>;
|
|
14
14
|
surroundings?: (event: H3Event, collection: string, path: string, options?: ContentCollectionItemSurroundingsOptions) => Promise<Array<NavItem | null>>;
|
|
15
15
|
searchSections?: (event: H3Event, collection: string, options?: ContentCollectionSearchSectionsOptions) => Promise<ContentSearchSection[]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SUPPORTED_QUERY_OPERATORS } from "../../../core/query/operators";
|
|
2
2
|
import { executeFilesystemContentQuery } from "../query-executor.js";
|
|
3
3
|
import { resolveContentNavigation } from "../navigation-query.js";
|
|
4
4
|
import {
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
queryFilesystemCollectionSearchSections
|
|
10
10
|
} from "../collection-helpers.js";
|
|
11
11
|
import { queryFilesystemCollectionsSitemapEntries } from "../sitemap.js";
|
|
12
|
-
import { createContentProviderError } from "../../../public/provider-errors";
|
|
13
12
|
export const filesystemProvider = {
|
|
14
13
|
name: "filesystem",
|
|
15
14
|
capabilities: {
|
|
@@ -32,15 +31,8 @@ export const filesystemProvider = {
|
|
|
32
31
|
count: true
|
|
33
32
|
}
|
|
34
33
|
},
|
|
35
|
-
query: (event, query) =>
|
|
36
|
-
|
|
37
|
-
throw createContentProviderError("unsupported_query_shape", "Query operator $options requires $regex.", {
|
|
38
|
-
operator: "$options"
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
return executeFilesystemContentQuery(event, query);
|
|
42
|
-
},
|
|
43
|
-
navigationQuery: (event, query) => resolveContentNavigation(event, query),
|
|
34
|
+
query: (event, query) => executeFilesystemContentQuery(event, query.plan),
|
|
35
|
+
navigationQuery: (event, query, options) => resolveContentNavigation(event, query, options),
|
|
44
36
|
navigation: (event, collection, options) => queryFilesystemCollectionNavigation(event, collection, options),
|
|
45
37
|
surroundings: (event, collection, path, options) => queryFilesystemCollectionItemSurroundings(event, collection, path, options),
|
|
46
38
|
searchSections: (event, collection, options) => queryFilesystemCollectionSearchSections(event, collection, options),
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
|
-
import type
|
|
2
|
+
import { type ContentProvider, type ContentProviderQuery } from '../../../public/provider';
|
|
3
|
+
import type { FilterExpr } from '../../../core/query/plan';
|
|
3
4
|
import { type RuntimeContentProvider } from '../provider-result';
|
|
5
|
+
/**
|
|
6
|
+
* Derive the operator vocabulary a plan actually exercises by walking its
|
|
7
|
+
* `FilterExpr` tree (CS-5 trap 3). Only `compare` nodes carry operators; we
|
|
8
|
+
* recurse through `and`/`or`/`not` to reach every one. Operators are reported
|
|
9
|
+
* in the builder's `$`-prefixed vocabulary so they compare directly against
|
|
10
|
+
* `capabilities.query.operators`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const collectPlanFilterOperators: (filter: FilterExpr, operators?: Set<string>) => Set<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Dev-mode guard: the provider wire is JSON-pure by contract (CS-5). A stray
|
|
15
|
+
* `RegExp`/`Date` in `plan.filter` would corrupt any provider that serializes
|
|
16
|
+
* the query, so we fail fast in dev instead of shipping a silently mangled
|
|
17
|
+
* wire. No-op in production (the walk is not free).
|
|
18
|
+
*/
|
|
19
|
+
export declare const assertJsonPureProviderQuery: (provider: ContentProvider, query: ContentProviderQuery) => void;
|
|
20
|
+
export declare const enforceProviderCapabilities: (provider: ContentProvider) => ContentProvider;
|
|
4
21
|
export declare function getContentProvider(): Promise<ContentProvider>;
|
|
5
22
|
export declare function getContentProvider(event: H3Event): Promise<RuntimeContentProvider>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
2
|
import { loadExternalContentProvider } from "#content/virtual/providers";
|
|
3
|
+
import { PROVIDER_QUERY_VERSION } from "../../../public/provider";
|
|
3
4
|
import { createContentProviderError } from "../../../public/provider-errors";
|
|
4
5
|
import { wrapContentProviderCacheResults } from "../provider-result.js";
|
|
5
6
|
const isObject = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -24,43 +25,91 @@ const assertProviderField = (providerName, condition, field) => {
|
|
|
24
25
|
const assertProviderMethod = (providerName, provider, method) => {
|
|
25
26
|
assertProviderField(providerName, typeof provider[method] === "function", method);
|
|
26
27
|
};
|
|
27
|
-
const
|
|
28
|
-
|
|
28
|
+
export const collectPlanFilterOperators = (filter, operators = /* @__PURE__ */ new Set()) => {
|
|
29
|
+
switch (filter.type) {
|
|
30
|
+
case "true":
|
|
31
|
+
break;
|
|
32
|
+
case "compare":
|
|
33
|
+
operators.add(`$${filter.operator}`);
|
|
34
|
+
break;
|
|
35
|
+
case "and":
|
|
36
|
+
case "or":
|
|
37
|
+
for (const clause of filter.clauses) {
|
|
38
|
+
collectPlanFilterOperators(clause, operators);
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
case "not":
|
|
42
|
+
collectPlanFilterOperators(filter.clause, operators);
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
throw new TypeError(`Unknown query filter node: ${filter.type}`);
|
|
46
|
+
}
|
|
47
|
+
return operators;
|
|
48
|
+
};
|
|
49
|
+
const findNonJsonValue = (value, path) => {
|
|
50
|
+
if (value === null || value === void 0) return void 0;
|
|
51
|
+
const kind = typeof value;
|
|
52
|
+
if (kind === "string" || kind === "number" || kind === "boolean") return void 0;
|
|
53
|
+
if (kind === "function" || kind === "bigint" || kind === "symbol") return path;
|
|
29
54
|
if (Array.isArray(value)) {
|
|
30
|
-
for (
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
55
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
56
|
+
const offender = findNonJsonValue(value[index], `${path}[${index}]`);
|
|
57
|
+
if (offender) return offender;
|
|
33
58
|
}
|
|
34
59
|
return void 0;
|
|
35
60
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
61
|
+
if (kind === "object") {
|
|
62
|
+
const prototype = Object.getPrototypeOf(value);
|
|
63
|
+
if (prototype !== Object.prototype && prototype !== null) return path;
|
|
64
|
+
for (const [key, child] of Object.entries(value)) {
|
|
65
|
+
const offender = findNonJsonValue(child, `${path}.${key}`);
|
|
66
|
+
if (offender) return offender;
|
|
67
|
+
}
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
return path;
|
|
71
|
+
};
|
|
72
|
+
export const assertJsonPureProviderQuery = (provider, query) => {
|
|
73
|
+
if (!import.meta.dev) return;
|
|
74
|
+
const offender = findNonJsonValue(query, "query");
|
|
75
|
+
if (offender) {
|
|
76
|
+
throw createContentProviderError("provider_query_not_json_pure", `${provider.name} received a non-JSON-pure query at ${offender}. Provider queries must survive JSON.parse(JSON.stringify(query)).`, {
|
|
77
|
+
provider: provider.name,
|
|
78
|
+
field: offender
|
|
79
|
+
});
|
|
40
80
|
}
|
|
41
81
|
};
|
|
42
82
|
const assertProviderQuerySupported = (provider, query) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (unsupportedOperator) {
|
|
46
|
-
throw createContentProviderError("unsupported_query_operator", `${provider.name} does not support query operator: ${unsupportedOperator}`, {
|
|
83
|
+
if (query.v !== PROVIDER_QUERY_VERSION) {
|
|
84
|
+
throw createContentProviderError("unsupported_query_shape", `${provider.name} received unsupported provider query version: ${String(query.v)}.`, {
|
|
47
85
|
provider: provider.name,
|
|
48
|
-
|
|
86
|
+
field: "v"
|
|
49
87
|
});
|
|
50
88
|
}
|
|
51
|
-
|
|
89
|
+
const capabilities = provider.capabilities.query;
|
|
90
|
+
const supported = new Set(capabilities.operators);
|
|
91
|
+
const usedOperators = collectPlanFilterOperators(query.plan.filter);
|
|
92
|
+
for (const operator of usedOperators) {
|
|
93
|
+
if (!supported.has(operator)) {
|
|
94
|
+
throw createContentProviderError("unsupported_query_operator", `${provider.name} does not support query operator: ${operator}`, {
|
|
95
|
+
provider: provider.name,
|
|
96
|
+
operator
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!capabilities.limit && query.plan.limit !== void 0) {
|
|
52
101
|
throw createContentProviderError("unsupported_query_shape", `${provider.name} does not support query limits.`, {
|
|
53
102
|
provider: provider.name,
|
|
54
103
|
field: "limit"
|
|
55
104
|
});
|
|
56
105
|
}
|
|
57
|
-
if (!capabilities.skip && query.skip
|
|
106
|
+
if (!capabilities.skip && query.plan.skip > 0) {
|
|
58
107
|
throw createContentProviderError("unsupported_query_shape", `${provider.name} does not support query offsets.`, {
|
|
59
108
|
provider: provider.name,
|
|
60
109
|
field: "skip"
|
|
61
110
|
});
|
|
62
111
|
}
|
|
63
|
-
if (!capabilities.count && query.
|
|
112
|
+
if (!capabilities.count && query.plan.mode === "count") {
|
|
64
113
|
throw createContentProviderError("unsupported_query_shape", `${provider.name} does not support count queries.`, {
|
|
65
114
|
provider: provider.name,
|
|
66
115
|
field: "count"
|
|
@@ -75,15 +124,18 @@ const assertProviderOperationSupported = (provider, supported, operation) => {
|
|
|
75
124
|
});
|
|
76
125
|
}
|
|
77
126
|
};
|
|
78
|
-
const enforceProviderCapabilities = (provider) => ({
|
|
127
|
+
export const enforceProviderCapabilities = (provider) => ({
|
|
79
128
|
...provider,
|
|
80
129
|
query: async (event, query) => {
|
|
130
|
+
assertJsonPureProviderQuery(provider, query);
|
|
81
131
|
assertProviderQuerySupported(provider, query);
|
|
82
132
|
return await provider.query(event, query);
|
|
83
133
|
},
|
|
84
|
-
navigationQuery: provider.navigationQuery ? async (
|
|
134
|
+
navigationQuery: provider.navigationQuery ? async (event, query, options) => {
|
|
85
135
|
assertProviderOperationSupported(provider, provider.capabilities.navigation, "navigation");
|
|
86
|
-
|
|
136
|
+
assertJsonPureProviderQuery(provider, query);
|
|
137
|
+
assertProviderQuerySupported(provider, query);
|
|
138
|
+
return await provider.navigationQuery(event, query, options);
|
|
87
139
|
} : void 0,
|
|
88
140
|
navigation: provider.navigation ? async (...args) => {
|
|
89
141
|
assertProviderOperationSupported(provider, provider.capabilities.navigation, "navigation");
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
2
|
import type { ParsedContent } from '../../types/content';
|
|
3
3
|
import type { ContentCollectionHandle } from '../../types/config';
|
|
4
|
-
import type { BacklinksOptions, BacklinksResult, BacklinkSource, ContentVariant, ContentTreeItem, DocumentFromHandle, ManyOptions, LocalizedDoc, NeighborsOptions, NeighborsResult, OneOptions, PopulateSpec, PopulateFromOptions, PopulatedDocument, PaginationOptions, PaginationResult, ResolveOneOptions, ResolveOneResult, TreeOptions, VariantsOptions } from '../../types/query';
|
|
5
|
-
import { type ContentQueryContext } from '
|
|
4
|
+
import type { BacklinksOptions, BacklinksResult, BacklinkSource, ContentVariant, ContentTreeItem, DocumentFromHandle, ManyOptions, LocalizedDoc, NeighborsOptions, NeighborsResult, OneOptions, OptionsArg, PopulateSpec, PopulateFromOptions, PopulatedDocument, PaginationOptions, PaginationResult, ResolveOneOptions, ResolveOneResult, TreeOptions, VariantsOptions } from '../../types/query';
|
|
5
|
+
import { type ContentQueryContext } from '../../features/query/unified';
|
|
6
6
|
export declare const createServerContentQueryContext: (event: H3Event) => Promise<ContentQueryContext>;
|
|
7
7
|
export declare function resolveOne<const H extends ContentCollectionHandle | string, O extends ResolveOneOptions<H, PopulateSpec | undefined>>(event: H3Event, handle: H, options: O): Promise<ResolveOneResult<PopulatedDocument<DocumentFromHandle<H>, PopulateFromOptions<O>>>>;
|
|
8
8
|
export declare function one<const H extends ContentCollectionHandle | string, O extends OneOptions<H, PopulateSpec | undefined>>(event: H3Event, handle: H, options: O): Promise<LocalizedDoc<PopulatedDocument<DocumentFromHandle<H>, PopulateFromOptions<O>>> | null>;
|
|
9
|
-
export declare function many<const H extends ContentCollectionHandle | string, O extends ManyOptions<H, PopulateSpec | undefined>>(event: H3Event, handle: H,
|
|
9
|
+
export declare function many<const H extends ContentCollectionHandle | string, O extends ManyOptions<H, PopulateSpec | undefined>>(event: H3Event, handle: H, ...args: OptionsArg<H, O>): Promise<Array<LocalizedDoc<PopulatedDocument<DocumentFromHandle<H>, PopulateFromOptions<O>>>>>;
|
|
10
10
|
export declare function paginate<const H extends ContentCollectionHandle | string, O extends PaginationOptions<H, PopulateSpec | undefined>>(event: H3Event, handle: H, options: O): Promise<PaginationResult<PopulatedDocument<DocumentFromHandle<H>, PopulateFromOptions<O>>>>;
|
|
11
11
|
export declare function backlinks<const Target extends ContentCollectionHandle | string, const Source extends BacklinkSource | ReadonlyArray<BacklinkSource>, P extends PopulateSpec | undefined = undefined>(event: H3Event, handle: Target, options: BacklinksOptions<Target, Source, P>): Promise<BacklinksResult<Source, P>>;
|
|
12
12
|
export declare function variants<H extends ContentCollectionHandle | string>(event: H3Event, handle: H, options: VariantsOptions<H>): Promise<Array<ContentVariant<H extends {
|
|
@@ -14,9 +14,9 @@ export declare function variants<H extends ContentCollectionHandle | string>(eve
|
|
|
14
14
|
_output: infer O;
|
|
15
15
|
};
|
|
16
16
|
} ? O & ParsedContent : ParsedContent>>>;
|
|
17
|
-
export declare function tree<H extends ContentCollectionHandle | string, Fields extends ReadonlyArray<string> | undefined = undefined>(event: H3Event, handle: H,
|
|
17
|
+
export declare function tree<H extends ContentCollectionHandle | string, Fields extends ReadonlyArray<string> | undefined = undefined>(event: H3Event, handle: H, ...args: OptionsArg<H, Omit<TreeOptions<H>, 'fields'> & {
|
|
18
18
|
fields?: Fields;
|
|
19
|
-
}): Promise<ContentTreeItem<H extends {
|
|
19
|
+
}>): Promise<ContentTreeItem<H extends {
|
|
20
20
|
__schema: {
|
|
21
21
|
_output: infer O;
|
|
22
22
|
};
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
resolveOne as resolveOneWithContext,
|
|
8
8
|
tree as treeWithContext,
|
|
9
9
|
variants as variantsWithContext
|
|
10
|
-
} from "
|
|
10
|
+
} from "../../features/query/unified";
|
|
11
11
|
import { getContentProvider } from "./providers/index.js";
|
|
12
12
|
import { createContentProviderError } from "../../public/provider-errors";
|
|
13
13
|
import { getContentRuntimeConfig } from "./runtime-config.js";
|
|
14
|
-
import { normalizeProviderQueryResponse } from "./provider-query.js";
|
|
14
|
+
import { createProviderNavigationQuery, createProviderQuery, normalizeProviderQueryResponse } from "./provider-query.js";
|
|
15
15
|
export const createServerContentQueryContext = async (event) => {
|
|
16
16
|
const provider = await getContentProvider(event);
|
|
17
17
|
return {
|
|
@@ -23,9 +23,10 @@ export const createServerContentQueryContext = async (event) => {
|
|
|
23
23
|
provider: provider.name
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const { query, options } = createProviderNavigationQuery(params);
|
|
27
|
+
return await provider.navigationQuery(event, query, options);
|
|
27
28
|
}
|
|
28
|
-
return normalizeProviderQueryResponse(params, await provider.query(event, params), provider.name);
|
|
29
|
+
return normalizeProviderQueryResponse(params, await provider.query(event, createProviderQuery(params)), provider.name);
|
|
29
30
|
}
|
|
30
31
|
};
|
|
31
32
|
};
|
|
@@ -35,7 +36,8 @@ export async function resolveOne(event, handle, options) {
|
|
|
35
36
|
export async function one(event, handle, options) {
|
|
36
37
|
return await oneWithContext(await createServerContentQueryContext(event), handle, options);
|
|
37
38
|
}
|
|
38
|
-
export async function many(event, handle,
|
|
39
|
+
export async function many(event, handle, ...args) {
|
|
40
|
+
const options = args[0] ?? {};
|
|
39
41
|
return await manyWithContext(await createServerContentQueryContext(event), handle, options);
|
|
40
42
|
}
|
|
41
43
|
export async function paginate(event, handle, options) {
|
|
@@ -47,7 +49,8 @@ export async function backlinks(event, handle, options) {
|
|
|
47
49
|
export async function variants(event, handle, options) {
|
|
48
50
|
return await variantsWithContext(await createServerContentQueryContext(event), handle, options);
|
|
49
51
|
}
|
|
50
|
-
export async function tree(event, handle,
|
|
52
|
+
export async function tree(event, handle, ...args) {
|
|
53
|
+
const options = args[0] ?? {};
|
|
51
54
|
return await treeWithContext(await createServerContentQueryContext(event), handle, options);
|
|
52
55
|
}
|
|
53
56
|
export async function neighbors(event, handle, options) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type H3Event } from 'h3';
|
|
2
2
|
import type { ContentQueryResponse } from '../../types/api';
|
|
3
|
-
import type {
|
|
4
|
-
export declare const executeFilesystemContentQuery: <T = unknown>(event: H3Event,
|
|
5
|
-
export declare const executeContentQuery: <T = unknown>(event: H3Event,
|
|
3
|
+
import type { ContentQueryPlan } from '../../core/query/plan';
|
|
4
|
+
export declare const executeFilesystemContentQuery: <T = unknown>(event: H3Event, inputPlan: ContentQueryPlan) => Promise<ContentQueryResponse<T>>;
|
|
5
|
+
export declare const executeContentQuery: <T = unknown>(event: H3Event, inputPlan: ContentQueryPlan) => Promise<ContentQueryResponse<T>>;
|
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
import { createError } from "h3";
|
|
2
|
-
import {
|
|
2
|
+
import { isPlanRegex } from "../../core/query/plan";
|
|
3
3
|
import { executeQueryPlan } from "../../core/query/execute";
|
|
4
4
|
import { ContentError } from "../../core/errors";
|
|
5
|
-
import { normalizeContentQueryParams } from "../../core/query/params";
|
|
6
|
-
import { compileWhere } from "../../core/query/filter";
|
|
7
|
-
import { containsStandaloneRegexOptions, findUnsupportedQueryOperator } from "../../core/query/operators";
|
|
8
5
|
import { withResolvedRefs, withResolvedRefsList } from "../../storage/references";
|
|
9
6
|
import { getContentGraph } from "../../storage/graph";
|
|
10
7
|
import { getContentRuntimeConfig } from "./runtime-config.js";
|
|
11
8
|
import { isPreview } from "../../integrations/nitro/preview";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
const notFound = (query, description = "Could not find document for the given query.") => {
|
|
9
|
+
import { MAX_PUBLIC_QUERY_LIMIT, MAX_PUBLIC_QUERY_SKIP } from "../../features/query/public-limits";
|
|
10
|
+
const notFound = (plan, description = "Could not find document for the given query.") => {
|
|
15
11
|
throw createError({
|
|
16
12
|
statusMessage: "Document not found!",
|
|
17
13
|
statusCode: 404,
|
|
18
14
|
data: {
|
|
19
15
|
description,
|
|
20
|
-
query
|
|
16
|
+
query: plan
|
|
21
17
|
}
|
|
22
18
|
});
|
|
23
19
|
};
|
|
24
20
|
const statusForContentError = {
|
|
25
21
|
INVALID_REF_VALUE: 422
|
|
26
22
|
};
|
|
27
|
-
const toHttpError = (error,
|
|
23
|
+
const toHttpError = (error, plan) => createError({
|
|
28
24
|
statusCode: statusForContentError[error.code] ?? 500,
|
|
29
25
|
statusMessage: error.code,
|
|
30
26
|
message: error.message,
|
|
31
|
-
data: { code: error.code, context: error.context, query }
|
|
27
|
+
data: { code: error.code, context: error.context, query: plan }
|
|
32
28
|
});
|
|
33
29
|
const badQuery = (message) => {
|
|
34
30
|
throw createError({
|
|
@@ -37,71 +33,59 @@ const badQuery = (message) => {
|
|
|
37
33
|
message
|
|
38
34
|
});
|
|
39
35
|
};
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
const planFilterContainsRegex = (filter) => {
|
|
37
|
+
switch (filter.type) {
|
|
38
|
+
case "true":
|
|
39
|
+
return false;
|
|
40
|
+
case "compare":
|
|
41
|
+
return filter.operator === "regex" || isPlanRegex(filter.value);
|
|
42
|
+
case "and":
|
|
43
|
+
case "or":
|
|
44
|
+
return filter.clauses.some(planFilterContainsRegex);
|
|
45
|
+
case "not":
|
|
46
|
+
return planFilterContainsRegex(filter.clause);
|
|
47
|
+
default:
|
|
48
|
+
throw new TypeError(`Unknown query filter node: ${filter.type}`);
|
|
43
49
|
}
|
|
44
|
-
if (!value || typeof value !== "object") {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
if (Array.isArray(value)) {
|
|
48
|
-
return value.some(containsPublicRegex);
|
|
49
|
-
}
|
|
50
|
-
const record = value;
|
|
51
|
-
return Object.entries(record).some(([key, child]) => key === "$regex" || containsPublicRegex(child));
|
|
52
50
|
};
|
|
53
|
-
const
|
|
54
|
-
|
|
51
|
+
const andPlanFilters = (base, ...extra) => {
|
|
52
|
+
const clauses = [base, ...extra].filter((clause) => clause.type !== "true");
|
|
53
|
+
if (!clauses.length) return { type: "true" };
|
|
54
|
+
if (clauses.length === 1) return clauses[0];
|
|
55
|
+
return { type: "and", clauses };
|
|
56
|
+
};
|
|
57
|
+
const applyFilesystemQueryPolicy = (event, plan) => {
|
|
58
|
+
if (!plan.collection) {
|
|
55
59
|
badQuery("Public content queries must target a collection.");
|
|
56
60
|
}
|
|
57
|
-
if (
|
|
61
|
+
if (planFilterContainsRegex(plan.filter)) {
|
|
58
62
|
badQuery("Public content queries do not accept RegExp filters.");
|
|
59
63
|
}
|
|
60
|
-
if (containsStandaloneRegexOptions(query.where)) {
|
|
61
|
-
badQuery("Query operator $options requires $regex.");
|
|
62
|
-
}
|
|
63
64
|
const enforceProductionVisibility = !import.meta.dev && !isPreview(event);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const where = Array.isArray(normalized.where) ? normalized.where : normalized.where ? [normalized.where] : [];
|
|
76
|
-
normalized.where = [
|
|
77
|
-
...where,
|
|
78
|
-
{ _draft: { $ne: true } },
|
|
79
|
-
{ _partial: { $ne: true } }
|
|
80
|
-
];
|
|
81
|
-
}
|
|
82
|
-
const normalizedWhere = Array.isArray(normalized.where) ? normalized.where : normalized.where ? [normalized.where] : [];
|
|
83
|
-
normalized.where = normalizedWhere.map((condition) => compileWhere(condition)).filter((condition) => Boolean(condition));
|
|
84
|
-
const unsupported = findUnsupportedQueryOperator(normalized.where);
|
|
85
|
-
if (unsupported) {
|
|
86
|
-
throw createContentProviderError("unsupported_query_operator", `Unsupported query operator: ${unsupported}`, {
|
|
87
|
-
operator: unsupported
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
return normalized;
|
|
65
|
+
const filter = enforceProductionVisibility ? andPlanFilters(
|
|
66
|
+
plan.filter,
|
|
67
|
+
{ type: "compare", field: "draft", operator: "ne", value: true },
|
|
68
|
+
{ type: "compare", field: "partial", operator: "ne", value: true }
|
|
69
|
+
) : plan.filter;
|
|
70
|
+
return {
|
|
71
|
+
...plan,
|
|
72
|
+
filter,
|
|
73
|
+
limit: typeof plan.limit === "number" ? Math.max(0, Math.min(plan.limit, MAX_PUBLIC_QUERY_LIMIT)) : plan.limit,
|
|
74
|
+
skip: Math.max(0, Math.min(plan.skip, MAX_PUBLIC_QUERY_SKIP))
|
|
75
|
+
};
|
|
91
76
|
};
|
|
92
|
-
export const executeFilesystemContentQuery = async (event,
|
|
77
|
+
export const executeFilesystemContentQuery = async (event, inputPlan) => {
|
|
93
78
|
const config = getContentRuntimeConfig().content || {};
|
|
94
|
-
const
|
|
79
|
+
const plan = applyFilesystemQueryPolicy(event, inputPlan);
|
|
95
80
|
let graph;
|
|
96
81
|
try {
|
|
97
82
|
graph = await getContentGraph(event);
|
|
98
83
|
} catch (cause) {
|
|
99
84
|
if (cause instanceof ContentError) {
|
|
100
|
-
throw toHttpError(cause,
|
|
85
|
+
throw toHttpError(cause, plan);
|
|
101
86
|
}
|
|
102
87
|
throw cause;
|
|
103
88
|
}
|
|
104
|
-
const plan = lowerQueryPlan(query);
|
|
105
89
|
const response = executeQueryPlan(graph, plan, {
|
|
106
90
|
defaultLocale: config.defaultLocale,
|
|
107
91
|
localeFallback: config.localeFallback,
|
|
@@ -114,7 +98,7 @@ export const executeFilesystemContentQuery = async (event, inputQuery) => {
|
|
|
114
98
|
if (plan.mode === "first") {
|
|
115
99
|
const content = response.result;
|
|
116
100
|
if (!content) {
|
|
117
|
-
notFound(
|
|
101
|
+
notFound(plan, plan.resolveVariant ? "Could not find document for the given route variant." : void 0);
|
|
118
102
|
}
|
|
119
103
|
return {
|
|
120
104
|
result: await withResolvedRefs(event, content, requestedLocale)
|
|
@@ -3,7 +3,7 @@ import type { ParsedContent } from '../../types/content';
|
|
|
3
3
|
import type { ContentQueryBuilderWhere } from '../../types/query';
|
|
4
4
|
import type { ContentSearchIndexRecord } from '../../types/search';
|
|
5
5
|
export { searchRecords } from '../shared/search';
|
|
6
|
-
type SearchablePage = Pick<ParsedContent, '
|
|
6
|
+
type SearchablePage = Pick<ParsedContent, 'path' | 'locale' | 'title' | 'description' | 'body'> & Record<string, unknown>;
|
|
7
7
|
type RuntimeSearchConfig = {
|
|
8
8
|
search?: {
|
|
9
9
|
collections?: string[];
|
|
@@ -39,7 +39,7 @@ const rememberSearchRecords = (cacheKey, records) => {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
const mergeSearchFilter = (filterQuery, locale) => {
|
|
42
|
-
const localeFilter = locale ? {
|
|
42
|
+
const localeFilter = locale ? { locale } : void 0;
|
|
43
43
|
if (filterQuery && localeFilter) {
|
|
44
44
|
return { $and: [filterQuery, localeFilter] };
|
|
45
45
|
}
|
|
@@ -50,7 +50,7 @@ export async function serverSearchContent(event, filterQuery, locale, collection
|
|
|
50
50
|
const collections = resolveSearchCollections(runtimeConfig.content, collectionsOverride);
|
|
51
51
|
const results = await Promise.all(collections.map(async (collection) => {
|
|
52
52
|
const loadPages = async (queryLocale) => {
|
|
53
|
-
const query = serverQueryCollection(event, collection).select("
|
|
53
|
+
const query = serverQueryCollection(event, collection).select("path", "locale", "title", "description", "body");
|
|
54
54
|
const mergedFilter = mergeSearchFilter(filterQuery, queryLocale);
|
|
55
55
|
if (mergedFilter) {
|
|
56
56
|
return await query.where(mergedFilter).find();
|
|
@@ -84,7 +84,7 @@ const toSearchRecord = (section) => {
|
|
|
84
84
|
content: section.content,
|
|
85
85
|
headings: section.titles,
|
|
86
86
|
anchor: anchor || void 0,
|
|
87
|
-
locale: typeof section.
|
|
87
|
+
locale: typeof section.locale === "string" ? section.locale : void 0
|
|
88
88
|
};
|
|
89
89
|
};
|
|
90
90
|
const buildProviderSearchSections = async (event, collections, provider, opts) => {
|
|
@@ -92,7 +92,7 @@ const buildProviderSearchSections = async (event, collections, provider, opts) =
|
|
|
92
92
|
const sections = await Promise.all(collections.map(async (collection) => {
|
|
93
93
|
const loadCollectionLocale = async (locale) => (await provider.searchSections(event, collection, {
|
|
94
94
|
ignoredTags: opts.ignoredTags || [],
|
|
95
|
-
extraFields: unique(["
|
|
95
|
+
extraFields: unique(["locale", ...opts.extraFields || []]),
|
|
96
96
|
filterQuery: opts.filterQuery,
|
|
97
97
|
locale
|
|
98
98
|
})).map((section) => ({
|
|
@@ -6,11 +6,11 @@ import { serverQueryCollection } from "./storage.js";
|
|
|
6
6
|
import { contentConfig } from "./storage-access.js";
|
|
7
7
|
import { resolveCollectionI18n } from "../../features/localization/path";
|
|
8
8
|
const sitemapPageFields = [
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
9
|
+
"path",
|
|
10
|
+
"file",
|
|
11
|
+
"locale",
|
|
12
|
+
"draft",
|
|
13
|
+
"canonicalKey",
|
|
14
14
|
"sitemap",
|
|
15
15
|
"image",
|
|
16
16
|
"seo",
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
import { cacheParsedStorage, cacheStorage, contentConfig, contentIgnorePredicate, getSourceContentIds, resolveStorageId, sourceStorage } from '../../integrations/nitro/storage';
|
|
3
|
+
export declare const getContentsIds: (event: H3Event, prefix?: string) => Promise<string[]>;
|
|
4
|
+
export { cacheParsedStorage, cacheStorage, contentConfig, contentIgnorePredicate, getSourceContentIds, resolveStorageId, sourceStorage };
|
|
@@ -1,9 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
import { splitInlineLocaleVariantId } from "../../core/content/locale";
|
|
2
|
+
import {
|
|
2
3
|
cacheParsedStorage,
|
|
3
4
|
cacheStorage,
|
|
4
5
|
contentConfig,
|
|
5
6
|
contentIgnorePredicate,
|
|
6
|
-
getContentsIds,
|
|
7
|
+
getContentsIds as getStorageContentsIds,
|
|
8
|
+
getSourceContentIds,
|
|
7
9
|
resolveStorageId,
|
|
8
10
|
sourceStorage
|
|
9
11
|
} from "../../integrations/nitro/storage";
|
|
12
|
+
import { getProcessDocuments, usesProcessSnapshot } from "../../storage/snapshot-runtime";
|
|
13
|
+
export const getContentsIds = async (event, prefix) => {
|
|
14
|
+
if (!usesProcessSnapshot) {
|
|
15
|
+
return getStorageContentsIds(event, prefix);
|
|
16
|
+
}
|
|
17
|
+
const ids = /* @__PURE__ */ new Set();
|
|
18
|
+
for (const document of await getProcessDocuments(event)) {
|
|
19
|
+
const { sourceId } = splitInlineLocaleVariantId(document.id);
|
|
20
|
+
if (!prefix || sourceId.startsWith(prefix)) {
|
|
21
|
+
ids.add(sourceId);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return [...ids];
|
|
25
|
+
};
|
|
26
|
+
export {
|
|
27
|
+
cacheParsedStorage,
|
|
28
|
+
cacheStorage,
|
|
29
|
+
contentConfig,
|
|
30
|
+
contentIgnorePredicate,
|
|
31
|
+
getSourceContentIds,
|
|
32
|
+
resolveStorageId,
|
|
33
|
+
sourceStorage
|
|
34
|
+
};
|
|
@@ -6,5 +6,5 @@ export declare function loadComponents(node: ParsedContent['body'] | {
|
|
|
6
6
|
props?: Record<string, unknown>;
|
|
7
7
|
children?: Array<ParsedContent['body']>;
|
|
8
8
|
} | null, tags: Record<string, string>): [string, unknown][];
|
|
9
|
-
declare const _default: import("../../types").ContentTransformer;
|
|
9
|
+
declare const _default: import("../../types/content").ContentTransformer;
|
|
10
10
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
|
-
import type { ParsedContent } from '../types/content';
|
|
2
|
+
import type { ContentDocumentResolution, ParsedContent } from '../types/content';
|
|
3
3
|
import type { ContentCollectionMap, ContentLocaleEntry, ContentQueryBuilderParams, ContentQueryFetcher, CollectionQueryBuilder, ResolveContentReferenceOptions } from '../types/query';
|
|
4
4
|
export declare const createServerQueryFetch: <T = ParsedContent>(event: H3Event) => ContentQueryFetcher<T>;
|
|
5
5
|
/**
|
|
@@ -19,11 +19,7 @@ export declare const createServerQueryFetch: <T = ParsedContent>(event: H3Event)
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
export declare const resolveContentReference: <T = ParsedContent>(event: H3Event, reference: string, options?: ResolveContentReferenceOptions) => Promise<(T & {
|
|
22
|
-
|
|
23
|
-
_resolvedLocale?: string;
|
|
24
|
-
_fallback?: boolean;
|
|
25
|
-
_availableLocales?: string[];
|
|
26
|
-
_variantPaths?: Record<string, string>;
|
|
22
|
+
resolved?: ContentDocumentResolution;
|
|
27
23
|
}) | null>;
|
|
28
24
|
export declare const createServerContentQuery: <T = ParsedContent>(event: H3Event, query?: string | ContentQueryBuilderParams, ...pathParts: string[]) => import("../types/query").ContentQueryBuilder<T>;
|
|
29
25
|
export declare function serverQueryCollection<K extends keyof ContentCollectionMap & string>(event: H3Event, collection: K): CollectionQueryBuilder<ContentCollectionMap[K]>;
|