@json-schema-engine/core 0.0.1
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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/coverage.d.ts +30 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +81 -0
- package/dist/coverage.js.map +1 -0
- package/dist/cursor.d.ts +16 -0
- package/dist/cursor.d.ts.map +1 -0
- package/dist/cursor.js +28 -0
- package/dist/cursor.js.map +1 -0
- package/dist/dialect.d.ts +316 -0
- package/dist/dialect.d.ts.map +1 -0
- package/dist/dialect.js +135 -0
- package/dist/dialect.js.map +1 -0
- package/dist/engine.d.ts +203 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +493 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +182 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +370 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +49 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +128 -0
- package/dist/json.js.map +1 -0
- package/dist/keywords/applicator.d.ts +57 -0
- package/dist/keywords/applicator.d.ts.map +1 -0
- package/dist/keywords/applicator.js +789 -0
- package/dist/keywords/applicator.js.map +1 -0
- package/dist/keywords/core.d.ts +42 -0
- package/dist/keywords/core.d.ts.map +1 -0
- package/dist/keywords/core.js +139 -0
- package/dist/keywords/core.js.map +1 -0
- package/dist/keywords/format.d.ts +43 -0
- package/dist/keywords/format.d.ts.map +1 -0
- package/dist/keywords/format.js +101 -0
- package/dist/keywords/format.js.map +1 -0
- package/dist/keywords/metaschemas2019.d.ts +3 -0
- package/dist/keywords/metaschemas2019.d.ts.map +1 -0
- package/dist/keywords/metaschemas2019.js +406 -0
- package/dist/keywords/metaschemas2019.js.map +1 -0
- package/dist/keywords/metaschemas2020.d.ts +3 -0
- package/dist/keywords/metaschemas2020.d.ts.map +1 -0
- package/dist/keywords/metaschemas2020.js +441 -0
- package/dist/keywords/metaschemas2020.js.map +1 -0
- package/dist/keywords/metaschemas6.d.ts +3 -0
- package/dist/keywords/metaschemas6.d.ts.map +1 -0
- package/dist/keywords/metaschemas6.js +221 -0
- package/dist/keywords/metaschemas6.js.map +1 -0
- package/dist/keywords/metaschemas7.d.ts +3 -0
- package/dist/keywords/metaschemas7.d.ts.map +1 -0
- package/dist/keywords/metaschemas7.js +248 -0
- package/dist/keywords/metaschemas7.js.map +1 -0
- package/dist/keywords/unevaluated.d.ts +14 -0
- package/dist/keywords/unevaluated.d.ts.map +1 -0
- package/dist/keywords/unevaluated.js +296 -0
- package/dist/keywords/unevaluated.js.map +1 -0
- package/dist/keywords/validation.d.ts +21 -0
- package/dist/keywords/validation.d.ts.map +1 -0
- package/dist/keywords/validation.js +332 -0
- package/dist/keywords/validation.js.map +1 -0
- package/dist/keywords/vocab2019.d.ts +36 -0
- package/dist/keywords/vocab2019.d.ts.map +1 -0
- package/dist/keywords/vocab2019.js +585 -0
- package/dist/keywords/vocab2019.js.map +1 -0
- package/dist/keywords/vocab2020.d.ts +20 -0
- package/dist/keywords/vocab2020.d.ts.map +1 -0
- package/dist/keywords/vocab2020.js +55 -0
- package/dist/keywords/vocab2020.js.map +1 -0
- package/dist/keywords/vocab7.d.ts +46 -0
- package/dist/keywords/vocab7.d.ts.map +1 -0
- package/dist/keywords/vocab7.js +305 -0
- package/dist/keywords/vocab7.js.map +1 -0
- package/dist/loader.d.ts +41 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +13 -0
- package/dist/loader.js.map +1 -0
- package/dist/lowering.d.ts +371 -0
- package/dist/lowering.d.ts.map +1 -0
- package/dist/lowering.js +59 -0
- package/dist/lowering.js.map +1 -0
- package/dist/output.d.ts +251 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +357 -0
- package/dist/output.js.map +1 -0
- package/dist/records.d.ts +71 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +150 -0
- package/dist/records.js.map +1 -0
- package/dist/ref.d.ts +10 -0
- package/dist/ref.d.ts.map +1 -0
- package/dist/ref.js +5 -0
- package/dist/ref.js.map +1 -0
- package/dist/regex.d.ts +45 -0
- package/dist/regex.d.ts.map +1 -0
- package/dist/regex.js +163 -0
- package/dist/regex.js.map +1 -0
- package/dist/registry.d.ts +141 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +407 -0
- package/dist/registry.js.map +1 -0
- package/dist/result.d.ts +109 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +112 -0
- package/dist/result.js.map +1 -0
- package/dist/uri.d.ts +18 -0
- package/dist/uri.d.ts.map +1 -0
- package/dist/uri.js +27 -0
- package/dist/uri.js.map +1 -0
- package/dist/walk.d.ts +25 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +65 -0
- package/dist/walk.js.map +1 -0
- package/package.json +32 -0
- package/src/coverage.ts +88 -0
- package/src/cursor.ts +42 -0
- package/src/dialect.ts +428 -0
- package/src/engine.ts +741 -0
- package/src/index.ts +699 -0
- package/src/json.ts +137 -0
- package/src/keywords/applicator.ts +895 -0
- package/src/keywords/core.ts +168 -0
- package/src/keywords/format.ts +143 -0
- package/src/keywords/metaschemas2019.ts +410 -0
- package/src/keywords/metaschemas2020.ts +443 -0
- package/src/keywords/metaschemas6.ts +226 -0
- package/src/keywords/metaschemas7.ts +253 -0
- package/src/keywords/unevaluated.ts +329 -0
- package/src/keywords/validation.ts +627 -0
- package/src/keywords/vocab2019.ts +676 -0
- package/src/keywords/vocab2020.ts +82 -0
- package/src/keywords/vocab7.ts +393 -0
- package/src/loader.ts +60 -0
- package/src/lowering.ts +414 -0
- package/src/output.ts +651 -0
- package/src/records.ts +226 -0
- package/src/ref.ts +14 -0
- package/src/regex.ts +171 -0
- package/src/registry.ts +481 -0
- package/src/result.ts +252 -0
- package/src/uri.ts +35 -0
- package/src/walk.ts +88 -0
package/dist/registry.js
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
// Schema registration and static reference resolution.
|
|
2
|
+
//
|
|
3
|
+
// The registration walk descends only into *schema positions*, so `$id` or
|
|
4
|
+
// `$anchor` inside `enum` data or an unknown keyword's value is never treated
|
|
5
|
+
// as an identifier. Unlike the F2 prototype, the positions are not hard-coded:
|
|
6
|
+
// the walk asks each keyword behavior's analyze() for its subschema positions
|
|
7
|
+
// (DESIGN.md D1/D2), so a custom applicator registered through the dialect
|
|
8
|
+
// registry gets correct identifier handling for free.
|
|
9
|
+
import { isObject, escapeSegment, unescapeSegment } from "./json.js";
|
|
10
|
+
import { resolveUri, splitFragment, UnresolvableRefError } from "./uri.js";
|
|
11
|
+
import { ReadOnlyRegistryError } from "./dialect.js";
|
|
12
|
+
/**
|
|
13
|
+
* A value that is not a schema (neither an object nor a boolean) was found
|
|
14
|
+
* where a schema is required (D19): in a keyword-claimed schema position at
|
|
15
|
+
* registration, or applied as a schema during evaluation. Keyword-value
|
|
16
|
+
* validity beyond schema shape is not checked here — that is metaschema
|
|
17
|
+
* validation's job ({@link EngineOptions.validateSchemas}).
|
|
18
|
+
*
|
|
19
|
+
* When thrown during registration, the document may be partially indexed;
|
|
20
|
+
* re-register a corrected document under the same URI, or discard the
|
|
21
|
+
* engine.
|
|
22
|
+
*/
|
|
23
|
+
export class InvalidSchemaError extends Error {
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Schema nesting (at registration) or schema-application nesting (at
|
|
27
|
+
* evaluation) exceeded {@link EngineOptions.maxDepth}. A bounded, catchable
|
|
28
|
+
* failure that replaces the native stack overflow deep input would otherwise
|
|
29
|
+
* cause; the engine remains usable afterward (each evaluation runs in fresh
|
|
30
|
+
* state). Raise `maxDepth` for legitimately deep documents, within what the
|
|
31
|
+
* runtime's own stack allows.
|
|
32
|
+
*/
|
|
33
|
+
export class MaxDepthExceededError extends Error {
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Default schema/application nesting bound. Chosen below the native
|
|
37
|
+
* call-stack ceiling so the typed {@link MaxDepthExceededError} fires before
|
|
38
|
+
* a `RangeError`, while staying generous for real-world documents.
|
|
39
|
+
*/
|
|
40
|
+
export const DEFAULT_MAX_DEPTH = 512;
|
|
41
|
+
/** One-line description of a non-schema value for error messages. */
|
|
42
|
+
export function describeNonSchema(node) {
|
|
43
|
+
if (node === null)
|
|
44
|
+
return "null";
|
|
45
|
+
return Array.isArray(node) ? "array" : typeof node;
|
|
46
|
+
}
|
|
47
|
+
/** Schema registration, identifier indexing, and reference resolution. */
|
|
48
|
+
export class SchemaRegistry {
|
|
49
|
+
dialectRegistry;
|
|
50
|
+
defaultDialectUri;
|
|
51
|
+
maxDepth;
|
|
52
|
+
documents = new Map(); // resource URI -> schema node
|
|
53
|
+
anchors = new Map(); // "resource#anchor"
|
|
54
|
+
dynamicAnchors = new Map(); // $dynamicAnchor only (D8)
|
|
55
|
+
recursiveRoots = new Set(); // 2019-09 $recursiveAnchor at root
|
|
56
|
+
// Unions of StaticFacts.produces / consumes over every registered keyword
|
|
57
|
+
// occurrence: produce()'s declaration guard and the elision predicate's
|
|
58
|
+
// "someone might read this" side (D5/M5.5).
|
|
59
|
+
producedBehaviorIds = new Set();
|
|
60
|
+
consumedBehaviorIds = new Set();
|
|
61
|
+
// Consumed ids whose producer declares evaluated coverage (D9a facts): the
|
|
62
|
+
// only dependency data the coverage channel's shape-dispatching folds
|
|
63
|
+
// understand (coverage.ts).
|
|
64
|
+
coverageProducerIds = new Set();
|
|
65
|
+
coverageConsumedIds = new Set();
|
|
66
|
+
documentDialects = new Map(); // resource URI -> dialect URI
|
|
67
|
+
resourceLocations = new Map();
|
|
68
|
+
// Retrieval URI -> declared $id base, when they differ: the document must
|
|
69
|
+
// be reachable under both, but anchors and lexical bases live under $id.
|
|
70
|
+
aliases = new Map();
|
|
71
|
+
// External resources seen in reference values during registration walks,
|
|
72
|
+
// drained by the load closure (D7).
|
|
73
|
+
pendingResources = new Set();
|
|
74
|
+
documentRanges = new Map();
|
|
75
|
+
/**
|
|
76
|
+
* Called for each `pattern`/`patternProperties` regex during a
|
|
77
|
+
* registration walk, when set. The Engine installs this (after registering
|
|
78
|
+
* its trusted metaschemas) to enforce `rejectUnsafeRegex`.
|
|
79
|
+
*/
|
|
80
|
+
onRegex;
|
|
81
|
+
// Snapshots share the indexes above copy-on-write: the source copies them
|
|
82
|
+
// before its first registration after a snapshot, so a view stays frozen
|
|
83
|
+
// at no cost until the source changes.
|
|
84
|
+
shared = false;
|
|
85
|
+
readOnly = false;
|
|
86
|
+
constructor(dialectRegistry, defaultDialectUri, maxDepth = DEFAULT_MAX_DEPTH) {
|
|
87
|
+
this.dialectRegistry = dialectRegistry;
|
|
88
|
+
this.defaultDialectUri = defaultDialectUri;
|
|
89
|
+
this.maxDepth = maxDepth;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A read-only view of the registry's current contents, over a view of the
|
|
93
|
+
* dialect registry. Later registrations on this registry are invisible to
|
|
94
|
+
* the view, and registering into the view throws
|
|
95
|
+
* {@link ReadOnlyRegistryError}. A compiled artifact binds to one so that
|
|
96
|
+
* a compilation boundary cannot change reference resolution (E1).
|
|
97
|
+
*/
|
|
98
|
+
snapshot() {
|
|
99
|
+
const view = new SchemaRegistry(this.dialectRegistry.snapshot(), this.defaultDialectUri, this.maxDepth);
|
|
100
|
+
view.documents = this.documents;
|
|
101
|
+
view.anchors = this.anchors;
|
|
102
|
+
view.dynamicAnchors = this.dynamicAnchors;
|
|
103
|
+
view.recursiveRoots = this.recursiveRoots;
|
|
104
|
+
view.producedBehaviorIds = this.producedBehaviorIds;
|
|
105
|
+
view.consumedBehaviorIds = this.consumedBehaviorIds;
|
|
106
|
+
view.coverageProducerIds = this.coverageProducerIds;
|
|
107
|
+
view.coverageConsumedIds = this.coverageConsumedIds;
|
|
108
|
+
view.documentDialects = this.documentDialects;
|
|
109
|
+
view.resourceLocations = this.resourceLocations;
|
|
110
|
+
view.aliases = this.aliases;
|
|
111
|
+
view.documentRanges = this.documentRanges;
|
|
112
|
+
view.readOnly = true;
|
|
113
|
+
this.shared = true;
|
|
114
|
+
return view;
|
|
115
|
+
}
|
|
116
|
+
mutable() {
|
|
117
|
+
if (this.readOnly) {
|
|
118
|
+
throw new ReadOnlyRegistryError("a registry snapshot is read-only");
|
|
119
|
+
}
|
|
120
|
+
if (!this.shared)
|
|
121
|
+
return;
|
|
122
|
+
this.documents = new Map(this.documents);
|
|
123
|
+
this.anchors = new Map(this.anchors);
|
|
124
|
+
this.dynamicAnchors = new Map(this.dynamicAnchors);
|
|
125
|
+
this.recursiveRoots = new Set(this.recursiveRoots);
|
|
126
|
+
this.producedBehaviorIds = new Set(this.producedBehaviorIds);
|
|
127
|
+
this.consumedBehaviorIds = new Set(this.consumedBehaviorIds);
|
|
128
|
+
this.coverageProducerIds = new Set(this.coverageProducerIds);
|
|
129
|
+
this.coverageConsumedIds = new Set(this.coverageConsumedIds);
|
|
130
|
+
this.documentDialects = new Map(this.documentDialects);
|
|
131
|
+
this.resourceLocations = new Map(this.resourceLocations);
|
|
132
|
+
this.aliases = new Map(this.aliases);
|
|
133
|
+
this.documentRanges = new Map(this.documentRanges);
|
|
134
|
+
this.shared = false;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Register a schema document. The dialect comes from `$schema` when present
|
|
138
|
+
* (and must already be registered), else `dialectUri`, else the default.
|
|
139
|
+
* Returns the document's canonical base URI.
|
|
140
|
+
*/
|
|
141
|
+
register(schema, retrievalUri, dialectUri, getRange) {
|
|
142
|
+
this.mutable();
|
|
143
|
+
// Dialect URIs are compared fragment-free: "…/draft-07/schema#" (the
|
|
144
|
+
// canonical in-the-wild $schema spelling) names the same dialect.
|
|
145
|
+
let effectiveDialect = splitFragment(dialectUri ?? this.defaultDialectUri).resource;
|
|
146
|
+
if (isObject(schema) && typeof schema.$schema === "string") {
|
|
147
|
+
effectiveDialect = splitFragment(resolveUri(schema.$schema, retrievalUri)).resource;
|
|
148
|
+
}
|
|
149
|
+
const dialect = this.dialectRegistry.getDialect(effectiveDialect);
|
|
150
|
+
const retrievalResource = splitFragment(retrievalUri).resource;
|
|
151
|
+
let baseUri = retrievalResource;
|
|
152
|
+
const rootIds = isObject(schema) ? dialect.identifiers(schema) : {};
|
|
153
|
+
if (rootIds.baseId !== undefined) {
|
|
154
|
+
baseUri = splitFragment(resolveUri(rootIds.baseId, baseUri)).resource;
|
|
155
|
+
}
|
|
156
|
+
if (baseUri !== retrievalResource)
|
|
157
|
+
this.aliases.set(retrievalResource, baseUri);
|
|
158
|
+
this.documents.set(baseUri, schema);
|
|
159
|
+
this.documentDialects.set(baseUri, effectiveDialect);
|
|
160
|
+
this.resourceLocations.set(baseUri, { documentUri: baseUri, pointer: "" });
|
|
161
|
+
if (getRange)
|
|
162
|
+
this.documentRanges.set(baseUri, getRange);
|
|
163
|
+
this.walk(schema, baseUri, "", baseUri, "", dialect, 0);
|
|
164
|
+
return baseUri;
|
|
165
|
+
}
|
|
166
|
+
walk(node, baseUri, pointer, documentUri, docPointer, // pointer from the registered document's root
|
|
167
|
+
dialect, depth) {
|
|
168
|
+
if (depth > this.maxDepth) {
|
|
169
|
+
throw new MaxDepthExceededError(`schema nesting exceeds maxDepth (${this.maxDepth}) at ` +
|
|
170
|
+
`'${baseUri}#${pointer}'`);
|
|
171
|
+
}
|
|
172
|
+
if (typeof node === "boolean")
|
|
173
|
+
return;
|
|
174
|
+
if (!isObject(node)) {
|
|
175
|
+
throw new InvalidSchemaError(`non-schema value (${describeNonSchema(node)}) in schema position ` +
|
|
176
|
+
`'${baseUri}#${pointer}'`);
|
|
177
|
+
}
|
|
178
|
+
const ids = dialect.identifiers(node);
|
|
179
|
+
if (pointer !== "" && ids.baseId !== undefined) {
|
|
180
|
+
baseUri = splitFragment(resolveUri(ids.baseId, baseUri)).resource;
|
|
181
|
+
pointer = "";
|
|
182
|
+
this.documents.set(baseUri, node);
|
|
183
|
+
this.documentDialects.set(baseUri, dialect.uri);
|
|
184
|
+
this.resourceLocations.set(baseUri, { documentUri, pointer: docPointer });
|
|
185
|
+
}
|
|
186
|
+
for (const anchor of ids.anchors ?? []) {
|
|
187
|
+
this.anchors.set(`${baseUri}#${anchor}`, { node, baseUri, pointer });
|
|
188
|
+
}
|
|
189
|
+
// A dynamic anchor is also a plain anchor for $ref purposes; only the
|
|
190
|
+
// dynamic-anchor index participates in $dynamicRef rebinding (D8).
|
|
191
|
+
if (ids.dynamicAnchor !== undefined) {
|
|
192
|
+
const ref = { node, baseUri, pointer };
|
|
193
|
+
this.anchors.set(`${baseUri}#${ids.dynamicAnchor}`, ref);
|
|
194
|
+
this.dynamicAnchors.set(`${baseUri}#${ids.dynamicAnchor}`, ref);
|
|
195
|
+
}
|
|
196
|
+
// $recursiveAnchor participates in rebinding only at a resource root.
|
|
197
|
+
if (ids.recursiveAnchor === true && pointer === "") {
|
|
198
|
+
this.recursiveRoots.add(baseUri);
|
|
199
|
+
}
|
|
200
|
+
for (const [name, value] of Object.entries(node)) {
|
|
201
|
+
const behavior = dialect.keywords.get(name)?.behavior;
|
|
202
|
+
const facts = behavior?.analyze?.(value, { schema: node });
|
|
203
|
+
if (!facts)
|
|
204
|
+
continue;
|
|
205
|
+
for (const p of facts.produces ?? [])
|
|
206
|
+
this.producedBehaviorIds.add(p);
|
|
207
|
+
for (const c of facts.consumes ?? []) {
|
|
208
|
+
this.consumedBehaviorIds.add(c);
|
|
209
|
+
if (this.coverageProducerIds.has(c))
|
|
210
|
+
this.coverageConsumedIds.add(c);
|
|
211
|
+
}
|
|
212
|
+
if (facts.evaluatesNames !== undefined ||
|
|
213
|
+
facts.evaluatesIndexes !== undefined) {
|
|
214
|
+
this.coverageProducerIds.add(behavior.id);
|
|
215
|
+
if (this.consumedBehaviorIds.has(behavior.id)) {
|
|
216
|
+
this.coverageConsumedIds.add(behavior.id);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (this.onRegex) {
|
|
220
|
+
const keywordLocation = `${baseUri}#${pointer}/${escapeSegment(name)}`;
|
|
221
|
+
for (const rx of facts.regexes ?? [])
|
|
222
|
+
this.onRegex(rx, keywordLocation);
|
|
223
|
+
}
|
|
224
|
+
for (const ref of facts.references ?? []) {
|
|
225
|
+
try {
|
|
226
|
+
this.pendingResources.add(splitFragment(resolveUri(ref, baseUri)).resource);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Unresolvable now is not an error: evaluation reports it if the
|
|
230
|
+
// reference is actually followed.
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const positions = facts.subschemas;
|
|
234
|
+
if (!positions)
|
|
235
|
+
continue;
|
|
236
|
+
for (const relPath of positions) {
|
|
237
|
+
let child = value;
|
|
238
|
+
let suffix = "/" + escapeSegment(name);
|
|
239
|
+
for (const seg of relPath) {
|
|
240
|
+
child = (Array.isArray(child)
|
|
241
|
+
? child[seg]
|
|
242
|
+
: child[seg]);
|
|
243
|
+
suffix += "/" + escapeSegment(String(seg));
|
|
244
|
+
}
|
|
245
|
+
this.walk(child, baseUri, pointer + suffix, documentUri, docPointer + suffix, dialect, depth + 1);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* The registered document containing a schema resource, and the resource
|
|
251
|
+
* root's pointer from that document's root (D17 bridge; see loader.ts).
|
|
252
|
+
* Undefined for resources the registration walk never saw (e.g. an `$id`
|
|
253
|
+
* inside an unknown keyword reached only by pointer navigation).
|
|
254
|
+
*/
|
|
255
|
+
documentLocation(resourceUri) {
|
|
256
|
+
return this.resourceLocations.get(this.canonical(resourceUri));
|
|
257
|
+
}
|
|
258
|
+
/** Source range for a document-rooted pointer, when the loader supplied one (D17). */
|
|
259
|
+
range(documentUri, pointer) {
|
|
260
|
+
return this.documentRanges.get(documentUri)?.(pointer);
|
|
261
|
+
}
|
|
262
|
+
/** True if a resource is registered, directly or via a retrieval-URI alias. */
|
|
263
|
+
has(resourceUri) {
|
|
264
|
+
return this.documents.has(resourceUri) || this.aliases.has(resourceUri);
|
|
265
|
+
}
|
|
266
|
+
/** The schema node at a resource's root, if registered. */
|
|
267
|
+
document(resourceUri) {
|
|
268
|
+
return this.documents.get(this.canonical(resourceUri));
|
|
269
|
+
}
|
|
270
|
+
/** External resources referenced but not yet registered; drained per call. */
|
|
271
|
+
takeUnresolved() {
|
|
272
|
+
const missing = [...this.pendingResources].filter((r) => !this.has(r));
|
|
273
|
+
this.pendingResources.clear();
|
|
274
|
+
return missing;
|
|
275
|
+
}
|
|
276
|
+
/** The `$dynamicAnchor` target for a name in a resource, if one was registered (D8). */
|
|
277
|
+
dynamicAnchor(resourceUri, name) {
|
|
278
|
+
return this.dynamicAnchors.get(`${this.canonical(resourceUri)}#${name}`);
|
|
279
|
+
}
|
|
280
|
+
/** True if a resource's root carries 2019-09 `$recursiveAnchor: true`. */
|
|
281
|
+
hasRecursiveRoot(resourceUri) {
|
|
282
|
+
return this.recursiveRoots.has(this.canonical(resourceUri));
|
|
283
|
+
}
|
|
284
|
+
/** Behavior ids some registered keyword declares it produces dependency data under. */
|
|
285
|
+
producedIds() {
|
|
286
|
+
return this.producedBehaviorIds;
|
|
287
|
+
}
|
|
288
|
+
/** Behavior ids some registered keyword declares it consumes. */
|
|
289
|
+
consumedIds() {
|
|
290
|
+
return this.consumedBehaviorIds;
|
|
291
|
+
}
|
|
292
|
+
/** The consumed subset of {@link consumedIds} whose producer declares evaluated coverage: what the coverage channel carries. */
|
|
293
|
+
coverageIds() {
|
|
294
|
+
return this.coverageConsumedIds;
|
|
295
|
+
}
|
|
296
|
+
canonical(resourceUri) {
|
|
297
|
+
return this.aliases.get(resourceUri) ?? resourceUri;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* The dialect URI a resource was registered under.
|
|
301
|
+
* @throws UnresolvableRefError if the resource is not registered.
|
|
302
|
+
*/
|
|
303
|
+
dialectUriFor(baseUri) {
|
|
304
|
+
const uri = this.documentDialects.get(this.canonical(baseUri));
|
|
305
|
+
if (uri === undefined)
|
|
306
|
+
throw new UnresolvableRefError(`unknown schema '${baseUri}'`);
|
|
307
|
+
return uri;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* The dialect a resource was registered under.
|
|
311
|
+
* @throws UnresolvableRefError if the resource is not registered.
|
|
312
|
+
*/
|
|
313
|
+
dialectFor(baseUri) {
|
|
314
|
+
return this.dialectRegistry.getDialect(this.dialectUriFor(baseUri));
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Resolves a URI to its resource's root schema.
|
|
318
|
+
* @throws UnresolvableRefError if the resource is not registered.
|
|
319
|
+
*/
|
|
320
|
+
rootRef(uri) {
|
|
321
|
+
const { resource: rawResource, fragment } = splitFragment(uri);
|
|
322
|
+
const resource = this.canonical(rawResource);
|
|
323
|
+
if (fragment !== null && fragment !== "") {
|
|
324
|
+
return this.resolveRef(uri, resource);
|
|
325
|
+
}
|
|
326
|
+
const node = this.documents.get(resource);
|
|
327
|
+
if (node === undefined)
|
|
328
|
+
throw new UnresolvableRefError(`unknown schema '${resource}'`);
|
|
329
|
+
return { node, baseUri: resource, pointer: "" };
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Resolves a reference value against the referring schema's base URI.
|
|
333
|
+
* @throws UnresolvableRefError if the resource, anchor, or pointer target
|
|
334
|
+
* does not exist.
|
|
335
|
+
*/
|
|
336
|
+
resolveRef(ref, currentBase) {
|
|
337
|
+
const resolved = splitFragment(resolveUri(ref, currentBase));
|
|
338
|
+
const resource = this.canonical(resolved.resource);
|
|
339
|
+
const fragment = resolved.fragment;
|
|
340
|
+
if (fragment !== null && fragment !== "" && !fragment.startsWith("/")) {
|
|
341
|
+
const hit = this.anchors.get(`${resource}#${fragment}`);
|
|
342
|
+
if (!hit)
|
|
343
|
+
throw new UnresolvableRefError(`unknown anchor '${resource}#${fragment}'`);
|
|
344
|
+
return hit;
|
|
345
|
+
}
|
|
346
|
+
const root = this.documents.get(resource);
|
|
347
|
+
if (root === undefined)
|
|
348
|
+
throw new UnresolvableRefError(`unknown schema '${resource}'`);
|
|
349
|
+
if (fragment === null || fragment === "") {
|
|
350
|
+
return { node: root, baseUri: resource, pointer: "" };
|
|
351
|
+
}
|
|
352
|
+
// JSON Pointer navigation, tracking identifier-induced base changes on
|
|
353
|
+
// the way, per the target document's dialect (D18).
|
|
354
|
+
const identifiers = this.dialectFor(resource).identifiers;
|
|
355
|
+
let node = root;
|
|
356
|
+
let baseUri = resource;
|
|
357
|
+
let pointer = "";
|
|
358
|
+
for (const rawSeg of fragment.slice(1).split("/")) {
|
|
359
|
+
const seg = unescapeSegment(rawSeg);
|
|
360
|
+
if (Array.isArray(node)) {
|
|
361
|
+
node = node[Number(seg)];
|
|
362
|
+
}
|
|
363
|
+
else if (isObject(node) && Object.hasOwn(node, seg)) {
|
|
364
|
+
node = node[seg];
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
node = undefined;
|
|
368
|
+
}
|
|
369
|
+
if (node === undefined) {
|
|
370
|
+
throw new UnresolvableRefError(`pointer '${fragment}' not found in '${resource}'`);
|
|
371
|
+
}
|
|
372
|
+
pointer += "/" + escapeSegment(seg);
|
|
373
|
+
if (isObject(node)) {
|
|
374
|
+
const baseId = identifiers(node).baseId;
|
|
375
|
+
if (baseId !== undefined) {
|
|
376
|
+
baseUri = splitFragment(resolveUri(baseId, baseUri)).resource;
|
|
377
|
+
pointer = "";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return { node, baseUri, pointer };
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Descend from a schema position into keyword/index children, maintaining
|
|
385
|
+
* canonical location and lexical base.
|
|
386
|
+
*/
|
|
387
|
+
child(ref, segments) {
|
|
388
|
+
const identifiers = this.dialectFor(ref.baseUri).identifiers;
|
|
389
|
+
let node = ref.node;
|
|
390
|
+
let { baseUri, pointer } = ref;
|
|
391
|
+
for (const seg of segments) {
|
|
392
|
+
node = (Array.isArray(node)
|
|
393
|
+
? node[seg]
|
|
394
|
+
: node[seg]);
|
|
395
|
+
pointer += "/" + escapeSegment(String(seg));
|
|
396
|
+
if (isObject(node)) {
|
|
397
|
+
const baseId = identifiers(node).baseId;
|
|
398
|
+
if (baseId !== undefined) {
|
|
399
|
+
baseUri = splitFragment(resolveUri(baseId, baseUri)).resource;
|
|
400
|
+
pointer = "";
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return { node, baseUri, pointer };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/result.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { type AnnotationSelection, type AnnotationUnit, type BasicOutputDocument, type DetailedOutputUnit, type ErrorUnit, type ListOutputDocument, type OutputUnit, type RenderNode, type TraceUnit } from "./output.js";
|
|
2
|
+
/**
|
|
3
|
+
* Output format names (ADR 0003), each fixing a document structure and field
|
|
4
|
+
* vocabulary: `flag`, `basic`, `detailed`, `verbose` from IETF draft-03 §13;
|
|
5
|
+
* `list`, `hierarchical` from the machines-oriented output proposal.
|
|
6
|
+
*/
|
|
7
|
+
export type OutputFormat = "flag" | "basic" | "detailed" | "verbose" | "list" | "hierarchical";
|
|
8
|
+
/** Thrown by `evaluate` for an unsupported combination of output options (ADR 0003: no silent no-ops). */
|
|
9
|
+
export declare class OutputOptionsError extends Error {
|
|
10
|
+
}
|
|
11
|
+
/** Options for `Engine.evaluate`. */
|
|
12
|
+
export interface EvaluateOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Output format, by name; default `"flag"` (the minimal level: `valid`
|
|
15
|
+
* only). Every other name populates the flat `Result.errors`/
|
|
16
|
+
* `Result.annotations` surface and renders `Result.outputDocument` in the
|
|
17
|
+
* format's own structure ({@link OutputDocuments}).
|
|
18
|
+
*/
|
|
19
|
+
output?: OutputFormat;
|
|
20
|
+
/**
|
|
21
|
+
* Request the verbose level for `list` or `hierarchical`: every unit is
|
|
22
|
+
* kept and irrelevant records (draft-03 §12.2) render marked, as
|
|
23
|
+
* `droppedErrors`/`droppedAnnotations` in the document and as
|
|
24
|
+
* `Result.droppedErrors`/`Result.droppedAnnotations`. `basic` and
|
|
25
|
+
* `detailed` are relevant-level by definition and reject it; `verbose` is
|
|
26
|
+
* the verbose level by definition.
|
|
27
|
+
*/
|
|
28
|
+
verbose?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Which annotations reach output: `false` (default) none, `true` all, or
|
|
31
|
+
* an {@link AnnotationSelection}. Independent of format and level; never
|
|
32
|
+
* affects dependency data or validation.
|
|
33
|
+
*/
|
|
34
|
+
annotations?: boolean | AnnotationSelection;
|
|
35
|
+
/** Include `keyword`, `vocabulary`, and structured `params` on each flat error unit (D13). */
|
|
36
|
+
errorParams?: boolean;
|
|
37
|
+
/** Decorate flat units with schema-side source positions when available (D17). */
|
|
38
|
+
positions?: boolean;
|
|
39
|
+
/** Render the evaluation trace into `Result.trace`. */
|
|
40
|
+
trace?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** The document type each non-minimal {@link OutputFormat} renders. */
|
|
43
|
+
export interface OutputDocuments {
|
|
44
|
+
basic: BasicOutputDocument;
|
|
45
|
+
detailed: DetailedOutputUnit;
|
|
46
|
+
verbose: DetailedOutputUnit;
|
|
47
|
+
list: ListOutputDocument;
|
|
48
|
+
hierarchical: OutputUnit;
|
|
49
|
+
}
|
|
50
|
+
/** The result of an evaluation. */
|
|
51
|
+
export interface Result {
|
|
52
|
+
valid: boolean;
|
|
53
|
+
/** relevant errors, native field names; present on an invalid result of any non-flag format */
|
|
54
|
+
errors?: ErrorUnit[];
|
|
55
|
+
/** relevant annotations per the selection; present on a valid result when annotations are selected */
|
|
56
|
+
annotations?: AnnotationUnit[];
|
|
57
|
+
/** irrelevant errors (draft-03 §12.2); present at the verbose level */
|
|
58
|
+
droppedErrors?: ErrorUnit[];
|
|
59
|
+
/** irrelevant annotations per the selection; present at the verbose level when annotations are selected */
|
|
60
|
+
droppedAnnotations?: AnnotationUnit[];
|
|
61
|
+
/** the output document, in the requested format's structure ({@link OutputDocuments}) */
|
|
62
|
+
outputDocument?: OutputDocuments[keyof OutputDocuments];
|
|
63
|
+
/** the evaluation trace, present with `trace: true`; `errorIndexes` reference `errors` on this result */
|
|
64
|
+
trace?: TraceUnit;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* {@link Result} narrowed by literal options: `outputDocument` takes the
|
|
68
|
+
* requested format's document type and `trace` is present when requested.
|
|
69
|
+
* A widened {@link EvaluateOptions} yields the plain `Result`.
|
|
70
|
+
*/
|
|
71
|
+
export type ResultFor<O extends EvaluateOptions> = Result & ([O["output"]] extends [infer F extends keyof OutputDocuments] ? {
|
|
72
|
+
outputDocument: OutputDocuments[F];
|
|
73
|
+
} : unknown) & ([O["trace"]] extends [true] ? {
|
|
74
|
+
trace: TraceUnit;
|
|
75
|
+
} : unknown);
|
|
76
|
+
/** What an evaluation must produce for a resolved set of output options. */
|
|
77
|
+
export interface OutputDemand {
|
|
78
|
+
format: OutputFormat;
|
|
79
|
+
/** the verbose level: irrelevant records are rendered, marked */
|
|
80
|
+
verbose: boolean;
|
|
81
|
+
/** the located tree is built: every format but flag and basic, or `trace: true` */
|
|
82
|
+
tracing: boolean;
|
|
83
|
+
annotations: boolean | AnnotationSelection;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Every combination of controls is supported or rejected here, before any
|
|
87
|
+
* evaluation (ADR 0003).
|
|
88
|
+
*/
|
|
89
|
+
export declare function resolveOutputDemand(options: EvaluateOptions): OutputDemand;
|
|
90
|
+
/**
|
|
91
|
+
* The flat surface as one evaluation produced it. The arrays are placed on
|
|
92
|
+
* the {@link Result} as they are; `annotations` is empty on an invalid run
|
|
93
|
+
* or when none are selected, and the dropped pair is empty unless
|
|
94
|
+
* irrelevant records were retained (verbose demand).
|
|
95
|
+
*/
|
|
96
|
+
export interface ResultUnits {
|
|
97
|
+
errors: ErrorUnit[];
|
|
98
|
+
droppedErrors: ErrorUnit[];
|
|
99
|
+
annotations: AnnotationUnit[];
|
|
100
|
+
droppedAnnotations: AnnotationUnit[];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Assembles a {@link Result} from the flat surface and, when the demand
|
|
104
|
+
* built one, the located tree. `root` is required whenever
|
|
105
|
+
* `demand.tracing`; `rootLocation` is the root schema's canonical location
|
|
106
|
+
* (the `basic` document's own).
|
|
107
|
+
*/
|
|
108
|
+
export declare function assembleResult(demand: OutputDemand, valid: boolean, units: ResultUnits, root: RenderNode | null, rootLocation: string, trace: boolean): Result;
|
|
109
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"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"}
|
package/dist/result.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Result assembly (ADR 0003): the option checks that admit or reject a
|
|
2
|
+
// combination of controls before any evaluation, and the assembly of a
|
|
3
|
+
// Result from the flat surface and the located tree. Both tiers use it —
|
|
4
|
+
// the interpreter after rendering its records, a compiled evaluator after
|
|
5
|
+
// recording its tree — so presence rules and key order have one owner.
|
|
6
|
+
import { renderBasic, renderDetailed, renderHierarchical, renderList, renderTrace, renderVerbose, } from "./output.js";
|
|
7
|
+
const OUTPUT_FORMATS = new Set([
|
|
8
|
+
"flag",
|
|
9
|
+
"basic",
|
|
10
|
+
"detailed",
|
|
11
|
+
"verbose",
|
|
12
|
+
"list",
|
|
13
|
+
"hierarchical",
|
|
14
|
+
]);
|
|
15
|
+
/** Thrown by `evaluate` for an unsupported combination of output options (ADR 0003: no silent no-ops). */
|
|
16
|
+
export class OutputOptionsError extends Error {
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Every combination of controls is supported or rejected here, before any
|
|
20
|
+
* evaluation (ADR 0003).
|
|
21
|
+
*/
|
|
22
|
+
export function resolveOutputDemand(options) {
|
|
23
|
+
const format = options.output ?? "flag";
|
|
24
|
+
if (!OUTPUT_FORMATS.has(format)) {
|
|
25
|
+
throw new OutputOptionsError(`unknown output format '${format}'`);
|
|
26
|
+
}
|
|
27
|
+
const annotations = options.annotations ?? false;
|
|
28
|
+
if (format === "flag") {
|
|
29
|
+
const requested = [
|
|
30
|
+
["verbose", options.verbose === true],
|
|
31
|
+
["annotations", annotations !== false],
|
|
32
|
+
["errorParams", options.errorParams === true],
|
|
33
|
+
["positions", options.positions === true],
|
|
34
|
+
["trace", options.trace === true],
|
|
35
|
+
];
|
|
36
|
+
for (const [name, on] of requested) {
|
|
37
|
+
if (on) {
|
|
38
|
+
throw new OutputOptionsError(`'${name}' has no effect with output "flag", which carries no ` +
|
|
39
|
+
`records (the minimal level); choose "basic" or another format`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (options.verbose === true &&
|
|
44
|
+
(format === "basic" || format === "detailed")) {
|
|
45
|
+
throw new OutputOptionsError(`'verbose' does not apply to output "${format}", a relevant-level ` +
|
|
46
|
+
`format by definition (IETF draft-03 §13.4); use "verbose", or ` +
|
|
47
|
+
`"list"/"hierarchical" with verbose: true`);
|
|
48
|
+
}
|
|
49
|
+
if (options.verbose === false && format === "verbose") {
|
|
50
|
+
throw new OutputOptionsError(`output "verbose" is the verbose level by definition; ` +
|
|
51
|
+
`'verbose: false' contradicts it`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
format,
|
|
55
|
+
verbose: format === "verbose" || options.verbose === true,
|
|
56
|
+
tracing: format !== "flag" && (format !== "basic" || options.trace === true),
|
|
57
|
+
annotations,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Assembles a {@link Result} from the flat surface and, when the demand
|
|
62
|
+
* built one, the located tree. `root` is required whenever
|
|
63
|
+
* `demand.tracing`; `rootLocation` is the root schema's canonical location
|
|
64
|
+
* (the `basic` document's own).
|
|
65
|
+
*/
|
|
66
|
+
export function assembleResult(demand, valid, units, root, rootLocation, trace) {
|
|
67
|
+
const result = { valid };
|
|
68
|
+
if (demand.format === "flag")
|
|
69
|
+
return result;
|
|
70
|
+
if (!valid)
|
|
71
|
+
result.errors = units.errors;
|
|
72
|
+
if (valid && demand.annotations !== false) {
|
|
73
|
+
result.annotations = units.annotations;
|
|
74
|
+
}
|
|
75
|
+
if (demand.verbose) {
|
|
76
|
+
result.droppedErrors = units.droppedErrors;
|
|
77
|
+
if (demand.annotations !== false) {
|
|
78
|
+
result.droppedAnnotations = units.droppedAnnotations;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const input = demand.tracing
|
|
82
|
+
? {
|
|
83
|
+
errors: units.errors,
|
|
84
|
+
droppedErrors: units.droppedErrors,
|
|
85
|
+
annotations: units.annotations,
|
|
86
|
+
droppedAnnotations: units.droppedAnnotations,
|
|
87
|
+
root: root,
|
|
88
|
+
}
|
|
89
|
+
: null;
|
|
90
|
+
if (trace)
|
|
91
|
+
result.trace = renderTrace(input.root);
|
|
92
|
+
const irrelevant = demand.verbose ? "mark" : "omit";
|
|
93
|
+
switch (demand.format) {
|
|
94
|
+
case "basic":
|
|
95
|
+
result.outputDocument = renderBasic(valid, rootLocation, units.errors, units.annotations);
|
|
96
|
+
break;
|
|
97
|
+
case "list":
|
|
98
|
+
result.outputDocument = renderList(input, irrelevant);
|
|
99
|
+
break;
|
|
100
|
+
case "hierarchical":
|
|
101
|
+
result.outputDocument = renderHierarchical(input, irrelevant);
|
|
102
|
+
break;
|
|
103
|
+
case "detailed":
|
|
104
|
+
result.outputDocument = renderDetailed(input);
|
|
105
|
+
break;
|
|
106
|
+
case "verbose":
|
|
107
|
+
result.outputDocument = renderVerbose(input);
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=result.js.map
|