ata-validator 1.49.0 → 1.51.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 +19 -4
- package/aot.d.ts +50 -0
- package/aot.mjs +1 -1
- package/bin/ata.js +35 -1
- package/build.d.ts +1 -1
- package/error-runtime.d.ts +24 -0
- package/error-runtime.js +40 -0
- package/error-runtime.mjs +3 -0
- package/index.browser.mjs +14 -5
- package/index.edge.js +14 -0
- package/index.edge.mjs +13 -0
- package/index.js +8 -1014
- package/lib/aot-build.js +386 -69
- package/lib/aot-impl.js +240 -7
- package/lib/codegen-engine.js +1024 -0
- package/lib/error-code-of.js +22 -0
- package/lib/error-runtime-entry.js +85 -0
- package/lib/error-runtime.js +152 -0
- package/lib/error-sort-rank.js +61 -0
- package/lib/interpreter-core.js +1356 -0
- package/lib/interpreter.js +8 -1260
- package/lib/public-api.js +80 -0
- package/lib/schema-order.js +64 -2
- package/lib/schema-runtime-entry.js +45 -0
- package/lib/schema-strip.js +115 -0
- package/lib/tools.mjs +21 -0
- package/lib/validator-core.js +20 -5
- package/lib/version.js +1 -1
- package/package.json +28 -8
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The public names of the package, shared by index.js (with the code
|
|
4
|
+
// generator) and index.edge.js (without it), so the two entries export the
|
|
5
|
+
// same thing.
|
|
6
|
+
const core = require('./validator-core.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// The parts no Validator calls: TypeScript generation, the error renderers,
|
|
11
|
+
// the spec output format, the retry message for language models, the schema
|
|
12
|
+
// description and the suggestion helper. ata-validator/lite leaves them out.
|
|
13
|
+
// Each loads its module on first call. None of them is on the path to a first
|
|
14
|
+
// validated request, and together they were about a sixth of what requiring
|
|
15
|
+
// the package cost.
|
|
16
|
+
function toTypeScript (...a) { return require('./ts-gen').toTypeScript(...a); }
|
|
17
|
+
function renderPretty (...a) { return require('./render-pretty').renderPretty(...a); }
|
|
18
|
+
function renderCompact (...a) { return require('./render-compact').renderCompact(...a); }
|
|
19
|
+
function toOutput (...a) { return require('./output-format').toOutput(...a); }
|
|
20
|
+
function toRetryMessage (...a) { return require('./retry-message').toRetryMessage(...a); }
|
|
21
|
+
function describeSchema (...a) { return require('./describe-schema').describeSchema(...a); }
|
|
22
|
+
function renderJSON (...a) { return require('./render-json').renderJSON(...a); }
|
|
23
|
+
|
|
24
|
+
// Walk a JSON pointer (RFC 6901 escapes) into a data tree. Mirrors the helper
|
|
25
|
+
// inside lib/suggestions.js, kept local to avoid exporting an internal.
|
|
26
|
+
function _walkPointer (root, pointer) {
|
|
27
|
+
if (!pointer) return root;
|
|
28
|
+
const parts = pointer.replace(/^\//, '').split('/').map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'));
|
|
29
|
+
let cur = root;
|
|
30
|
+
for (const p of parts) { if (cur == null) return undefined; cur = cur[p]; }
|
|
31
|
+
return cur;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Post-hoc suggestion enrichment for AOT-compiled validators. The standalone
|
|
35
|
+
// modules do not embed the suggestion engine, so consumers who want
|
|
36
|
+
// suggestions pass the error array through this after validation.
|
|
37
|
+
function attachSuggestions (errors, data) {
|
|
38
|
+
if (!errors) return errors;
|
|
39
|
+
const { suggestFor } = require('./suggestions');
|
|
40
|
+
const { reprValue } = require('./enrich-error');
|
|
41
|
+
for (const e of errors) {
|
|
42
|
+
if (!e || e.suggestion) continue;
|
|
43
|
+
let received = e.received;
|
|
44
|
+
if (received === undefined && data !== undefined) {
|
|
45
|
+
const ptr = e.instancePath != null ? e.instancePath : (e.path || '');
|
|
46
|
+
const raw = _walkPointer(data, ptr);
|
|
47
|
+
if (raw !== undefined || ptr === '') received = reprValue(raw);
|
|
48
|
+
}
|
|
49
|
+
const probe = received !== undefined && e.received === undefined
|
|
50
|
+
? Object.assign({}, e, { received })
|
|
51
|
+
: e;
|
|
52
|
+
const s = suggestFor(probe, data);
|
|
53
|
+
if (s) e.suggestion = s;
|
|
54
|
+
}
|
|
55
|
+
// AOT modules import nothing, so this is their only route to a frame. The
|
|
56
|
+
// caller holds the original object and ran no preprocessing through here.
|
|
57
|
+
require('./diagnostic-source').setDiagnosticSource(errors, { data, mutatesInput: false });
|
|
58
|
+
return errors;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
Validator: core.Validator,
|
|
63
|
+
compile: core.compile,
|
|
64
|
+
validate: core.validate,
|
|
65
|
+
validateAsync: core.validateAsync,
|
|
66
|
+
parseAsync: core.parseAsync,
|
|
67
|
+
version: core.version,
|
|
68
|
+
createPaddedBuffer: core.createPaddedBuffer,
|
|
69
|
+
SIMDJSON_PADDING: core.SIMDJSON_PADDING,
|
|
70
|
+
parseJSON: core.parseJSON,
|
|
71
|
+
toTypeScript,
|
|
72
|
+
defineSchema: core.defineSchema,
|
|
73
|
+
renderPretty,
|
|
74
|
+
renderCompact,
|
|
75
|
+
toOutput,
|
|
76
|
+
toRetryMessage,
|
|
77
|
+
describeSchema,
|
|
78
|
+
renderJSON,
|
|
79
|
+
attachSuggestions, // internal: used by the renderers; not public API
|
|
80
|
+
};
|
package/lib/schema-order.js
CHANGED
|
@@ -57,17 +57,53 @@ function rankFor(rootSchema, schemaPath) {
|
|
|
57
57
|
return rank;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// The documents a root's references reach beyond itself, id to schema, from
|
|
61
|
+
// the validators that own the root (the `schemas` option, addSchema) or a
|
|
62
|
+
// schema module's registry. Several validators of one root schema register
|
|
63
|
+
// their maps into one; an id that two of them give different schemas makes the
|
|
64
|
+
// root resolve nothing outside itself, as it did before any was registered.
|
|
65
|
+
const _documents = new WeakMap();
|
|
66
|
+
const CONFLICT = new Map();
|
|
67
|
+
function registerDocuments(rootSchema, map) {
|
|
68
|
+
if (rootSchema === null || typeof rootSchema !== 'object' || !map || map.size === 0) return;
|
|
69
|
+
const had = _documents.get(rootSchema);
|
|
70
|
+
if (had === CONFLICT) return;
|
|
71
|
+
if (had === undefined) { _documents.set(rootSchema, new Map(map)); _rankCache.delete(rootSchema); return; }
|
|
72
|
+
let added = false;
|
|
73
|
+
for (const [id, doc] of map) {
|
|
74
|
+
const cur = had.get(id);
|
|
75
|
+
if (cur === undefined) { had.set(id, doc); added = true; } else if (cur !== doc) { _documents.set(rootSchema, CONFLICT); _rankCache.delete(rootSchema); return; }
|
|
76
|
+
}
|
|
77
|
+
if (added) _rankCache.delete(rootSchema);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function withoutEmptyFragment(uri) {
|
|
81
|
+
return uri.endsWith('#') ? uri.slice(0, -1) : uri;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function resolveUri(ref, base) {
|
|
85
|
+
try { return base ? new URL(ref, base).href : new URL(ref).href; } catch { return null; }
|
|
86
|
+
}
|
|
87
|
+
|
|
60
88
|
function computeRank(rootSchema, schemaPath) {
|
|
61
89
|
const rank = [];
|
|
62
90
|
let node = rootSchema;
|
|
63
91
|
let start = 1;
|
|
64
92
|
let hops = 0;
|
|
93
|
+
const docs = _documents.get(rootSchema);
|
|
94
|
+
// The document the walk is in and the base URI references resolve against,
|
|
95
|
+
// for following a reference into another document.
|
|
96
|
+
let doc = rootSchema;
|
|
97
|
+
// A root without an $id can still name another document by absolute URI.
|
|
98
|
+
const follow = docs !== undefined && docs !== CONFLICT;
|
|
99
|
+
let base = follow && typeof rootSchema.$id === 'string' ? resolveUri(rootSchema.$id, null) : null;
|
|
65
100
|
while (start <= schemaPath.length) {
|
|
66
101
|
let end = schemaPath.indexOf('/', start);
|
|
67
102
|
if (end < 0) end = schemaPath.length;
|
|
68
103
|
if (end === start) { start = end + 1; continue; }
|
|
69
104
|
const seg = unescapePointerSegment(schemaPath.slice(start, end));
|
|
70
105
|
if (node == null || typeof node !== 'object') break;
|
|
106
|
+
if (follow && node !== doc && !Array.isArray(node) && typeof node.$id === 'string' && node.$id[0] !== '#') base = resolveUri(node.$id, base);
|
|
71
107
|
if (Array.isArray(node)) {
|
|
72
108
|
const idx = Number(seg);
|
|
73
109
|
if (!Number.isInteger(idx) || idx < 0 || idx >= node.length) break;
|
|
@@ -80,7 +116,11 @@ function computeRank(rootSchema, schemaPath) {
|
|
|
80
116
|
// naming it. Ranking the rest inside the target, as if the target sat
|
|
81
117
|
// under the `$ref` key, orders errors behind a reference by the
|
|
82
118
|
// target's declaration order, as they are ordered inline.
|
|
83
|
-
|
|
119
|
+
let target = hops < 64 ? localTarget(doc, node) : null;
|
|
120
|
+
if (target === null && hops < 64 && follow) {
|
|
121
|
+
const remote = remoteTarget(docs, base, node);
|
|
122
|
+
if (remote !== null) { target = remote.node; doc = remote.doc; base = remote.base; }
|
|
123
|
+
}
|
|
84
124
|
if (target === null) break;
|
|
85
125
|
hops++;
|
|
86
126
|
rank.push(keyIndex(node, '$ref'));
|
|
@@ -95,6 +135,28 @@ function computeRank(rootSchema, schemaPath) {
|
|
|
95
135
|
return rank;
|
|
96
136
|
}
|
|
97
137
|
|
|
138
|
+
// The schema a node's `$ref` names in a registered document: { node, doc,
|
|
139
|
+
// base }, or null when it names none (an anchor, an unknown document).
|
|
140
|
+
function remoteTarget(docs, base, node) {
|
|
141
|
+
const ref = node.$ref;
|
|
142
|
+
if (typeof ref !== 'string' || ref.charCodeAt(0) === 35) return null;
|
|
143
|
+
const abs = resolveUri(ref, base);
|
|
144
|
+
if (abs === null) return null;
|
|
145
|
+
const hash = abs.indexOf('#');
|
|
146
|
+
const uri = hash < 0 ? abs : abs.slice(0, hash);
|
|
147
|
+
let target = docs.get(uri);
|
|
148
|
+
if (target === undefined) target = docs.get(uri + '#');
|
|
149
|
+
if (target === undefined) {
|
|
150
|
+
for (const [id, s] of docs) if (withoutEmptyFragment(resolveUri(id, null) || '') === uri) { target = s; break; }
|
|
151
|
+
}
|
|
152
|
+
if (target === null || typeof target !== 'object') return null;
|
|
153
|
+
const frag = hash < 0 ? '' : abs.slice(hash + 1);
|
|
154
|
+
if (frag === '') return { node: target, doc: target, base: uri };
|
|
155
|
+
if (frag.charCodeAt(0) !== 47) return null;
|
|
156
|
+
const t = localTarget(target, { $ref: '#' + frag });
|
|
157
|
+
return t === null ? null : { node: t, doc: target, base: uri };
|
|
158
|
+
}
|
|
159
|
+
|
|
98
160
|
// The schema a node's `$ref` names, when it is a pointer into this document.
|
|
99
161
|
function localTarget(rootSchema, node) {
|
|
100
162
|
const ref = node.$ref;
|
|
@@ -191,4 +253,4 @@ function ordinalFor(rootSchema, schemaPath) {
|
|
|
191
253
|
const _missCache = new WeakMap();
|
|
192
254
|
const MISS_CACHE_LIMIT = 4096;
|
|
193
255
|
|
|
194
|
-
module.exports = { rankFor, ordinalFor, unescapePointerSegment };
|
|
256
|
+
module.exports = { rankFor, ordinalFor, unescapePointerSegment, registerDocuments };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The runtime a schema module (`ata build --mode schema`) imports: the verdict
|
|
4
|
+
// and the errors both come from the interpreted engine walking the embedded
|
|
5
|
+
// schema, so a module is its schema and a few lines. Smaller and quicker to
|
|
6
|
+
// load than generated code, slower per check once warm; see docs/API.md.
|
|
7
|
+
// One interpreter per schema answers both, so the schema is prepared once.
|
|
8
|
+
// It loads lib/interpreter.js, which brings the plan compiler for schemas
|
|
9
|
+
// used often (TIER in lib/interpreter-core.js).
|
|
10
|
+
const { createInterpreter } = require('./interpreter');
|
|
11
|
+
const { errorsOf, interpreterOptions } = require('./error-runtime-entry');
|
|
12
|
+
|
|
13
|
+
// A registry is the array of schemas a build writes beside schema modules
|
|
14
|
+
// whose schemas reference each other by `$id` (ata-registry.mjs). It becomes
|
|
15
|
+
// one Map, id to schema, shared by every module of the build.
|
|
16
|
+
const _maps = new WeakMap();
|
|
17
|
+
function registryMap(registry) {
|
|
18
|
+
let map = _maps.get(registry);
|
|
19
|
+
if (map === undefined) {
|
|
20
|
+
map = new Map();
|
|
21
|
+
for (const s of registry) map.set(s.$id, s);
|
|
22
|
+
_maps.set(registry, map);
|
|
23
|
+
}
|
|
24
|
+
return map;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// options.registry and options.id: the module's schema is the registry entry
|
|
28
|
+
// with that `$id`, and its references resolve against the registry.
|
|
29
|
+
function createValidator(schema, codeOf, options) {
|
|
30
|
+
const opts = interpreterOptions(options);
|
|
31
|
+
if (options && options.registry) {
|
|
32
|
+
const map = registryMap(options.registry);
|
|
33
|
+
if (schema === null || schema === undefined) schema = map.get(options.id);
|
|
34
|
+
opts.schemaMap = map;
|
|
35
|
+
opts.flat = false;
|
|
36
|
+
require('./schema-order').registerDocuments(schema, map);
|
|
37
|
+
}
|
|
38
|
+
const interp = createInterpreter(schema, opts);
|
|
39
|
+
return {
|
|
40
|
+
isValid: (data) => interp.isValid(data),
|
|
41
|
+
errors: (data) => errorsOf(interp, schema, codeOf, data),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { createValidator };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// A copy of a schema without the keywords that only describe it (title,
|
|
4
|
+
// description, examples and the like), for a compact module that embeds its
|
|
5
|
+
// schema so the shared error runtime can walk it. Validation never reads
|
|
6
|
+
// these, and in a typical published schema they are most of the bytes.
|
|
7
|
+
//
|
|
8
|
+
// Only schema positions are touched. An `enum`, a `const` or any keyword this
|
|
9
|
+
// file does not know is copied as it is, so a value that happens to hold a
|
|
10
|
+
// "description" key keeps it. If a local `$ref` points through a keyword that
|
|
11
|
+
// would be removed, nothing is removed: the reference has to land where it
|
|
12
|
+
// did.
|
|
13
|
+
|
|
14
|
+
const DROP = new Set([
|
|
15
|
+
'title', 'description', '$comment', 'examples', 'default', 'deprecated',
|
|
16
|
+
'readOnly', 'writeOnly', 'markdownDescription', 'deprecationMessage',
|
|
17
|
+
'enumDescriptions', 'markdownEnumDescriptions', 'defaultSnippets',
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
const SINGLE = new Set([
|
|
21
|
+
'additionalProperties', 'contains', 'propertyNames', 'if', 'then', 'else', 'not',
|
|
22
|
+
'items', 'unevaluatedItems', 'unevaluatedProperties', 'additionalItems', 'contentSchema',
|
|
23
|
+
]);
|
|
24
|
+
const MAPS = new Set(['$defs', 'definitions', 'properties', 'patternProperties', 'dependentSchemas']);
|
|
25
|
+
const LISTS = new Set(['allOf', 'anyOf', 'oneOf', 'prefixItems']);
|
|
26
|
+
|
|
27
|
+
function dropped(key) {
|
|
28
|
+
return DROP.has(key) || key.startsWith('x-');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function setOwn(o, k, v) {
|
|
32
|
+
// A key named __proto__ has to stay an own property.
|
|
33
|
+
if (k === '__proto__') Object.defineProperty(o, k, { value: v, enumerable: true, writable: true, configurable: true });
|
|
34
|
+
else o[k] = v;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function unescape(seg) {
|
|
38
|
+
return seg.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// True when some local reference walks through a key that would be dropped.
|
|
42
|
+
function refsIntoDropped(node, seen) {
|
|
43
|
+
if (node === null || typeof node !== 'object') return false;
|
|
44
|
+
if (seen.has(node)) return false;
|
|
45
|
+
seen.add(node);
|
|
46
|
+
if (Array.isArray(node)) {
|
|
47
|
+
for (const x of node) if (refsIntoDropped(x, seen)) return true;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
for (const k of ['$ref', '$dynamicRef', '$recursiveRef']) {
|
|
51
|
+
const r = node[k];
|
|
52
|
+
if (typeof r !== 'string') continue;
|
|
53
|
+
const hash = r.indexOf('#');
|
|
54
|
+
if (hash < 0) continue;
|
|
55
|
+
let frag;
|
|
56
|
+
try { frag = decodeURIComponent(r.slice(hash + 1)); } catch { return true; }
|
|
57
|
+
if (!frag.startsWith('/')) continue;
|
|
58
|
+
for (const seg of frag.slice(1).split('/')) if (dropped(unescape(seg))) return true;
|
|
59
|
+
}
|
|
60
|
+
for (const k of Object.keys(node)) if (refsIntoDropped(node[k], seen)) return true;
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// keepTitle: the node is a branch of anyOf or oneOf, whose title names the
|
|
65
|
+
// branch in the collapsed error (params.closestName).
|
|
66
|
+
function stripSchema(node, keepTitle) {
|
|
67
|
+
if (node === null || typeof node !== 'object' || Array.isArray(node)) return node;
|
|
68
|
+
const out = {};
|
|
69
|
+
for (const k of Object.keys(node)) {
|
|
70
|
+
if (dropped(k) && !(keepTitle === true && k === 'title')) continue;
|
|
71
|
+
const v = node[k];
|
|
72
|
+
if (SINGLE.has(k)) {
|
|
73
|
+
setOwn(out, k, Array.isArray(v) ? v.map((x) => stripSchema(x, false)) : stripSchema(v, false));
|
|
74
|
+
} else if (MAPS.has(k) && v !== null && typeof v === 'object' && !Array.isArray(v)) {
|
|
75
|
+
const m = {};
|
|
76
|
+
for (const name of Object.keys(v)) setOwn(m, name, stripSchema(v[name], false));
|
|
77
|
+
setOwn(out, k, m);
|
|
78
|
+
} else if (LISTS.has(k) && Array.isArray(v)) {
|
|
79
|
+
const branches = k === 'anyOf' || k === 'oneOf';
|
|
80
|
+
setOwn(out, k, v.map((x) => stripSchema(x, branches)));
|
|
81
|
+
} else if (k === 'dependencies' && v !== null && typeof v === 'object' && !Array.isArray(v)) {
|
|
82
|
+
const m = {};
|
|
83
|
+
for (const name of Object.keys(v)) setOwn(m, name, Array.isArray(v[name]) ? v[name] : stripSchema(v[name], false));
|
|
84
|
+
setOwn(out, k, m);
|
|
85
|
+
} else if (k === 'propertyDependencies' && v !== null && typeof v === 'object' && !Array.isArray(v)) {
|
|
86
|
+
const m = {};
|
|
87
|
+
for (const name of Object.keys(v)) {
|
|
88
|
+
const inner = v[name];
|
|
89
|
+
if (inner === null || typeof inner !== 'object' || Array.isArray(inner)) { setOwn(m, name, inner); continue; }
|
|
90
|
+
const mi = {};
|
|
91
|
+
for (const val of Object.keys(inner)) setOwn(mi, val, stripSchema(inner[val], false));
|
|
92
|
+
setOwn(m, name, mi);
|
|
93
|
+
}
|
|
94
|
+
setOwn(out, k, m);
|
|
95
|
+
} else {
|
|
96
|
+
setOwn(out, k, v);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// A compact or schema module strips its schema three times on the way out
|
|
103
|
+
// (the reference check, the module, the flat-index check): once per schema
|
|
104
|
+
// object. A validator's schema object does not change after it compiles.
|
|
105
|
+
const _stripped = new WeakMap();
|
|
106
|
+
function stripAnnotations(schema) {
|
|
107
|
+
if (schema === null || typeof schema !== 'object') return schema;
|
|
108
|
+
const hit = _stripped.get(schema);
|
|
109
|
+
if (hit !== undefined) return hit;
|
|
110
|
+
const out = refsIntoDropped(schema, new Set()) ? schema : stripSchema(schema, false);
|
|
111
|
+
_stripped.set(schema, out);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { stripAnnotations };
|
package/lib/tools.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// The package's tools as ES modules, one import each, for the entries a
|
|
2
|
+
// bundler reads (index.browser.mjs, index.edge.mjs): an application that
|
|
3
|
+
// imports only Validator leaves TypeScript generation, the renderers, the
|
|
4
|
+
// output format, the retry message and the schema description out of its
|
|
5
|
+
// bundle. Through index.js they load on first call instead, which a bundler
|
|
6
|
+
// cannot see, so it kept all of them.
|
|
7
|
+
import tsGen from './ts-gen.js';
|
|
8
|
+
import renderPrettyMod from './render-pretty.js';
|
|
9
|
+
import renderCompactMod from './render-compact.js';
|
|
10
|
+
import outputFormat from './output-format.js';
|
|
11
|
+
import retryMessage from './retry-message.js';
|
|
12
|
+
import describe from './describe-schema.js';
|
|
13
|
+
import renderJsonMod from './render-json.js';
|
|
14
|
+
|
|
15
|
+
export function toTypeScript (...a) { return tsGen.toTypeScript(...a); }
|
|
16
|
+
export function renderPretty (...a) { return renderPrettyMod.renderPretty(...a); }
|
|
17
|
+
export function renderCompact (...a) { return renderCompactMod.renderCompact(...a); }
|
|
18
|
+
export function toOutput (...a) { return outputFormat.toOutput(...a); }
|
|
19
|
+
export function toRetryMessage (...a) { return retryMessage.toRetryMessage(...a); }
|
|
20
|
+
export function describeSchema (...a) { return describe.describeSchema(...a); }
|
|
21
|
+
export function renderJSON (...a) { return renderJsonMod.renderJSON(...a); }
|
package/lib/validator-core.js
CHANGED
|
@@ -25,6 +25,14 @@ function _registerCodegen(engine) {
|
|
|
25
25
|
_codegen = engine;
|
|
26
26
|
({ compileToJS, compileToJSCodegen, compileToJSCodegenWithErrors, compileToJSCombined } = engine.jsCompiler);
|
|
27
27
|
}
|
|
28
|
+
// The ahead-of-time loaders without the code generator: the edge entry
|
|
29
|
+
// (index.edge.js) registers lib/aot.browser.js here, so modules written by
|
|
30
|
+
// `ata build` or Validator.bundle() load where generated code cannot run.
|
|
31
|
+
// The emitters stay out, as they do in a browser bundle of the full package.
|
|
32
|
+
let _aotLoader = null;
|
|
33
|
+
function _registerAot(load) {
|
|
34
|
+
_aotLoader = load;
|
|
35
|
+
}
|
|
28
36
|
const { draftCode, normalizeDraft2019, normalizeDraft7, normalizeNullable, normalizeExclusiveBounds, stripFormatAssertions } = require("./draft7");
|
|
29
37
|
const { enabledKeywords, stripDisabledKeywords } = require("./vocabularies");
|
|
30
38
|
const { needsNormalization } = require("./schema-scan");
|
|
@@ -856,6 +864,9 @@ class Validator {
|
|
|
856
864
|
if (this._initialized) return;
|
|
857
865
|
this._ensureVocabularies();
|
|
858
866
|
this._initialized = true;
|
|
867
|
+
// Errors behind a reference into a registered document are ordered as
|
|
868
|
+
// they would be inline: the ordering follows the reference there.
|
|
869
|
+
if (this._schemaMap && this._schemaMap.size > 0) require('./schema-order').registerDocuments(this._schemaObj, this._schemaMap);
|
|
859
870
|
|
|
860
871
|
const schemaObj = this._schemaObj;
|
|
861
872
|
const options = this._options;
|
|
@@ -1599,7 +1610,7 @@ class Validator {
|
|
|
1599
1610
|
static fromStandalone(mod, schema, opts) {
|
|
1600
1611
|
// It loads what Validator.bundleStandalone() writes, and compiles an error
|
|
1601
1612
|
// function when the module carries none, so it goes with those methods.
|
|
1602
|
-
if (_codegen === null) throw new TypeError('Validator.fromStandalone is not part of ata-validator/lite, like the bundle methods it loads for. Import it from ata-validator, or import a module from `ata build` directly.');
|
|
1613
|
+
if (_codegen === null && _aotLoader === null) throw new TypeError('Validator.fromStandalone is not part of ata-validator/lite, like the bundle methods it loads for. Import it from ata-validator, or import a module from `ata build` directly.');
|
|
1603
1614
|
const options = opts || {};
|
|
1604
1615
|
const schemaObj = typeof schema === "string" ? JSON.parse(schema) : schema;
|
|
1605
1616
|
|
|
@@ -1635,7 +1646,9 @@ class Validator {
|
|
|
1635
1646
|
});
|
|
1636
1647
|
if (mod.errFn) {
|
|
1637
1648
|
errFn = (d) => mod.errFn(d, true);
|
|
1638
|
-
} else {
|
|
1649
|
+
} else if (compileToJSCodegenWithErrors !== undefined) {
|
|
1650
|
+
// Without the code generator (the edge entry) a module that carries no
|
|
1651
|
+
// error function reports the stub above.
|
|
1639
1652
|
const jsErrFn = compileToJSCodegenWithErrors(schemaObj);
|
|
1640
1653
|
if (jsErrFn) {
|
|
1641
1654
|
try {
|
|
@@ -1783,8 +1796,9 @@ function version() {
|
|
|
1783
1796
|
// generated module shapes; browser bundles get `lib/aot.browser.js` (a stub
|
|
1784
1797
|
// that throws) via the package.json `browser` field.
|
|
1785
1798
|
function _aot() {
|
|
1786
|
-
if (_codegen
|
|
1787
|
-
return
|
|
1799
|
+
if (_codegen !== null) return _codegen.aot();
|
|
1800
|
+
if (_aotLoader !== null) return _aotLoader();
|
|
1801
|
+
throw new TypeError('The ahead-of-time bundle methods are not part of ata-validator/lite. Import them from ata-validator.');
|
|
1788
1802
|
}
|
|
1789
1803
|
Validator.bundle = function (schemas, opts) {
|
|
1790
1804
|
return _aot().bundle(Validator, schemas, opts);
|
|
@@ -2195,7 +2209,7 @@ function _buildParse(self) {
|
|
|
2195
2209
|
// isValidObject, which runs them, and a property they check with instanceof
|
|
2196
2210
|
// is carried over as it is (see clone-emit).
|
|
2197
2211
|
const extended = self._verdictTail !== null || self._validateTail !== null;
|
|
2198
|
-
if (_codegen === null) return decline('
|
|
2212
|
+
if (_codegen === null) return decline('this entry has no code generator to build the copy with', 'Use validate(); a valid result carries the input as it is.');
|
|
2199
2213
|
return _codegen.buildParse(self, decline, extended);
|
|
2200
2214
|
}
|
|
2201
2215
|
|
|
@@ -2369,5 +2383,6 @@ module.exports = {
|
|
|
2369
2383
|
// How an entry registers the code generator. Not enumerable, so the exported
|
|
2370
2384
|
// surface of `require('ata-validator')` is what it was.
|
|
2371
2385
|
Object.defineProperty(module.exports, '_registerCodegen', { value: _registerCodegen, enumerable: false });
|
|
2386
|
+
Object.defineProperty(module.exports, '_registerAot', { value: _registerAot, enumerable: false });
|
|
2372
2387
|
// What the compiled paths in index.js need from this module.
|
|
2373
2388
|
Object.defineProperty(module.exports, '_internals', { value: { _jsonSyntaxRejection, ABORT_EARLY_RESULT, HYBRID_TIER_CALLS, SIMDJSON_THRESHOLD, VALID_RESULT, _bindEntry, _bindVerdict, _compileCache, _compileCacheSet, _mustReject, _rememberInstance, _verboseWrap, compileCacheKey, getNative, isV1Dialect, resolveSchemaByPath }, enumerable: false });
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.51.0",
|
|
4
4
|
"description": "JSON Schema validator that compiles to plain JavaScript, still runs where code generation is blocked, and can be compiled away at build time. Passes the full official test suite.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
"types": "index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"workerd": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"import": "./index.edge.mjs",
|
|
14
|
+
"require": "./index.edge.js"
|
|
15
|
+
},
|
|
16
|
+
"edge-light": {
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"import": "./index.edge.mjs",
|
|
19
|
+
"require": "./index.edge.js"
|
|
20
|
+
},
|
|
11
21
|
"types": "./index.d.ts",
|
|
12
22
|
"browser": {
|
|
13
23
|
"import": "./index.browser.mjs",
|
|
@@ -54,6 +64,11 @@
|
|
|
54
64
|
"import": "./lite.mjs",
|
|
55
65
|
"require": "./lite.js"
|
|
56
66
|
},
|
|
67
|
+
"./error-runtime": {
|
|
68
|
+
"types": "./error-runtime.d.ts",
|
|
69
|
+
"import": "./error-runtime.mjs",
|
|
70
|
+
"require": "./error-runtime.js"
|
|
71
|
+
},
|
|
57
72
|
"./package.json": "./package.json"
|
|
58
73
|
},
|
|
59
74
|
"sideEffects": false,
|
|
@@ -123,6 +138,8 @@
|
|
|
123
138
|
"index.mjs",
|
|
124
139
|
"index.node.mjs",
|
|
125
140
|
"index.browser.mjs",
|
|
141
|
+
"index.edge.js",
|
|
142
|
+
"index.edge.mjs",
|
|
126
143
|
"index.d.ts",
|
|
127
144
|
"aot.js",
|
|
128
145
|
"aot.mjs",
|
|
@@ -147,18 +164,21 @@
|
|
|
147
164
|
"lite.js",
|
|
148
165
|
"lite.mjs",
|
|
149
166
|
"lite.d.ts",
|
|
167
|
+
"error-runtime.js",
|
|
168
|
+
"error-runtime.mjs",
|
|
169
|
+
"error-runtime.d.ts",
|
|
150
170
|
"bin/",
|
|
151
171
|
"README.md",
|
|
152
172
|
"LICENSE"
|
|
153
173
|
],
|
|
154
174
|
"optionalDependencies": {
|
|
155
|
-
"@ata-validator/native-darwin-arm64": "1.
|
|
156
|
-
"@ata-validator/native-darwin-x64": "1.
|
|
157
|
-
"@ata-validator/native-linux-arm64-gnu": "1.
|
|
158
|
-
"@ata-validator/native-linux-arm64-musl": "1.
|
|
159
|
-
"@ata-validator/native-linux-x64-gnu": "1.
|
|
160
|
-
"@ata-validator/native-linux-x64-musl": "1.
|
|
161
|
-
"@ata-validator/native-win32-x64": "1.
|
|
175
|
+
"@ata-validator/native-darwin-arm64": "1.51.0",
|
|
176
|
+
"@ata-validator/native-darwin-x64": "1.51.0",
|
|
177
|
+
"@ata-validator/native-linux-arm64-gnu": "1.51.0",
|
|
178
|
+
"@ata-validator/native-linux-arm64-musl": "1.51.0",
|
|
179
|
+
"@ata-validator/native-linux-x64-gnu": "1.51.0",
|
|
180
|
+
"@ata-validator/native-linux-x64-musl": "1.51.0",
|
|
181
|
+
"@ata-validator/native-win32-x64": "1.51.0"
|
|
162
182
|
},
|
|
163
183
|
"peerDependencies": {
|
|
164
184
|
"yaml": "^2.0.0"
|