content-query 0.3.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 +21 -1
- package/dist/{build-CI4s0oFP.mjs → build-CcqIpkes.mjs} +709 -39
- package/dist/{build-jKnjDjQE.d.mts → build-DL1GzmRy.d.mts} +12 -5
- package/dist/build.d.mts +1 -1
- 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-lwPxE9Yu.d.mts → content-CwTKqRs9.d.mts} +39 -14
- package/dist/{types-FmUJ3cH1.d.mts → descriptor-bcPa6XLk.d.mts} +17 -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 -18
- package/dist/index.mjs +1 -1
- package/dist/internal.d.mts +11 -4
- package/dist/internal.mjs +29 -5
- package/dist/loaders.d.mts +1 -2
- 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-B45zM34W.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 +1 -1
- package/dist/vite.mjs +2 -2
- package/package.json +1 -1
- package/dist/descriptor-BUPT2J7X.d.mts +0 -18
- package/dist/types-BC8gVJ6u.d.mts +0 -69
- package/dist/validation-D_XdE1pF.mjs +0 -84
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { c as Loader, n as GlobOptions, t as FileOptions } from "./descriptor-bcPa6XLk.mjs";
|
|
2
|
+
import { n as ContentRenderResult, r as RenderedContent } from "./types-Dh-Sydyw.mjs";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
//#region src/collection/types.d.ts
|
|
5
|
+
declare const builtinPayloadsType: unique symbol;
|
|
6
|
+
declare const customPayloadsType: unique symbol;
|
|
7
|
+
type Schema = StandardSchemaV1;
|
|
8
|
+
type SchemaOutput<Value> = Value extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Value> : Record<string, unknown>;
|
|
9
|
+
/** One file or record that a `files` helper read, shaped like a loader entry. */
|
|
10
|
+
type FileEntry<Data = Record<string, unknown>> = {
|
|
11
|
+
id: string;
|
|
12
|
+
data: Data;
|
|
13
|
+
/** The Markdown body, when the file is Markdown and `retainBody` is not `false`. */
|
|
14
|
+
body?: string;
|
|
15
|
+
/** The file's path relative to the project root. */
|
|
16
|
+
filePath: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Tracked file access for computed and payload resolvers. Paths are relative to the entry's
|
|
20
|
+
* folder and must stay inside it or one of the collection's `sharedFiles` directories. Every read
|
|
21
|
+
* is recorded, so editing, adding, or removing a file re-resolves only what read it.
|
|
22
|
+
*/
|
|
23
|
+
type EntryFiles = {
|
|
24
|
+
/** Lists and parses files like `glob()`, with `base` relative to the entry's folder. */
|
|
25
|
+
glob<FileSchema extends Schema | undefined = undefined>(options: Omit<GlobOptions, "base" | "deferRender"> & {
|
|
26
|
+
base?: string;
|
|
27
|
+
schema?: FileSchema;
|
|
28
|
+
}): Promise<FileEntry<SchemaOutput<FileSchema>>[]>;
|
|
29
|
+
/** Parses one data file's records like `file()`, returning one entry per record. */
|
|
30
|
+
file<FileSchema extends Schema | undefined = undefined>(filePath: string, options?: FileOptions & {
|
|
31
|
+
schema?: FileSchema;
|
|
32
|
+
}): Promise<FileEntry<SchemaOutput<FileSchema>>[]>;
|
|
33
|
+
/** Reads a file as UTF-8 text. */
|
|
34
|
+
text(filePath: string): Promise<string>;
|
|
35
|
+
/** Reads a file's bytes. */
|
|
36
|
+
bytes(filePath: string): Promise<Uint8Array>;
|
|
37
|
+
/** Renders Markdown with the built-in renderer, like a loader's `renderMarkdown()`. */
|
|
38
|
+
renderMarkdown(body: string): Promise<RenderedContent>;
|
|
39
|
+
};
|
|
40
|
+
type ComputedContext<Data, Source = unknown> = {
|
|
41
|
+
/** The collection's key in the configured registry. */
|
|
42
|
+
collection: string;
|
|
43
|
+
id: string;
|
|
44
|
+
/** Loader-provided source metadata, detached from stored entries for this resolver. */
|
|
45
|
+
source?: Source extends object ? Readonly<Source> : Source;
|
|
46
|
+
data: Readonly<Data>;
|
|
47
|
+
readBody(this: void): Promise<string | undefined>;
|
|
48
|
+
/** Tracked reads of files beside the entry; edits re-prepare the entry. */
|
|
49
|
+
files: EntryFiles;
|
|
50
|
+
signal: AbortSignal;
|
|
51
|
+
};
|
|
52
|
+
type ComputedDefinition<Data = Record<string, unknown>, Source = unknown> = {
|
|
53
|
+
schema: Schema;
|
|
54
|
+
resolve(context: ComputedContext<Data, Source>): unknown;
|
|
55
|
+
};
|
|
56
|
+
/** Context for a payload's `combinations()` override, with the entry's prepared data. */
|
|
57
|
+
type VariantContext<Data, Source = unknown> = {
|
|
58
|
+
/** The collection's key in the configured registry. */
|
|
59
|
+
collection: string;
|
|
60
|
+
id: string;
|
|
61
|
+
/** Loader-provided source metadata, detached from stored entries for this resolver. */
|
|
62
|
+
source?: Source extends object ? Readonly<Source> : Source;
|
|
63
|
+
/** Validated metadata plus computed fields. */
|
|
64
|
+
data: Readonly<Data>;
|
|
65
|
+
signal: AbortSignal;
|
|
66
|
+
};
|
|
67
|
+
/** Context for a custom payload resolver, called once per entry and variant combination. */
|
|
68
|
+
type PayloadContext<Data, Source = unknown, Variant = {}> = VariantContext<Data, Source> & {
|
|
69
|
+
/** The variant combination being resolved; empty for payloads without variants. */
|
|
70
|
+
variant: Readonly<Variant>;
|
|
71
|
+
readBody(this: void): Promise<string | undefined>;
|
|
72
|
+
/** Tracked reads of files beside the entry; edits re-resolve only this variant. */
|
|
73
|
+
files: EntryFiles;
|
|
74
|
+
};
|
|
75
|
+
/** Data fields, including computed fields, whose values are string arrays. */
|
|
76
|
+
type VariantField<Data> = { [Field in keyof Data]-?: NonNullable<Data[Field]> extends readonly string[] ? Field : never; }[keyof Data] & string;
|
|
77
|
+
/**
|
|
78
|
+
* Enumerates one variant key's values: the name of a string-array data field, read per entry, or
|
|
79
|
+
* a fixed list. Derive values in a computed field when they need logic.
|
|
80
|
+
*/
|
|
81
|
+
type VariantValues<Data> = VariantField<Data> | readonly string[];
|
|
82
|
+
/**
|
|
83
|
+
* A custom payload: schema-validated data resolved during preparation and loaded only when a
|
|
84
|
+
* query requests it. Names cannot start with `_`, which built-in payloads such as `_body` use.
|
|
85
|
+
*/
|
|
86
|
+
type PayloadDefinition<Data = Record<string, unknown>, Source = unknown, Variant = {}> = {
|
|
87
|
+
schema: Schema;
|
|
88
|
+
/** Variant keys and their values for an entry. Omit for a single payload value. */
|
|
89
|
+
variants?: Record<string, VariantValues<Data>>;
|
|
90
|
+
/**
|
|
91
|
+
* Overrides the default cross product of enumerated values. Each combination must name every
|
|
92
|
+
* variant key with one of that key's enumerated values.
|
|
93
|
+
*/
|
|
94
|
+
combinations?(context: VariantContext<Data, Source> & {
|
|
95
|
+
variants: Readonly<Record<string, readonly string[]>>;
|
|
96
|
+
}): Iterable<Variant> | PromiseLike<Iterable<Variant>>;
|
|
97
|
+
resolve(context: PayloadContext<Data, Source, Variant>): unknown;
|
|
98
|
+
/**
|
|
99
|
+
* Set to `false` to resolve again in every revision, for resolvers that read data `files` cannot
|
|
100
|
+
* track, such as a remote API. Defaults to `true`.
|
|
101
|
+
*/
|
|
102
|
+
cache?: boolean;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Any payload declaration once its inferred types are erased, as registries and preparation see
|
|
106
|
+
* it. Typed declarations from `defineCollection` are always assignable.
|
|
107
|
+
*/
|
|
108
|
+
type PayloadDeclaration = {
|
|
109
|
+
schema: Schema;
|
|
110
|
+
variants?: Record<string, string | readonly string[]>;
|
|
111
|
+
combinations?(context: never): unknown;
|
|
112
|
+
resolve(context: never): unknown;
|
|
113
|
+
cache?: boolean;
|
|
114
|
+
};
|
|
115
|
+
type Relationship = {
|
|
116
|
+
collection: string;
|
|
117
|
+
type: "one" | "many";
|
|
118
|
+
from: string;
|
|
119
|
+
to: string;
|
|
120
|
+
referenceSide: "from" | "to" | "none";
|
|
121
|
+
};
|
|
122
|
+
type CollectionDefinition<SourceSchema extends Schema | undefined = Schema | undefined, Computed extends Record<string, ComputedDefinition<never, never>> = Record<string, ComputedDefinition<never, never>>, Relationships extends Record<string, Relationship> = Record<string, Relationship>> = {
|
|
123
|
+
loader: Loader;
|
|
124
|
+
schema?: SourceSchema;
|
|
125
|
+
computed?: Computed;
|
|
126
|
+
relationships?: Relationships;
|
|
127
|
+
payloads?: Record<string, PayloadDeclaration>;
|
|
128
|
+
/** Directories, relative to the project root, that every entry's `files` helpers may read. */
|
|
129
|
+
sharedFiles?: readonly string[];
|
|
130
|
+
};
|
|
131
|
+
type CollectionRegistry = Record<string, CollectionDefinition>;
|
|
132
|
+
type EntryData<Definition> = Definition extends {
|
|
133
|
+
schema: infer SourceSchema;
|
|
134
|
+
} ? SchemaOutput<SourceSchema> : Record<string, unknown>;
|
|
135
|
+
type ComputedData<Definition> = Definition extends {
|
|
136
|
+
computed: infer Computed;
|
|
137
|
+
} ? { [Name in keyof Computed]: Computed[Name] extends {
|
|
138
|
+
schema: infer ResultSchema;
|
|
139
|
+
} ? SchemaOutput<ResultSchema> : never; } : {};
|
|
140
|
+
type QueryData<Definition> = {
|
|
141
|
+
id: string;
|
|
142
|
+
} & EntryData<Definition> & ComputedData<Definition>;
|
|
143
|
+
type RelationshipsOf<Definition> = Definition extends {
|
|
144
|
+
relationships: infer Relationships;
|
|
145
|
+
} ? Relationships : {};
|
|
146
|
+
/**
|
|
147
|
+
* Payloads that Markdown sources, `glob()`, and custom loaders provide for every entry.
|
|
148
|
+
* Built-in names start with an underscore, so they never collide with custom payloads.
|
|
149
|
+
*/
|
|
150
|
+
type BuiltinPayloads = {
|
|
151
|
+
/** The retained raw body, or undefined when the entry has none or retention is disabled. */
|
|
152
|
+
_body: string | undefined;
|
|
153
|
+
/** HTML and headings; entries without a rendering path reject with `not-renderable`. */
|
|
154
|
+
_rendered: ContentRenderResult;
|
|
155
|
+
};
|
|
156
|
+
/** Type-only marker recording which built-in payloads a defined collection carries. */
|
|
157
|
+
type BuiltinPayloadMarker<Available extends keyof BuiltinPayloads> = {
|
|
158
|
+
readonly [builtinPayloadsType]?: Available;
|
|
159
|
+
};
|
|
160
|
+
/** One custom payload's validated value type and variant record, as recorded by a definition. */
|
|
161
|
+
type CustomPayload<Value = unknown, Variant = {}> = {
|
|
162
|
+
value: Value;
|
|
163
|
+
variant: Variant;
|
|
164
|
+
};
|
|
165
|
+
/** Type-only marker recording a defined collection's custom payload values and variant keys. */
|
|
166
|
+
type CustomPayloadMarker<Payloads extends Record<string, CustomPayload>> = {
|
|
167
|
+
readonly [customPayloadsType]?: Payloads;
|
|
168
|
+
};
|
|
169
|
+
type CustomPayloadsOf<Definition> = Definition extends {
|
|
170
|
+
readonly [customPayloadsType]?: infer Payloads;
|
|
171
|
+
} ? Payloads extends Record<string, CustomPayload> ? Payloads : {} : {};
|
|
172
|
+
/** Payload names and value types that queries can request for a collection definition. */
|
|
173
|
+
type PayloadsOf<Definition> = (Definition extends {
|
|
174
|
+
readonly [builtinPayloadsType]?: infer Available;
|
|
175
|
+
} ? Pick<BuiltinPayloads, Available & keyof BuiltinPayloads> : BuiltinPayloads) & { [Name in keyof CustomPayloadsOf<Definition>]: CustomPayloadsOf<Definition>[Name] extends CustomPayload<infer Value> ? Value : never; };
|
|
176
|
+
/** The value type of one payload that queries return under `_payloads`. */
|
|
177
|
+
type PayloadData<Definition, Name extends keyof PayloadsOf<Definition>> = PayloadsOf<Definition>[Name];
|
|
178
|
+
/** The variant keys a payload request must supply; empty for built-in and single-value payloads. */
|
|
179
|
+
type VariantOf<Definition, Name> = Name extends keyof CustomPayloadsOf<Definition> ? CustomPayloadsOf<Definition>[Name] extends CustomPayload<unknown, infer Variant> ? Variant : {} : {};
|
|
180
|
+
//#endregion
|
|
181
|
+
export { VariantValues as C, VariantOf as S, RelationshipsOf as _, ComputedContext as a, VariantContext as b, EntryFiles as c, PayloadData as d, PayloadDeclaration as f, Relationship as g, QueryData as h, CollectionRegistry as i, FileEntry as l, PayloadsOf as m, BuiltinPayloads as n, CustomPayload as o, PayloadDefinition as p, CollectionDefinition as r, CustomPayloadMarker as s, BuiltinPayloadMarker as t, PayloadContext as u, Schema as v, VariantField as x, SchemaOutput as y };
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ContentSourceEvent, o as ContentSourceSnapshot, t as BuildContentOptions } from "./build-
|
|
1
|
+
import { a as ContentSourceEvent, o as ContentSourceSnapshot, t as BuildContentOptions } from "./build-DL1GzmRy.mjs";
|
|
2
2
|
import { Plugin } from "vite";
|
|
3
3
|
//#region src/integrations/vite/plugin.d.ts
|
|
4
4
|
/** Public, format-neutral hooks for integrations sharing this plugin's preparation session. */
|
package/dist/vite.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-
|
|
2
|
-
import { n as serializeContentError } from "./diagnostics-
|
|
1
|
+
import { a as sessionInternals, i as resolveConfigPath, l as virtualDeclarations, o as withinDirectory, r as configCandidates, s as writeChanged, t as buildAtRoot, u as revisionModules } from "./build-CcqIpkes.mjs";
|
|
2
|
+
import { n as serializeContentError } from "./diagnostics-DmUZtrJ6.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { m as MaybePromise } from "./types-FmUJ3cH1.mjs";
|
|
2
|
-
//#region src/loaders/descriptor.d.ts
|
|
3
|
-
type GlobOptions = {
|
|
4
|
-
pattern: string | string[];
|
|
5
|
-
base?: string | URL;
|
|
6
|
-
generateId?: (context: {
|
|
7
|
-
entry: string;
|
|
8
|
-
base: URL;
|
|
9
|
-
data: Record<string, unknown>;
|
|
10
|
-
}) => string;
|
|
11
|
-
retainBody?: boolean;
|
|
12
|
-
deferRender?: boolean;
|
|
13
|
-
};
|
|
14
|
-
type FileOptions = {
|
|
15
|
-
parser?: (text: string) => MaybePromise<unknown>;
|
|
16
|
-
};
|
|
17
|
-
//#endregion
|
|
18
|
-
export { GlobOptions as n, FileOptions as t };
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { o as Loader } from "./types-FmUJ3cH1.mjs";
|
|
2
|
-
import { n as ContentRenderResult } from "./types-Dh-Sydyw.mjs";
|
|
3
|
-
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
-
//#region src/collection/types.d.ts
|
|
5
|
-
declare const builtinPayloadsType: unique symbol;
|
|
6
|
-
type Schema = StandardSchemaV1;
|
|
7
|
-
type SchemaOutput<Value> = Value extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Value> : Record<string, unknown>;
|
|
8
|
-
type ComputedContext<Data, Source = unknown> = {
|
|
9
|
-
/** The collection's key in the configured registry. */
|
|
10
|
-
collection: string;
|
|
11
|
-
id: string;
|
|
12
|
-
/** Loader-provided source metadata, detached from stored entries for this resolver. */
|
|
13
|
-
source?: Source extends object ? Readonly<Source> : Source;
|
|
14
|
-
data: Readonly<Data>;
|
|
15
|
-
readBody(this: void): Promise<string | undefined>;
|
|
16
|
-
signal: AbortSignal;
|
|
17
|
-
};
|
|
18
|
-
type ComputedDefinition<Data = Record<string, unknown>, Source = unknown> = {
|
|
19
|
-
schema: Schema;
|
|
20
|
-
resolve(context: ComputedContext<Data, Source>): unknown;
|
|
21
|
-
};
|
|
22
|
-
type Relationship = {
|
|
23
|
-
collection: string;
|
|
24
|
-
type: "one" | "many";
|
|
25
|
-
from: string;
|
|
26
|
-
to: string;
|
|
27
|
-
referenceSide: "from" | "to" | "none";
|
|
28
|
-
};
|
|
29
|
-
type CollectionDefinition<SourceSchema extends Schema | undefined = Schema | undefined, Computed extends Record<string, ComputedDefinition<never, never>> = Record<string, ComputedDefinition<never, never>>, Relationships extends Record<string, Relationship> = Record<string, Relationship>> = {
|
|
30
|
-
loader: Loader;
|
|
31
|
-
schema?: SourceSchema;
|
|
32
|
-
computed?: Computed;
|
|
33
|
-
relationships?: Relationships;
|
|
34
|
-
};
|
|
35
|
-
type CollectionRegistry = Record<string, CollectionDefinition>;
|
|
36
|
-
type EntryData<Definition> = Definition extends {
|
|
37
|
-
schema: infer SourceSchema;
|
|
38
|
-
} ? SchemaOutput<SourceSchema> : Record<string, unknown>;
|
|
39
|
-
type ComputedData<Definition> = Definition extends {
|
|
40
|
-
computed: infer Computed;
|
|
41
|
-
} ? { [Name in keyof Computed]: Computed[Name] extends {
|
|
42
|
-
schema: infer ResultSchema;
|
|
43
|
-
} ? SchemaOutput<ResultSchema> : never; } : {};
|
|
44
|
-
type QueryData<Definition> = {
|
|
45
|
-
id: string;
|
|
46
|
-
} & EntryData<Definition> & ComputedData<Definition>;
|
|
47
|
-
type RelationshipsOf<Definition> = Definition extends {
|
|
48
|
-
relationships: infer Relationships;
|
|
49
|
-
} ? Relationships : {};
|
|
50
|
-
/**
|
|
51
|
-
* Payloads that Markdown sources, `glob()`, and custom loaders provide for every entry.
|
|
52
|
-
* Built-in names start with an underscore, so they never collide with custom payloads.
|
|
53
|
-
*/
|
|
54
|
-
type BuiltinPayloads = {
|
|
55
|
-
/** The retained raw body, or undefined when the entry has none or retention is disabled. */
|
|
56
|
-
_body: string | undefined;
|
|
57
|
-
/** HTML and headings; entries without a rendering path reject with `not-renderable`. */
|
|
58
|
-
_rendered: ContentRenderResult;
|
|
59
|
-
};
|
|
60
|
-
/** Type-only marker recording which built-in payloads a defined collection carries. */
|
|
61
|
-
type BuiltinPayloadMarker<Available extends keyof BuiltinPayloads> = {
|
|
62
|
-
readonly [builtinPayloadsType]?: Available;
|
|
63
|
-
};
|
|
64
|
-
/** Payload names and value types that queries can request for a collection definition. */
|
|
65
|
-
type PayloadsOf<Definition> = Definition extends {
|
|
66
|
-
readonly [builtinPayloadsType]?: infer Available;
|
|
67
|
-
} ? Pick<BuiltinPayloads, Available & keyof BuiltinPayloads> : BuiltinPayloads;
|
|
68
|
-
//#endregion
|
|
69
|
-
export { ComputedContext as a, Relationship as c, SchemaOutput as d, CollectionRegistry as i, RelationshipsOf as l, BuiltinPayloads as n, PayloadsOf as o, CollectionDefinition as r, QueryData as s, BuiltinPayloadMarker as t, Schema as u };
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { n as contentError, t as ContentError } from "./errors-C2iuBM0G.mjs";
|
|
2
|
-
import { i as detach } from "./values-BbTV4QT-.mjs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
//#region src/loaders/descriptor.ts
|
|
6
|
-
const builtinSymbol = Symbol.for("content-query.builtin-loader");
|
|
7
|
-
/** Finds library-owned loader settings without depending on module instance identity. */
|
|
8
|
-
function builtinLoader(loader) {
|
|
9
|
-
return loader[builtinSymbol];
|
|
10
|
-
}
|
|
11
|
-
/** Resolves a loader's watch root from the application root, including file URLs. */
|
|
12
|
-
function builtinPath(descriptor, root) {
|
|
13
|
-
if (descriptor.kind === "file") return path.resolve(root, descriptor.filename);
|
|
14
|
-
return descriptor.options.base instanceof URL ? path.resolve(fileURLToPath(descriptor.options.base)) : path.resolve(root, descriptor.options.base ?? ".");
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/preparation/validation.ts
|
|
18
|
-
/** Checks records independently from validation-provider schema introspection. */
|
|
19
|
-
function isRecord(value) {
|
|
20
|
-
return !!value && typeof value === "object" && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
21
|
-
}
|
|
22
|
-
/** Validates one result, retaining structured provider issues and their original detail. */
|
|
23
|
-
async function validate(schema, value, context) {
|
|
24
|
-
if (!schema) return value;
|
|
25
|
-
try {
|
|
26
|
-
const result = await schema["~standard"].validate(value);
|
|
27
|
-
if (result.issues) {
|
|
28
|
-
const firstPath = result.issues[0]?.path?.map((segment) => typeof segment === "object" ? segment.key : segment);
|
|
29
|
-
throw new ContentError({
|
|
30
|
-
...context,
|
|
31
|
-
code: "validation-error",
|
|
32
|
-
message: result.issues.map((issue) => issue.message).join("; "),
|
|
33
|
-
issues: result.issues,
|
|
34
|
-
path: [...context.path ?? [], ...firstPath ?? []]
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
return result.value;
|
|
38
|
-
} catch (cause) {
|
|
39
|
-
throw contentError(cause, {
|
|
40
|
-
...context,
|
|
41
|
-
code: "validation-error",
|
|
42
|
-
message: "Schema validation failed."
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/** Checks loader transport structure and rejects duplicate snapshot/upsert identities. */
|
|
47
|
-
function normalizeSnapshot(entries, collection) {
|
|
48
|
-
if (!Array.isArray(entries)) throw new ContentError({
|
|
49
|
-
code: "source-error",
|
|
50
|
-
collection,
|
|
51
|
-
message: "load() must return an array of structured entries."
|
|
52
|
-
});
|
|
53
|
-
const snapshot = /* @__PURE__ */ new Map();
|
|
54
|
-
for (const entry of entries) {
|
|
55
|
-
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({
|
|
56
|
-
code: "source-error",
|
|
57
|
-
collection,
|
|
58
|
-
id: entry && typeof entry === "object" && typeof entry.id === "string" ? entry.id : void 0,
|
|
59
|
-
source: entry && typeof entry === "object" && typeof entry.source === "string" ? entry.source : void 0,
|
|
60
|
-
message: "Invalid structured loader entry."
|
|
61
|
-
});
|
|
62
|
-
if (snapshot.has(entry.id)) throw new ContentError({
|
|
63
|
-
code: "duplicate-id",
|
|
64
|
-
collection,
|
|
65
|
-
id: entry.id,
|
|
66
|
-
source: entry.source,
|
|
67
|
-
message: `Duplicate entry ID "${entry.id}".`
|
|
68
|
-
});
|
|
69
|
-
snapshot.set(entry.id, entry);
|
|
70
|
-
}
|
|
71
|
-
return snapshot;
|
|
72
|
-
}
|
|
73
|
-
/** Validates supplied rendering data and normalizes omitted headings. */
|
|
74
|
-
function renderedPayload(entry) {
|
|
75
|
-
if (entry.rendered === void 0) return;
|
|
76
|
-
const rendered = entry.rendered;
|
|
77
|
-
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.");
|
|
78
|
-
return {
|
|
79
|
-
html: rendered.html,
|
|
80
|
-
headings: detach(rendered.metadata?.headings ?? [])
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
|
-
export { builtinLoader as a, validate as i, normalizeSnapshot as n, builtinPath as o, renderedPayload as r, builtinSymbol as s, isRecord as t };
|