content-query 0.2.0 → 0.4.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/README.md +28 -3
- package/dist/{build-Dxz7P1ur.mjs → build-CcqIpkes.mjs} +763 -39
- package/dist/build-DL1GzmRy.d.mts +55 -0
- package/dist/build.d.mts +2 -2
- package/dist/build.mjs +1 -1
- package/dist/cli.mjs +14 -8
- package/dist/computed.d.mts +2 -2
- package/dist/{content-N1gYshjg.mjs → content-BXrgP7nL.mjs} +271 -81
- package/dist/{content-G69dPPuo.d.mts → content-CwTKqRs9.d.mts} +49 -24
- package/dist/{types-ChaNhj42.d.mts → descriptor-bcPa6XLk.d.mts} +26 -1
- package/dist/{diagnostics-Cu94mZhl.mjs → diagnostics-DmUZtrJ6.mjs} +3 -1
- package/dist/{errors-C2iuBM0G.mjs → errors-Bfd0R4_P.mjs} +16 -1
- package/dist/file-DSOcdFj0.mjs +81 -0
- package/dist/{glob-Bv0dpvCQ.mjs → glob-BXJuwy_p.mjs} +94 -6
- package/dist/index.d.mts +61 -17
- package/dist/index.mjs +1 -1
- package/dist/internal.d.mts +11 -4
- package/dist/internal.mjs +29 -5
- package/dist/loaders.d.mts +2 -3
- package/dist/loaders.mjs +2 -81
- package/dist/next.d.mts +1 -1
- package/dist/next.mjs +2 -2
- package/dist/{operators-UqWUhKQJ.mjs → operators-Cwy8Kx4o.mjs} +88 -2
- package/dist/query-style-eXENQJ0O.d.mts +22 -0
- package/dist/query.d.mts +25 -2
- package/dist/query.mjs +1 -1
- package/dist/{relational-types-DgK3rLuw.d.mts → relational-types-C8xJtLG5.d.mts} +113 -38
- package/dist/runtime.d.mts +3 -2
- package/dist/runtime.mjs +1 -1
- package/dist/types-DbFfF6JE.d.mts +181 -0
- package/dist/vite.d.mts +15 -3
- package/dist/vite.mjs +25 -2
- package/package.json +2 -2
- package/dist/build-DfKd2bpf.d.mts +0 -25
- package/dist/descriptor-D9Th5hzk.d.mts +0 -18
- package/dist/types-C-kdMblM.d.mts +0 -69
- package/dist/validation-D_XdE1pF.mjs +0 -84
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
import { n as ContentRenderResult } from "./types-Dh-Sydyw.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
type Scalar = string | number | bigint | boolean | Date;
|
|
6
|
-
type Element<Value> = NonNullable<Value> extends readonly (infer Item)[] ? NonNullable<Item> : NonNullable<Value>;
|
|
7
|
-
type Compatible<Left, Right> = NonNullable<Left> extends readonly unknown[] ? NonNullable<Right> extends readonly unknown[] ? false : ScalarCompatible<Left, Right> : ScalarCompatible<Left, Right>;
|
|
8
|
-
type ScalarCompatible<Left, Right> = [Element<Left> | Element<Right>] extends [Scalar] ? [Element<Left>] extends [never] ? true : [Element<Right>] extends [never] ? true : [Extract<Element<Left>, Element<Right>> | Extract<Element<Right>, Element<Left>>] extends [never] ? false : true : false;
|
|
9
|
-
type CheckRelation<Registry extends CollectionRegistry, Name extends keyof Registry, Link extends Relationship> = Link["collection"] extends keyof Registry ? Link["from"] extends keyof QueryData<Registry[Name]> ? Link["to"] extends keyof QueryData<Registry[Link["collection"]]> ? Compatible<QueryData<Registry[Name]>[Link["from"]], QueryData<Registry[Link["collection"]]>[Link["to"]]> extends true ? never : "incompatible-relationship-fields" : "unknown-target-field" : "unknown-source-field" : "unknown-target-collection";
|
|
10
|
-
/** Registry-level relationship checks require the complete inferred collection map. */
|
|
11
|
-
type InvalidRelationships<Registry extends CollectionRegistry> = { [Name in keyof Registry]: { [Link in keyof RelationshipsOf<Registry[Name]>]: RelationshipsOf<Registry[Name]>[Link] extends Relationship ? CheckRelation<Registry, Name, RelationshipsOf<Registry[Name]>[Link]> : "invalid-relationship"; }[keyof RelationshipsOf<Registry[Name]>]; }[keyof Registry];
|
|
12
|
-
//#endregion
|
|
13
|
-
//#region src/query/select.d.ts
|
|
14
|
-
/** A selection whose collection and selected result are inferred when from() is supplied. */
|
|
15
|
-
type SelectFrom<Registry extends CollectionRegistry, Keys extends readonly string[]> = {
|
|
16
|
-
/** Binds the collection and rejects selected keys that are absent from its prepared data type. */
|
|
17
|
-
from<Name extends keyof Registry & string>(collection: Name & (Exclude<Keys[number], keyof QueryData<Registry[NoInfer<Name>]>> extends never ? unknown : never)): Query<Registry, Name, Keys extends readonly [] ? QueryData<Registry[Name]> : { [Key in Keys[number]]-?: Key extends keyof QueryData<Registry[Name]> ? QueryData<Registry[Name]>[Key] : never; }, true>;
|
|
18
|
-
};
|
|
19
|
-
//#endregion
|
|
2
|
+
import { _ as RelationshipsOf, g as Relationship, h as QueryData, i as CollectionRegistry } from "./types-DbFfF6JE.mjs";
|
|
3
|
+
import { b as QueryRegistry, n as RelationalQueries, t as RelationalCountOptions, u as Query, y as QueryPlan } from "./relational-types-C8xJtLG5.mjs";
|
|
4
|
+
import { i as QueryStyleMember, n as QueryStyle, r as QueryStyleDisabled, t as MembersOf } from "./query-style-eXENQJ0O.mjs";
|
|
20
5
|
//#region src/shared/errors.d.ts
|
|
21
6
|
type ContentErrorCode = "variant-not-found" | "not-renderable" | "source-error" | "validation-error" | "duplicate-id" | "invalid-reference" | "invalid-query" | "artifact-error" | "render-error";
|
|
22
7
|
type ContentDiagnostic = {
|
|
@@ -27,6 +12,10 @@ type ContentDiagnostic = {
|
|
|
27
12
|
id?: string;
|
|
28
13
|
source?: string;
|
|
29
14
|
path?: readonly PropertyKey[];
|
|
15
|
+
/** The custom payload being resolved or loaded. */
|
|
16
|
+
payload?: string;
|
|
17
|
+
/** The payload's variant combination, with keys in sorted order. */
|
|
18
|
+
variant?: Readonly<Record<string, string>>;
|
|
30
19
|
issues?: readonly unknown[];
|
|
31
20
|
cause?: unknown;
|
|
32
21
|
};
|
|
@@ -40,6 +29,8 @@ declare class ContentError extends Error {
|
|
|
40
29
|
readonly id?: string;
|
|
41
30
|
readonly source?: string;
|
|
42
31
|
readonly path?: readonly PropertyKey[];
|
|
32
|
+
readonly payload?: string;
|
|
33
|
+
readonly variant?: Readonly<Record<string, string>>;
|
|
43
34
|
readonly issues?: readonly unknown[];
|
|
44
35
|
readonly diagnostics: readonly ContentDiagnostic[];
|
|
45
36
|
/** Creates one failure or a grouped report preserving individual causes and issues. */
|
|
@@ -48,10 +39,21 @@ declare class ContentError extends Error {
|
|
|
48
39
|
});
|
|
49
40
|
}
|
|
50
41
|
//#endregion
|
|
42
|
+
//#region src/collection/registry-types.d.ts
|
|
43
|
+
type Scalar = string | number | bigint | boolean | Date;
|
|
44
|
+
type Element<Value> = NonNullable<Value> extends readonly (infer Item)[] ? NonNullable<Item> : NonNullable<Value>;
|
|
45
|
+
type Compatible<Left, Right> = NonNullable<Left> extends readonly unknown[] ? NonNullable<Right> extends readonly unknown[] ? false : ScalarCompatible<Left, Right> : ScalarCompatible<Left, Right>;
|
|
46
|
+
type ScalarCompatible<Left, Right> = [Element<Left> | Element<Right>] extends [Scalar] ? [Element<Left>] extends [never] ? true : [Element<Right>] extends [never] ? true : [Extract<Element<Left>, Element<Right>> | Extract<Element<Right>, Element<Left>>] extends [never] ? false : true : false;
|
|
47
|
+
type CheckRelation<Registry extends CollectionRegistry, Name extends keyof Registry, Link extends Relationship> = Link["collection"] extends keyof Registry ? Link["from"] extends keyof QueryData<Registry[Name]> ? Link["to"] extends keyof QueryData<Registry[Link["collection"]]> ? Compatible<QueryData<Registry[Name]>[Link["from"]], QueryData<Registry[Link["collection"]]>[Link["to"]]> extends true ? never : "incompatible-relationship-fields" : "unknown-target-field" : "unknown-source-field" : "unknown-target-collection";
|
|
48
|
+
/** Registry-level relationship checks require the complete inferred collection map. */
|
|
49
|
+
type InvalidRelationships<Registry extends CollectionRegistry> = { [Name in keyof Registry]: { [Link in keyof RelationshipsOf<Registry[Name]>]: RelationshipsOf<Registry[Name]>[Link] extends Relationship ? CheckRelation<Registry, Name, RelationshipsOf<Registry[Name]>[Link]> : "invalid-relationship"; }[keyof RelationshipsOf<Registry[Name]>]; }[keyof Registry];
|
|
50
|
+
//#endregion
|
|
51
51
|
//#region src/runtime/revision.d.ts
|
|
52
52
|
type QueryRecord = Record<string, unknown> & {
|
|
53
53
|
id: string;
|
|
54
54
|
};
|
|
55
|
+
/** Custom payload loaders by payload name, entry ID, and canonical variant key. */
|
|
56
|
+
type CustomPayloadTable = ReadonlyMap<string, ReadonlyMap<string, ReadonlyMap<string, () => Promise<unknown>>>>;
|
|
55
57
|
/** The built-in side payload shared by an entry's `_body` and `_rendered` payloads. */
|
|
56
58
|
type BuiltinPayload = {
|
|
57
59
|
body?: string;
|
|
@@ -63,6 +65,11 @@ type PreparedCollection = {
|
|
|
63
65
|
relationships: Record<string, Relationship>;
|
|
64
66
|
/** Lazy built-in payloads, present only for entries with a body or rendered output. */
|
|
65
67
|
builtins: ReadonlyMap<string, () => Promise<BuiltinPayload>>;
|
|
68
|
+
/**
|
|
69
|
+
* Lazy custom payloads by payload name, entry ID, and canonical variant key. A missing variant
|
|
70
|
+
* key means the entry has no such combination.
|
|
71
|
+
*/
|
|
72
|
+
payloads?: CustomPayloadTable;
|
|
66
73
|
sources?: ReadonlyMap<string, string | undefined>;
|
|
67
74
|
};
|
|
68
75
|
type PreparedRevision = {
|
|
@@ -70,9 +77,12 @@ type PreparedRevision = {
|
|
|
70
77
|
collections: Record<string, PreparedCollection>;
|
|
71
78
|
relations: Map<string, Map<string, readonly QueryRecord[]>>;
|
|
72
79
|
active: number;
|
|
73
|
-
|
|
80
|
+
/** Built-in payloads keyed by collection and ID; custom payloads also by name and variant. */
|
|
81
|
+
payloadCache: Map<string, Promise<unknown>>;
|
|
74
82
|
renderCache: Map<string, Promise<ContentRenderResult>>;
|
|
75
83
|
renderMarkdown?: (body: string) => Promise<ContentRenderResult>;
|
|
84
|
+
/** The only query style this revision's configuration allows; absent allows both. */
|
|
85
|
+
queryStyle?: QueryStyle;
|
|
76
86
|
execute?: (plan: QueryPlan, terminal: "all" | "first" | "count", requests: PayloadRequest[]) => Promise<unknown>;
|
|
77
87
|
};
|
|
78
88
|
/** A projected row awaiting the payloads its query scope requested. */
|
|
@@ -90,20 +100,35 @@ type ContentState = {
|
|
|
90
100
|
//#endregion
|
|
91
101
|
//#region src/runtime/content.d.ts
|
|
92
102
|
type ContentMethods<Registry extends CollectionRegistry = {}> = {
|
|
93
|
-
/**
|
|
94
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Starts a fluent query over one collection. Nothing is selected until `select()`, `with()`,
|
|
105
|
+
* `withPayload()`, or `selectAdjacent()` requests data, not even `id`.
|
|
106
|
+
*/
|
|
107
|
+
from<Name extends keyof Registry & string>(collection: Name): Query<Registry, Name>;
|
|
95
108
|
/** Collection-scoped relational queries with typed columns, relationships, payloads, and filters. */
|
|
96
109
|
readonly query: RelationalQueries<Registry>;
|
|
97
110
|
/** Counts matching entries before pagination, like the fluent count terminal. */
|
|
98
111
|
count<Name extends keyof Registry & string>(collection: Name, options?: RelationalCountOptions<Registry, Name>): Promise<number>;
|
|
99
112
|
};
|
|
100
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Root members outside the allowed style. Property access reports the message type directly; a
|
|
115
|
+
* call reports it as the required `this` type, whatever arguments it passes.
|
|
116
|
+
*/
|
|
117
|
+
type DisabledMembers<Style extends QueryStyle> = { readonly [Member in Exclude<QueryStyleMember, MembersOf<Style>>]: ContentMethods[Member] extends ((...arguments_: never) => unknown) ? (this: QueryStyleDisabled<Member, Style>, ...arguments_: readonly unknown[]) => never : QueryStyleDisabled<Member, Style>; };
|
|
118
|
+
/**
|
|
119
|
+
* The generated `content` export. `Style` narrows the root query APIs to the `queryStyle` exported
|
|
120
|
+
* by content-query.config; the default allows both fluent and relational queries.
|
|
121
|
+
*
|
|
122
|
+
* The gate avoids a conditional on `Style`: a conditional on a generic `Style` would make
|
|
123
|
+
* `ContentSession<Registry>` invariant in `Registry` and break assignment to wider sessions.
|
|
124
|
+
*/
|
|
125
|
+
type Content<Registry extends CollectionRegistry = {}, Style extends QueryStyle = QueryStyle> = InvalidRelationships<Registry> extends never ? Pick<ContentMethods<Registry>, MembersOf<Style>> & DisabledMembers<Style> : {
|
|
101
126
|
readonly invalidRelationships: InvalidRelationships<Registry>;
|
|
102
127
|
};
|
|
103
128
|
/** Keeps dev builders live across host-delivered revisions while pinning active operations. */
|
|
104
129
|
declare function createLiveRuntime(initial: ContentState): {
|
|
105
|
-
content: ContentMethods<CollectionRegistry>;
|
|
130
|
+
content: Pick<ContentMethods<CollectionRegistry>, "from" | "query" | "count"> & DisabledMembers<QueryStyle>;
|
|
106
131
|
update(next: ContentState): void;
|
|
107
132
|
};
|
|
108
133
|
//#endregion
|
|
109
|
-
export {
|
|
134
|
+
export { ContentDiagnostic as a, InvalidRelationships as i, createLiveRuntime as n, ContentError as o, PreparedRevision as r, ContentErrorCode as s, Content as t };
|
|
@@ -5,6 +5,7 @@ type MaybePromise<Value> = Value | Promise<Value>;
|
|
|
5
5
|
//#region src/loaders/types.d.ts
|
|
6
6
|
declare const loaderSourceType: unique symbol;
|
|
7
7
|
declare const recordLoaderType: unique symbol;
|
|
8
|
+
declare const bodyLoaderType: unique symbol;
|
|
8
9
|
/** A stored content record, following Astro's build-time DataEntry contract. */
|
|
9
10
|
type DataEntry<Data extends Record<string, unknown> = Record<string, unknown>, Source = unknown> = {
|
|
10
11
|
id: string;
|
|
@@ -135,9 +136,33 @@ type RecordLoader<Source = unknown> = Loader<Source> & {
|
|
|
135
136
|
/** Type-only marker: entries never carry built-in `_body` or `_rendered` payloads. */
|
|
136
137
|
readonly [recordLoaderType]: true;
|
|
137
138
|
};
|
|
139
|
+
/**
|
|
140
|
+
* A loader whose entries carry raw bodies but never rendered output, such as a loader for a
|
|
141
|
+
* format that the host application compiles itself.
|
|
142
|
+
*/
|
|
143
|
+
type BodyLoader<Source = unknown> = Loader<Source> & {
|
|
144
|
+
/** Type-only marker: entries offer the built-in `_body` payload but never `_rendered`. */
|
|
145
|
+
readonly [bodyLoaderType]: true;
|
|
146
|
+
};
|
|
138
147
|
/** Infers the source metadata a typed loader supplies to computed resolvers. */
|
|
139
148
|
type LoaderSource<Value> = Value extends {
|
|
140
149
|
readonly [loaderSourceType]?: infer Source;
|
|
141
150
|
} ? Source : unknown;
|
|
142
151
|
//#endregion
|
|
143
|
-
|
|
152
|
+
//#region src/loaders/descriptor.d.ts
|
|
153
|
+
type GlobOptions = {
|
|
154
|
+
pattern: string | string[];
|
|
155
|
+
base?: string | URL;
|
|
156
|
+
generateId?: (context: {
|
|
157
|
+
entry: string;
|
|
158
|
+
base: URL;
|
|
159
|
+
data: Record<string, unknown>;
|
|
160
|
+
}) => string;
|
|
161
|
+
retainBody?: boolean;
|
|
162
|
+
deferRender?: boolean;
|
|
163
|
+
};
|
|
164
|
+
type FileOptions = {
|
|
165
|
+
parser?: (text: string) => MaybePromise<unknown>;
|
|
166
|
+
};
|
|
167
|
+
//#endregion
|
|
168
|
+
export { DataStore as a, Loader as c, LoaderLogger as d, LoaderSource as f, MaybePromise as g, RecordLoader as h, DataEntry as i, LoaderConfig as l, MetaStore as m, GlobOptions as n, FileEntrySource as o, LoaderWatcher as p, BodyLoader as r, FileSource as s, FileOptions as t, LoaderContext as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ContentError } from "./errors-
|
|
1
|
+
import { t as ContentError } from "./errors-Bfd0R4_P.mjs";
|
|
2
2
|
import { o as encode, r as decode } from "./values-BbTV4QT-.mjs";
|
|
3
3
|
//#region src/runtime/diagnostics.ts
|
|
4
4
|
/** Transports Error nodes as records while preserving the supported diagnostic value graph. */
|
|
@@ -59,6 +59,8 @@ function serializeContentError(error) {
|
|
|
59
59
|
id: error.id,
|
|
60
60
|
source: error.source,
|
|
61
61
|
path: error.path,
|
|
62
|
+
payload: error.payload,
|
|
63
|
+
variant: error.variant,
|
|
62
64
|
issues: error.issues,
|
|
63
65
|
cause: error.cause,
|
|
64
66
|
diagnostics: error.diagnostics
|
|
@@ -12,6 +12,8 @@ var ContentError = class extends Error {
|
|
|
12
12
|
id;
|
|
13
13
|
source;
|
|
14
14
|
path;
|
|
15
|
+
payload;
|
|
16
|
+
variant;
|
|
15
17
|
issues;
|
|
16
18
|
diagnostics;
|
|
17
19
|
/** Creates one failure or a grouped report preserving individual causes and issues. */
|
|
@@ -25,10 +27,23 @@ var ContentError = class extends Error {
|
|
|
25
27
|
this.id = options.id;
|
|
26
28
|
this.source = options.source;
|
|
27
29
|
this.path = options.path;
|
|
30
|
+
this.payload = options.payload;
|
|
31
|
+
this.variant = options.variant;
|
|
28
32
|
this.issues = options.issues;
|
|
29
33
|
this.diagnostics = options.diagnostics ?? [{ ...options }];
|
|
30
34
|
}
|
|
31
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Formats a payload and its variant as a readable identity, such as `detail[locale=en-US]`.
|
|
38
|
+
*
|
|
39
|
+
* @param payload - The payload name.
|
|
40
|
+
* @param variant - The variant combination; keys are listed in sorted order.
|
|
41
|
+
* @returns The payload name, followed by its variant pairs when it has any.
|
|
42
|
+
*/
|
|
43
|
+
function payloadIdentity(payload, variant = {}) {
|
|
44
|
+
const pairs = Object.keys(variant).sort().map((key) => `${key}=${variant[key]}`);
|
|
45
|
+
return pairs.length ? `${payload}[${pairs.join(",")}]` : payload;
|
|
46
|
+
}
|
|
32
47
|
/** Rejects invalid query structure before any execution or payload access. */
|
|
33
48
|
function invalidQuery(message) {
|
|
34
49
|
throw new ContentError({
|
|
@@ -69,4 +84,4 @@ function withContext(cause, context) {
|
|
|
69
84
|
})));
|
|
70
85
|
}
|
|
71
86
|
//#endregion
|
|
72
|
-
export { invalidQuery as a, groupDiagnostics as i, contentError as n,
|
|
87
|
+
export { invalidQuery as a, groupDiagnostics as i, contentError as n, payloadIdentity as o, describeCause as r, withContext as s, ContentError as t };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { a as recordData, f as builtinPath, i as parseData, o as populateStore, p as builtinSymbol, r as coerceIdentity } from "./glob-BXJuwy_p.mjs";
|
|
2
|
+
import { i as groupDiagnostics, n as contentError, r as describeCause, t as ContentError } from "./errors-Bfd0R4_P.mjs";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
//#region src/loaders/file.ts
|
|
7
|
+
/** Declares a multi-entry data file with typed source paths and record keys, plus an optional parser. */
|
|
8
|
+
function file(filename, options = {}) {
|
|
9
|
+
if (typeof filename !== "string" || !filename) throw new TypeError("file() requires a filename.");
|
|
10
|
+
const descriptor = {
|
|
11
|
+
kind: "file",
|
|
12
|
+
filename,
|
|
13
|
+
options
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
[builtinSymbol]: descriptor,
|
|
17
|
+
name: "content-query/file",
|
|
18
|
+
async load(context) {
|
|
19
|
+
const entries = await loadFile(descriptor, fileURLToPath(context.config.root), context.signal ?? new AbortController().signal);
|
|
20
|
+
await populateStore(context, entries);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Captures a complete multi-entry data source without applying collection validation. */
|
|
25
|
+
async function loadFile(descriptor, root, signal) {
|
|
26
|
+
const resolved = builtinPath(descriptor, root);
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
const text = await readFile(resolved, {
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
signal
|
|
32
|
+
});
|
|
33
|
+
parsed = descriptor.options.parser ? await descriptor.options.parser(text) : parseData(text, resolved);
|
|
34
|
+
} catch (cause) {
|
|
35
|
+
signal.throwIfAborted();
|
|
36
|
+
throw contentError(cause, {
|
|
37
|
+
code: "source-error",
|
|
38
|
+
source: resolved,
|
|
39
|
+
message: `Could not load "${descriptor.filename}": ${describeCause(cause)}`,
|
|
40
|
+
cause
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const array = Array.isArray(parsed);
|
|
44
|
+
if (!array && (!parsed || typeof parsed !== "object")) throw new ContentError({
|
|
45
|
+
code: "source-error",
|
|
46
|
+
source: resolved,
|
|
47
|
+
message: `"${descriptor.filename}" must parse to an array or keyed record.`
|
|
48
|
+
});
|
|
49
|
+
const diagnostics = [];
|
|
50
|
+
const entries = Object.entries(parsed).flatMap(([key, value]) => {
|
|
51
|
+
if (!array && key === "$schema" && typeof value === "string") return [];
|
|
52
|
+
const source = `${resolved}#${key}`;
|
|
53
|
+
try {
|
|
54
|
+
const data = recordData(value);
|
|
55
|
+
const identity = array ? data.id ?? data.slug : key;
|
|
56
|
+
if (identity == null || coerceIdentity(identity) === "") throw new Error("Array entries require a nonempty id or slug.");
|
|
57
|
+
const { id: _transportId, ...metadata } = data;
|
|
58
|
+
return [{
|
|
59
|
+
id: coerceIdentity(identity),
|
|
60
|
+
data: metadata,
|
|
61
|
+
source: array ? source : `${resolved}#${coerceIdentity(identity)}`,
|
|
62
|
+
sourceData: {
|
|
63
|
+
filePath: path.relative(root, resolved).split(path.sep).join("/"),
|
|
64
|
+
key
|
|
65
|
+
}
|
|
66
|
+
}];
|
|
67
|
+
} catch (cause) {
|
|
68
|
+
diagnostics.push({
|
|
69
|
+
code: "source-error",
|
|
70
|
+
source,
|
|
71
|
+
message: `Invalid entry "${key}" in "${descriptor.filename}": ${describeCause(cause)}`,
|
|
72
|
+
cause
|
|
73
|
+
});
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
if (diagnostics.length) throw groupDiagnostics(diagnostics);
|
|
78
|
+
return entries;
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
export { loadFile as n, file as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { i as
|
|
1
|
+
import { i as groupDiagnostics, n as contentError, r as describeCause, t as ContentError } from "./errors-Bfd0R4_P.mjs";
|
|
2
|
+
import { i as detach } from "./values-BbTV4QT-.mjs";
|
|
3
3
|
import { n as slug } from "./github-slugger-BMgR_Q0I.mjs";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import path from "node:path";
|
|
@@ -8,6 +8,85 @@ import { glob } from "tinyglobby";
|
|
|
8
8
|
import matter from "gray-matter";
|
|
9
9
|
import { parse } from "yaml";
|
|
10
10
|
import { parse as parse$1 } from "smol-toml";
|
|
11
|
+
//#region src/loaders/descriptor.ts
|
|
12
|
+
const builtinSymbol = Symbol.for("content-query.builtin-loader");
|
|
13
|
+
/** Finds library-owned loader settings without depending on module instance identity. */
|
|
14
|
+
function builtinLoader(loader) {
|
|
15
|
+
return loader[builtinSymbol];
|
|
16
|
+
}
|
|
17
|
+
/** Resolves a loader's watch root from the application root, including file URLs. */
|
|
18
|
+
function builtinPath(descriptor, root) {
|
|
19
|
+
if (descriptor.kind === "file") return path.resolve(root, descriptor.filename);
|
|
20
|
+
return descriptor.options.base instanceof URL ? path.resolve(fileURLToPath(descriptor.options.base)) : path.resolve(root, descriptor.options.base ?? ".");
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/preparation/validation.ts
|
|
24
|
+
/** Checks records independently from validation-provider schema introspection. */
|
|
25
|
+
function isRecord(value) {
|
|
26
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
27
|
+
}
|
|
28
|
+
/** Validates one result, retaining structured provider issues and their original detail. */
|
|
29
|
+
async function validate(schema, value, context) {
|
|
30
|
+
if (!schema) return value;
|
|
31
|
+
try {
|
|
32
|
+
const result = await schema["~standard"].validate(value);
|
|
33
|
+
if (result.issues) {
|
|
34
|
+
const firstPath = result.issues[0]?.path?.map((segment) => typeof segment === "object" ? segment.key : segment);
|
|
35
|
+
throw new ContentError({
|
|
36
|
+
...context,
|
|
37
|
+
code: "validation-error",
|
|
38
|
+
message: result.issues.map((issue) => issue.message).join("; "),
|
|
39
|
+
issues: result.issues,
|
|
40
|
+
path: [...context.path ?? [], ...firstPath ?? []]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return result.value;
|
|
44
|
+
} catch (cause) {
|
|
45
|
+
throw contentError(cause, {
|
|
46
|
+
...context,
|
|
47
|
+
code: "validation-error",
|
|
48
|
+
message: "Schema validation failed."
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Checks loader transport structure and rejects duplicate snapshot/upsert identities. */
|
|
53
|
+
function normalizeSnapshot(entries, collection) {
|
|
54
|
+
if (!Array.isArray(entries)) throw new ContentError({
|
|
55
|
+
code: "source-error",
|
|
56
|
+
collection,
|
|
57
|
+
message: "load() must return an array of structured entries."
|
|
58
|
+
});
|
|
59
|
+
const snapshot = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const entry of entries) {
|
|
61
|
+
if (!entry || typeof entry.id !== "string" || !entry.id || !isRecord(entry.data) || entry.body !== void 0 && typeof entry.body !== "string" || entry.source !== void 0 && typeof entry.source !== "string") throw new ContentError({
|
|
62
|
+
code: "source-error",
|
|
63
|
+
collection,
|
|
64
|
+
id: entry && typeof entry === "object" && typeof entry.id === "string" ? entry.id : void 0,
|
|
65
|
+
source: entry && typeof entry === "object" && typeof entry.source === "string" ? entry.source : void 0,
|
|
66
|
+
message: "Invalid structured loader entry."
|
|
67
|
+
});
|
|
68
|
+
if (snapshot.has(entry.id)) throw new ContentError({
|
|
69
|
+
code: "duplicate-id",
|
|
70
|
+
collection,
|
|
71
|
+
id: entry.id,
|
|
72
|
+
source: entry.source,
|
|
73
|
+
message: `Duplicate entry ID "${entry.id}".`
|
|
74
|
+
});
|
|
75
|
+
snapshot.set(entry.id, entry);
|
|
76
|
+
}
|
|
77
|
+
return snapshot;
|
|
78
|
+
}
|
|
79
|
+
/** Validates supplied rendering data and normalizes omitted headings. */
|
|
80
|
+
function renderedPayload(entry) {
|
|
81
|
+
if (entry.rendered === void 0) return;
|
|
82
|
+
const rendered = entry.rendered;
|
|
83
|
+
if (!rendered || typeof rendered.html !== "string" || rendered.metadata !== void 0 && (!isRecord(rendered.metadata) || rendered.metadata.headings !== void 0 && (!Array.isArray(rendered.metadata.headings) || rendered.metadata.headings.some((heading) => !heading || !Number.isInteger(heading.depth) || heading.depth < 1 || heading.depth > 6 || typeof heading.slug !== "string" || typeof heading.text !== "string")))) throw new Error("Invalid supplied HTML/headings payload.");
|
|
84
|
+
return {
|
|
85
|
+
html: rendered.html,
|
|
86
|
+
headings: detach(rendered.metadata?.headings ?? [])
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
11
90
|
//#region src/loaders/populate.ts
|
|
12
91
|
/** Validates a complete built-in source before replacing its collection store. */
|
|
13
92
|
async function populateStore(context, entries) {
|
|
@@ -67,15 +146,24 @@ function glob$1(options) {
|
|
|
67
146
|
}
|
|
68
147
|
};
|
|
69
148
|
}
|
|
70
|
-
/**
|
|
71
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Captures complete matching Markdown and data sources before deployment.
|
|
151
|
+
*
|
|
152
|
+
* @param descriptor - The glob loader's options.
|
|
153
|
+
* @param root - The project root that relative bases and source paths use.
|
|
154
|
+
* @param signal - Cancels outstanding reads.
|
|
155
|
+
* @param options - `warnEmpty: false` skips the warning when nothing matches, for callers where an
|
|
156
|
+
* empty result is expected, such as resolvers' `files.glob()`.
|
|
157
|
+
* @returns Loader entries in sorted path order.
|
|
158
|
+
*/
|
|
159
|
+
async function loadGlob(descriptor, root, signal, { warnEmpty = true } = {}) {
|
|
72
160
|
const resolved = builtinPath(descriptor, root);
|
|
73
161
|
const entries = await glob(descriptor.options.pattern, {
|
|
74
162
|
cwd: resolved,
|
|
75
163
|
onlyFiles: true,
|
|
76
164
|
dot: false
|
|
77
165
|
});
|
|
78
|
-
if (entries.length === 0) console.warn(`[content-query] No content matched ${JSON.stringify(descriptor.options.pattern)} in ${resolved}.`);
|
|
166
|
+
if (entries.length === 0 && warnEmpty) console.warn(`[content-query] No content matched ${JSON.stringify(descriptor.options.pattern)} in ${resolved}.`);
|
|
79
167
|
const base = pathToFileURL(`${resolved}${path.sep}`);
|
|
80
168
|
entries.sort();
|
|
81
169
|
const results = [];
|
|
@@ -156,4 +244,4 @@ async function loadEntry(descriptor, entry, filename, base, signal) {
|
|
|
156
244
|
};
|
|
157
245
|
}
|
|
158
246
|
//#endregion
|
|
159
|
-
export {
|
|
247
|
+
export { recordData as a, normalizeSnapshot as c, builtinLoader as d, builtinPath as f, parseData as i, renderedPayload as l, loadGlob as n, populateStore as o, builtinSymbol as p, coerceIdentity as r, isRecord as s, glob$1 as t, validate as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as DataStore, c as Loader, d as LoaderLogger, f as LoaderSource, g as MaybePromise, h as RecordLoader, i as DataEntry, l as LoaderConfig, m as MetaStore, n as GlobOptions, o as FileEntrySource, p as LoaderWatcher, r as BodyLoader, s as FileSource, u as LoaderContext } from "./descriptor-bcPa6XLk.mjs";
|
|
2
2
|
import { n as ContentRenderResult, r as RenderedContent, t as ContentHeading } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { a as ComputedContext, c as
|
|
4
|
-
import { n as
|
|
3
|
+
import { C as VariantValues, S as VariantOf, a as ComputedContext, b as VariantContext, c as EntryFiles, d as PayloadData, f as PayloadDeclaration, g as Relationship, h as QueryData, i as CollectionRegistry, l as FileEntry, m as PayloadsOf, n as BuiltinPayloads, o as CustomPayload, p as PayloadDefinition, r as CollectionDefinition, s as CustomPayloadMarker, t as BuiltinPayloadMarker, u as PayloadContext, v as Schema, x as VariantField, y as SchemaOutput } from "./types-DbFfF6JE.mjs";
|
|
4
|
+
import { n as QueryStyle } from "./query-style-eXENQJ0O.mjs";
|
|
5
5
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
6
|
//#region src/collection/source.d.ts
|
|
7
7
|
type CollectionSource = string | ({
|
|
@@ -15,7 +15,35 @@ type CollectionSource = string | ({
|
|
|
15
15
|
type RecordSource = Extract<CollectionSource, object> & {
|
|
16
16
|
type: "json" | "yaml" | "toml";
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
/** Variant values are typed `string`, so inference never depends on declaration order. */
|
|
19
|
+
type VariantRecord<Keys> = { [Key in keyof Keys]: string; };
|
|
20
|
+
/** Metadata plus computed fields, as payload enumerators and resolvers receive them. */
|
|
21
|
+
type PayloadData$1<SourceSchema extends Schema | undefined, ComputedSchemas extends Record<string, Schema>> = SchemaOutput<NoInfer<SourceSchema>> & { [Field in keyof NoInfer<ComputedSchemas>]: SchemaOutput<NoInfer<ComputedSchemas>[Field]>; };
|
|
22
|
+
/**
|
|
23
|
+
* Custom payload declarations. Schemas and variant keys are inferred through separate mapped
|
|
24
|
+
* types, so resolvers are contextually typed without annotations. Variant values are data field
|
|
25
|
+
* names or fixed lists rather than callbacks: TypeScript cannot infer keys from an object whose
|
|
26
|
+
* values are all unannotated callbacks.
|
|
27
|
+
*/
|
|
28
|
+
type PayloadDeclarations<SourceSchema extends Schema | undefined, ComputedSchemas extends Record<string, Schema>, PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>, Source> = { [Name in keyof PayloadSchemas]: {
|
|
29
|
+
schema: PayloadSchemas[Name];
|
|
30
|
+
}; } & { [Name in keyof PayloadVariants]: {
|
|
31
|
+
variants?: { [Key in keyof PayloadVariants[Name]]: VariantValues<PayloadData$1<SourceSchema, ComputedSchemas>>; };
|
|
32
|
+
combinations?(context: VariantContext<PayloadData$1<SourceSchema, ComputedSchemas>, Source> & {
|
|
33
|
+
variants: Readonly<{ [Key in keyof NoInfer<PayloadVariants>[Name]]: readonly string[]; }>;
|
|
34
|
+
}): Iterable<VariantRecord<NoInfer<PayloadVariants>[Name]>> | PromiseLike<Iterable<VariantRecord<NoInfer<PayloadVariants>[Name]>>>;
|
|
35
|
+
resolve(context: PayloadContext<PayloadData$1<SourceSchema, ComputedSchemas>, Source, VariantRecord<NoInfer<PayloadVariants>[Name]>>): unknown;
|
|
36
|
+
/** Set to `false` to resolve again in every revision. */
|
|
37
|
+
cache?: boolean;
|
|
38
|
+
}; } & ReservedPayloadNames<NoInfer<PayloadSchemas>>;
|
|
39
|
+
/**
|
|
40
|
+
* Rejects underscore payload names, which built-ins own. A conditional keeps declaration inference
|
|
41
|
+
* intact, unlike a key-remapped mapped type.
|
|
42
|
+
*/
|
|
43
|
+
type ReservedPayloadNames<PayloadSchemas> = Extract<keyof PayloadSchemas, `_${string}`> extends never ? unknown : {
|
|
44
|
+
"Custom payload names cannot start with an underscore": Extract<keyof PayloadSchemas, `_${string}`>;
|
|
45
|
+
};
|
|
46
|
+
type CollectionFields<SourceSchema extends Schema | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>, Source> = {
|
|
19
47
|
schema?: SourceSchema;
|
|
20
48
|
computed?: { [Name in keyof ComputedSchemas]: {
|
|
21
49
|
schema: ComputedSchemas[Name];
|
|
@@ -26,16 +54,22 @@ type CollectionFields<SourceSchema extends Schema | undefined, ComputedSchemas e
|
|
|
26
54
|
id: string;
|
|
27
55
|
} & { [Field in keyof ComputedSchemas]: SchemaOutput<ComputedSchemas[Field]>; }) & string;
|
|
28
56
|
}; };
|
|
57
|
+
/** Directories, relative to the project root, that resolvers' `files` helpers may also read. */
|
|
58
|
+
sharedFiles?: readonly string[];
|
|
59
|
+
/** Named per-entry data resolved during preparation and loaded only when a query requests it. */
|
|
60
|
+
payloads?: PayloadDeclarations<SourceSchema, ComputedSchemas, PayloadSchemas, PayloadVariants, Source>;
|
|
29
61
|
};
|
|
30
|
-
type Definition<SourceSchema extends Schema | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, ContentLoader extends Loader> = ({
|
|
62
|
+
type Definition<SourceSchema extends Schema | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>, ContentLoader extends Loader> = ({
|
|
31
63
|
source: CollectionSource;
|
|
32
64
|
loader?: never;
|
|
33
|
-
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, FileSource>) | ({
|
|
65
|
+
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, FileSource>) | ({
|
|
34
66
|
loader: ContentLoader;
|
|
35
67
|
source?: never;
|
|
36
|
-
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, LoaderSource<NoInfer<ContentLoader>>>);
|
|
68
|
+
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, LoaderSource<NoInfer<ContentLoader>>>);
|
|
69
|
+
/** Records each declared payload's validated value type and variant record. */
|
|
70
|
+
type PayloadMarker<PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>> = CustomPayloadMarker<{ [Name in keyof PayloadSchemas & string]: CustomPayload<SchemaOutput<PayloadSchemas[Name]>, VariantRecord<PayloadVariants[Name & keyof PayloadVariants]>>; }>;
|
|
37
71
|
/** Normalizes either declaration form into a definition with a native loader. */
|
|
38
|
-
declare function collectionOf<SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, ContentLoader extends Loader>(definition: Definition<SourceSchema, ComputedSchemas, Relationships, ContentLoader>): {
|
|
72
|
+
declare function collectionOf<SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>, ContentLoader extends Loader>(definition: Definition<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader>): {
|
|
39
73
|
loader: ContentLoader | Loader<FileSource>;
|
|
40
74
|
schema: SourceSchema;
|
|
41
75
|
computed: { [Name in keyof ComputedSchemas]: {
|
|
@@ -47,6 +81,10 @@ declare function collectionOf<SourceSchema extends StandardSchemaV1<unknown, Rec
|
|
|
47
81
|
}; };
|
|
48
82
|
relationships: Relationships;
|
|
49
83
|
source: CollectionSource;
|
|
84
|
+
/** Directories, relative to the project root, that resolvers' `files` helpers may also read. */
|
|
85
|
+
sharedFiles?: readonly string[];
|
|
86
|
+
/** Named per-entry data resolved during preparation and loaded only when a query requests it. */
|
|
87
|
+
payloads?: PayloadDeclarations<SourceSchema, ComputedSchemas, PayloadSchemas, PayloadVariants, FileSource> | undefined;
|
|
50
88
|
} | {
|
|
51
89
|
loader: ContentLoader | Loader<FileSource>;
|
|
52
90
|
schema: SourceSchema;
|
|
@@ -59,20 +97,26 @@ declare function collectionOf<SourceSchema extends StandardSchemaV1<unknown, Rec
|
|
|
59
97
|
}; };
|
|
60
98
|
relationships: Relationships;
|
|
61
99
|
source?: never;
|
|
100
|
+
/** Directories, relative to the project root, that resolvers' `files` helpers may also read. */
|
|
101
|
+
sharedFiles?: readonly string[];
|
|
102
|
+
/** Named per-entry data resolved during preparation and loaded only when a query requests it. */
|
|
103
|
+
payloads?: PayloadDeclarations<SourceSchema, ComputedSchemas, PayloadSchemas, PayloadVariants, LoaderSource<NoInfer<ContentLoader>>> | undefined;
|
|
62
104
|
};
|
|
63
|
-
type Defined<SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, ContentLoader extends Loader> = ReturnType<typeof collectionOf<SourceSchema, ComputedSchemas, Relationships, ContentLoader
|
|
105
|
+
type Defined<SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined, ComputedSchemas extends Record<string, Schema>, Relationships extends Record<string, Relationship>, PayloadSchemas extends Record<string, Schema>, PayloadVariants extends Record<string, unknown>, ContentLoader extends Loader> = ReturnType<typeof collectionOf<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader>> & PayloadMarker<PayloadSchemas, PayloadVariants>;
|
|
64
106
|
/**
|
|
65
|
-
* Declares fields with inferred schema data and optional loader source metadata, plus
|
|
66
|
-
* JSON, YAML, and TOML sources carry no built-in `_body` or
|
|
107
|
+
* Declares fields with inferred schema data and optional loader source metadata, plus
|
|
108
|
+
* relationships and custom payloads. JSON, YAML, and TOML sources carry no built-in `_body` or
|
|
109
|
+
* `_rendered` payloads.
|
|
67
110
|
*/
|
|
68
|
-
export declare function defineCollection<const SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined, const ComputedSchemas extends Record<string, Schema> = {}, const Relationships extends Record<string, Relationship> = {}>(definition: {
|
|
111
|
+
export declare function defineCollection<const SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined, const ComputedSchemas extends Record<string, Schema> = {}, const Relationships extends Record<string, Relationship> = {}, const PayloadSchemas extends Record<string, Schema> = {}, const PayloadVariants extends Record<string, unknown> = {}>(definition: {
|
|
69
112
|
source: RecordSource;
|
|
70
113
|
loader?: never;
|
|
71
|
-
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, FileSource>): Defined<SourceSchema, ComputedSchemas, Relationships, Loader> & BuiltinPayloadMarker<
|
|
114
|
+
} & CollectionFields<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, FileSource>): Defined<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, Loader> & BuiltinPayloadMarker<never>;
|
|
72
115
|
/**
|
|
73
|
-
* Declares fields with inferred schema data and optional loader source metadata, plus
|
|
74
|
-
* Record loaders such as `file()` carry no built-in `_body` or
|
|
116
|
+
* Declares fields with inferred schema data and optional loader source metadata, plus
|
|
117
|
+
* relationships and custom payloads. Record loaders such as `file()` carry no built-in `_body` or
|
|
118
|
+
* `_rendered` payloads, and body loaders carry `_body` without `_rendered`.
|
|
75
119
|
*/
|
|
76
|
-
export declare function defineCollection<const SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined, const ComputedSchemas extends Record<string, Schema> = {}, const Relationships extends Record<string, Relationship> = {}, const ContentLoader extends Loader = Loader>(definition: Definition<SourceSchema, ComputedSchemas, Relationships, ContentLoader>): Defined<SourceSchema, ComputedSchemas, Relationships, ContentLoader> & BuiltinPayloadMarker<[ContentLoader] extends [RecordLoader] ?
|
|
120
|
+
export declare function defineCollection<const SourceSchema extends StandardSchemaV1<unknown, Record<string, unknown>> | undefined = undefined, const ComputedSchemas extends Record<string, Schema> = {}, const Relationships extends Record<string, Relationship> = {}, const PayloadSchemas extends Record<string, Schema> = {}, const PayloadVariants extends Record<string, unknown> = {}, const ContentLoader extends Loader = Loader>(definition: Definition<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader>): Defined<SourceSchema, ComputedSchemas, Relationships, PayloadSchemas, PayloadVariants, ContentLoader> & BuiltinPayloadMarker<[ContentLoader] extends [RecordLoader] ? never : [ContentLoader] extends [BodyLoader] ? "_body" : keyof BuiltinPayloads>;
|
|
77
121
|
//#endregion
|
|
78
|
-
export type { BuiltinPayloads, CollectionDefinition, CollectionRegistry, CollectionSource, ComputedContext, ContentHeading, ContentRenderResult, DataEntry, DataStore, FileEntrySource, FileSource, Loader, LoaderConfig, LoaderContext, LoaderLogger, LoaderSource, LoaderWatcher, MaybePromise, MetaStore, PayloadsOf, QueryData, RecordLoader, Relationship, RenderedContent };
|
|
122
|
+
export type { BodyLoader, BuiltinPayloads, CollectionDefinition, CollectionRegistry, CollectionSource, ComputedContext, ContentHeading, ContentRenderResult, DataEntry, DataStore, EntryFiles, FileEntry, FileEntrySource, FileSource, Loader, LoaderConfig, LoaderContext, LoaderLogger, LoaderSource, LoaderWatcher, MaybePromise, MetaStore, PayloadContext, PayloadData, PayloadDeclaration, PayloadDefinition, PayloadsOf, QueryData, QueryStyle, RecordLoader, Relationship, RenderedContent, VariantContext, VariantField, VariantOf, VariantValues };
|
package/dist/index.mjs
CHANGED
package/dist/internal.d.mts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { n as createLiveRuntime, o as ContentError, r as PreparedRevision, t as Content } from "./content-CwTKqRs9.mjs";
|
|
1
2
|
import { n as ContentRenderResult } from "./types-Dh-Sydyw.mjs";
|
|
2
|
-
import { i as CollectionRegistry } from "./types-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { i as CollectionRegistry } from "./types-DbFfF6JE.mjs";
|
|
4
|
+
import { b as QueryRegistry } from "./relational-types-C8xJtLG5.mjs";
|
|
5
|
+
import { n as QueryStyle } from "./query-style-eXENQJ0O.mjs";
|
|
5
6
|
//#region src/artifacts/types.d.ts
|
|
6
7
|
type ArtifactManifest = {
|
|
7
8
|
version: number;
|
|
8
9
|
codec: string;
|
|
9
10
|
collections: QueryRegistry;
|
|
11
|
+
/** Optional and additive, so it needs no version bump; absent allows both query styles. */
|
|
12
|
+
queryStyle?: QueryStyle;
|
|
10
13
|
};
|
|
11
14
|
type EncodedCollection = {
|
|
12
15
|
records: readonly string[];
|
|
@@ -14,13 +17,17 @@ type EncodedCollection = {
|
|
|
14
17
|
builtins: Record<string, () => Promise<{
|
|
15
18
|
default: string;
|
|
16
19
|
}>>;
|
|
20
|
+
/** Lazy encoded custom payloads by payload name, entry ID, and canonical variant key. */
|
|
21
|
+
payloads?: Record<string, Record<string, Record<string, () => Promise<{
|
|
22
|
+
default: string;
|
|
23
|
+
}>>>>;
|
|
17
24
|
};
|
|
18
25
|
//#endregion
|
|
19
26
|
//#region src/artifacts/runtime.d.ts
|
|
20
27
|
/** Initializes generated/embedded prepared content. This versioned wiring is internal. */
|
|
21
28
|
export declare function createArtifactRevision(manifest: ArtifactManifest, collections: Record<string, EncodedCollection>, renderMarkdown?: (body: string) => Promise<ContentRenderResult>): PreparedRevision;
|
|
22
29
|
/** Initializes the public generated server export from a complete immutable artifact revision. */
|
|
23
|
-
export declare function createArtifactRuntime<Registry extends CollectionRegistry>(manifest: ArtifactManifest, collections: Record<string, EncodedCollection>, renderMarkdown?: (body: string) => Promise<ContentRenderResult>): Content<Registry>;
|
|
30
|
+
export declare function createArtifactRuntime<Registry extends CollectionRegistry>(manifest: ArtifactManifest, collections: Record<string, EncodedCollection>, renderMarkdown?: (body: string) => Promise<ContentRenderResult>): Content<Registry, QueryStyle>;
|
|
24
31
|
//#endregion
|
|
25
32
|
//#region src/artifacts/payloads.d.ts
|
|
26
33
|
/**
|