diff --git a/DEPENDENCIES b/DEPENDENCIES
index 733f3f3c..17cd1816 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -1,7 +1,7 @@
vendorpull https://github.com/sourcemeta/vendorpull 1dcbac42809cf87cb5b045106b863e17ad84ba02
uwebsockets https://github.com/uNetworking/uWebSockets v20.76.0
core https://github.com/sourcemeta/core 94b0c4860231adfb18bb8d16951089f95bc3cc4c
-blaze https://github.com/sourcemeta/blaze 307e9fd12a1fa10987e55e1da8e8a7b9e6ea5171
+blaze https://github.com/sourcemeta/blaze 83e2458856b934aa7995c44da36ab09152bdfc8d
jsonbinpack https://github.com/sourcemeta/jsonbinpack 2fe6502cad30e539de271d2e58ee7f8432b95a4d
hydra https://github.com/sourcemeta/hydra 8cbbe5739c31d282a822dece8ed36ef0120cccbe
codegen https://github.com/sourcemeta/codegen 8799edb6a88b37b138c360936dd358389c2a3390
diff --git a/vendor/blaze/ports/javascript/LICENSE b/vendor/blaze/ports/javascript/LICENSE
new file mode 100644
index 00000000..0a041280
--- /dev/null
+++ b/vendor/blaze/ports/javascript/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/blaze/ports/javascript/README.md b/vendor/blaze/ports/javascript/README.md
new file mode 100644
index 00000000..28a5091b
--- /dev/null
+++ b/vendor/blaze/ports/javascript/README.md
@@ -0,0 +1,69 @@
+# @sourcemeta/blaze
+
+[](https://www.npmjs.com/package/@sourcemeta/blaze)
+[](https://www.npmjs.com/package/@sourcemeta/blaze)
+[](https://github.com/sourcemeta/blaze/graphs/contributors/)
+
+A pure JavaScript port of the evaluator from
+[Blaze](https://github.com/sourcemeta/blaze), a high-performance
+C++ JSON Schema validator. Zero dependencies. Supports Draft 4,
+Draft 6, Draft 7, 2019-09, and 2020-12 with schema-specific code
+generation for near-native speed.
+
+## Install
+
+```sh
+npm install --save @sourcemeta/blaze
+```
+
+## Usage
+
+Blaze evaluates pre-compiled schema templates. Compile your JSON
+Schema using the
+[jsonschema](https://github.com/sourcemeta/jsonschema) CLI
+([compile docs](https://github.com/sourcemeta/jsonschema/blob/main/docs/compile.markdown)):
+
+```sh
+npm install --global @sourcemeta/jsonschema
+
+cat > schema.json <<'EOF'
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "age": { "type": "integer" }
+ },
+ "required": [ "name" ]
+}
+EOF
+
+jsonschema compile schema.json --fast > template.json
+```
+
+Then validate instances:
+
+```javascript
+import { readFileSync } from "node:fs";
+import { Blaze } from "@sourcemeta/blaze";
+
+const template =
+ JSON.parse(readFileSync("template.json", "utf-8"));
+const evaluator = new Blaze(template);
+
+// true or false
+console.log(evaluator.validate({ name: "John", age: 30 }));
+```
+
+With an evaluation callback for tracing:
+
+```javascript
+const instance = { name: "John", age: 30 };
+const result = evaluator.validate(instance,
+ (type, valid, instruction,
+ evaluatePath, instanceLocation, annotation) => {
+ console.log(type, evaluatePath,
+ instanceLocation, valid);
+ });
+console.log(result); // true or false
+```
diff --git a/vendor/blaze/ports/javascript/index.d.mts b/vendor/blaze/ports/javascript/index.d.mts
new file mode 100644
index 00000000..9f151364
--- /dev/null
+++ b/vendor/blaze/ports/javascript/index.d.mts
@@ -0,0 +1,15 @@
+export type Template = Array;
+
+export type EvaluationCallback = (
+ type: "pre" | "post",
+ valid: boolean,
+ instruction: unknown[],
+ evaluatePath: string,
+ instanceLocation: string,
+ annotation: unknown
+) => void;
+
+export declare class Blaze {
+ constructor(template: Template);
+ validate(instance: unknown, callback?: EvaluationCallback): boolean;
+}
diff --git a/vendor/blaze/ports/javascript/index.mjs b/vendor/blaze/ports/javascript/index.mjs
index 5d7a6671..5cdccfd1 100644
--- a/vendor/blaze/ports/javascript/index.mjs
+++ b/vendor/blaze/ports/javascript/index.mjs
@@ -1,9 +1,11 @@
+const JSON_VERSION = 1;
const DEPTH_LIMIT = 300;
const ANNOTATION_EMIT = 44;
const ANNOTATION_TO_PARENT = 45;
const ANNOTATION_BASENAME_TO_PARENT = 46;
const CONTROL_GROUP_START = 85;
const CONTROL_EVALUATE_END = 89;
+const URI_REGEX = /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/;
function buildJsonPointer(tokens, length) {
if (length === 0) return '';
@@ -42,9 +44,14 @@ function isIntegral(value) {
}
function resolveInstance(instance, relativeInstanceLocation) {
- if (relativeInstanceLocation.length === 0) return instance;
+ const length = relativeInstanceLocation.length;
+ if (length === 0) return instance;
+ if (length === 1) {
+ if (instance === undefined || instance === null) return undefined;
+ return instance[relativeInstanceLocation[0]];
+ }
let current = instance;
- for (let index = 0; index < relativeInstanceLocation.length; index++) {
+ for (let index = 0; index < length; index++) {
if (current === undefined || current === null) return undefined;
current = current[relativeInstanceLocation[index]];
}
@@ -110,11 +117,27 @@ function prepareInstruction(instruction) {
}
}
+ const opcode = instruction[0];
+ if (opcode === 27 && Array.isArray(instruction[5])) {
+ const values = instruction[5];
+ let allPrimitive = true;
+ for (let index = 0; index < values.length; index++) {
+ const element = values[index];
+ if (element !== null && typeof element === 'object') {
+ allPrimitive = false;
+ break;
+ }
+ }
+ if (allPrimitive) {
+ instruction[5] = { set: new Set(values), values, primitive: true };
+ }
+ }
+
if (instruction.length < 7) {
instruction.push(undefined);
}
- instruction.push(handlers[instruction[0]] || null);
+ instruction.push(handlers[opcode] || null);
const children = instruction[6];
if (children) {
@@ -172,7 +195,7 @@ function collectAnchorNamesFromInstructions(instructions, result) {
}
function compile(template) {
- const targets = template[2];
+ const targets = template[3];
for (let targetIndex = 0; targetIndex < targets.length; targetIndex++) {
const target = targets[targetIndex];
for (let index = 0; index < target.length; index++) {
@@ -185,14 +208,14 @@ function compile(template) {
}
const labels = new Map();
- const rawLabels = template[3];
+ const rawLabels = template[4];
for (let index = 0; index < rawLabels.length; index++) {
const pair = rawLabels[index];
labels.set(pair[0], pair[1]);
}
const anchors = new Map();
- if (template[0]) {
+ if (template[1]) {
const anchorNames = new Set();
collectAnchorNames(targets, anchorNames);
const resourceCount = targets.length;
@@ -212,20 +235,172 @@ function compile(template) {
return template;
}
+function emitResolve(varName, instanceExpr, relInstance) {
+ if (relInstance.length === 0) return `var ${varName}=${instanceExpr};`;
+ if (relInstance.length === 1) return `var ${varName}=${instanceExpr}==null?void 0:${instanceExpr}[${JSON.stringify(relInstance[0])}];`;
+ return null;
+}
+
+function compileInstructionToCode(instruction, captures, visited, budget) {
+ if (budget[0] <= 0) { var ci = captures.length; captures.push(instruction); return 'return _fh['+instruction[0]+'](_c['+ci+'],i,d,_t,_v);'; }
+ var opcode = instruction[0], ri = instruction[2], value = instruction[5], children = instruction[6];
+ function R(v) { return emitResolve(v, 'i', ri); }
+ function inlineCondition(child, tv) {
+ var op = child[0], cr = child[2], cv = child[5];
+ if (cr.length !== 0) return null;
+ switch (op) {
+ case 11: return '{if(_es(' + tv + ')!==' + cv + ')return false;}';
+ case 38: return 'if(' + tv + '!=null&&typeof ' + tv + "==='object'&&!Array.isArray(" + tv + ')){' + emitResolve('t', tv, cr) + 'if(t!==void 0&&_es(t)!==' + cv + ')return false;}';
+ default: return null;
+ }
+ }
+ function seq(ci, tv) { var c = ''; for (var j = 0; j < ci.length; j++) { var inl = inlineCondition(ci[j], tv); if (inl !== null) { budget[0] -= inl.length; c += inl; continue; } var r = compileInstructionToCode(ci[j], captures, visited, budget); if (r === null) { var idx = captures.length; captures.push(ci[j]); c += 'if(!_e(_c['+idx+'],'+tv+',d+1,_t,_v))return false;'; } else { budget[0] -= r.length; c += 'if(!(function(i,d,_t,_v){'+r+'})('+tv+',d+1,_t,_v))return false;'; } } return c; }
+ function lb(ci, iv) { return seq(ci, iv); }
+ function fb(op) { var ci = captures.length; captures.push(instruction); return 'return _fh['+op+'](_c['+ci+'],i,d,_t,_v);'; }
+ function cc(child, tv) { var r = compileInstructionToCode(child, captures, visited, budget); if (r === null) { var ci = captures.length; captures.push(child); return '_e(_c['+ci+'],'+tv+',d+1,_t,_v)'; } budget[0] -= r.length; return '(function(i,d,_t,_v){'+r+'})('+tv+',d+1,_t,_v)'; }
+ var IO = "if(i==null||typeof i!=='object'||Array.isArray(i))return true;";
+ var TO = "if(t==null||typeof t!=='object'||Array.isArray(t))";
+ switch (opcode) {
+ case 0: return 'return false;';
+ case 1: { var r=R('t'); return r?r+TO+'return true;return Object.hasOwn(t,'+JSON.stringify(value)+');':null; }
+ case 2: { var r=R('t'); return r?r+"return t!=null&&typeof t==='object'&&!Array.isArray(t)&&Object.hasOwn(t,"+JSON.stringify(value)+');':null; }
+ case 3: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;'; for(var j=0;j'+value[1]+')return false;':'')+'return true;':null; }
+ case 14: { var r=R('t'); return r?r+"return typeof t==='string'&&_ul(t)<="+value+';':null; }
+ case 15: { var r=R('t'); return r?r+'if(!Array.isArray(t))return false;if(t.length<'+value[0]+')return false;'+(value[1]!==null?'if(t.length>'+value[1]+')return false;':'')+'return true;':null; }
+ case 16: { var r=R('t'); return r?r+'return Array.isArray(t)&&t.length<='+value+';':null; }
+ case 17: { var r=R('t'); return r?r+TO+'return false;var s=0;for(var k in t)s++;if(s<'+value[0]+')return false;'+(value[1]!==null?'if(s>'+value[1]+')return false;':'')+'return true;':null; }
+ case 18: { var r=R('t'); return r?r+TO+'return false;var s=0;for(var k in t)s++;return s<='+value+';':null; }
+ case 19: return fb(19); case 20: return fb(20); case 21: return fb(21);
+ case 22: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;return t.length<'+value+';':null; }
+ case 23: { var r=R('t'); return r?r+'if(!Array.isArray(t))return true;return t.length>'+value+';':null; }
+ case 24: { var r=R('t'); return r?r+TO+'return true;var s=0;for(var k in t)s++;return s<'+value+';':null; }
+ case 25: { var r=R('t'); return r?r+TO+'return true;var s=0;for(var k in t)s++;return s>'+value+';':null; }
+ case 26: { if(typeof value==='string'||typeof value==='number'||typeof value==='boolean'||value===null){var r=R('t');return r?r+'return t==='+JSON.stringify(value)+';':null;}return fb(26); }
+ case 27: return fb(27); case 28: return fb(28);
+ case 29: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t>="+value+';':null; }
+ case 30: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t<="+value+';':null; }
+ case 31: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t>"+value+';':null; }
+ case 32: { var r=R('t'); return r?r+"if(typeof t!=='number')return true;return t<"+value+';':null; }
+ case 33: return fb(33); case 34: return fb(34); case 35: return fb(35);
+ case 36: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;var a=_jt(t);return a==='+value+'||('+value+'===2&&_ii(t));':null; }
+ case 37: return fb(37);
+ case 38: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return _es(t)==='+value+';':null; }
+ case 39: return fb(39);
+ case 40: { var r=R('t'); return r?IO+r+'if(t===void 0)return true;return('+value+'&(1<<_es(t)))!==0;':null; }
+ case 41: return fb(41); case 42: return fb(42); case 43: return fb(43);
+ case 44: return 'return true;'; case 45: return 'return true;'; case 46: return 'return true;'; case 47: return 'return true;';
+ case 48: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return 'return false;'; var c=r; for(var j=0;j0)c+=seq(children,'t'); return c+'return true;'; }
+ case 55: { var r=R('t'); if(!r)return null; var c=r+TO+'return true;if(!Object.hasOwn(t,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
+ case 56: { var r=R('t'); if(!r)return null; var c=r+'if(!Array.isArray(t)||t.length<='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'t'); return c+'return true;'; }
+ case 57: return fb(57); case 58: return fb(58);
+ case 59: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi!==void 0){var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}}return true;'; }
+ case 60: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; var mi=captures.length; captures.push(value); var gf=''; for(var gi=0;gi0){gf+='function(i,d,_t,_v){'+lb(gc,'i')+'return true;},';}else{gf+='null,';}} return r+TO+'return true;var __cg=['+gf+'];for(var k in t){var __mi=_c['+mi+'][k];if(__mi===void 0)return false;var __cf=__cg[__mi];if(__cf&&!__cf(t,d,_t,_v))return false;}return true;'; }
+ case 61: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+TO+'return true;for(var k in t){'+lb(children,'t[k]')+'}return true;'; }
+ case 62: return fb(62); case 63: return fb(63); case 64: return fb(64); case 65: return fb(65); case 66: return fb(66);
+ case 67: return fb(67); case 68: return fb(68); case 69: return fb(69); case 70: return fb(70);
+ case 71: { var r=R('t'); return r?r+TO+'return true;for(var k in t){if(_es(t[k])!=='+value+')return false;}return true;':null; }
+ case 72: return fb(72); case 73: return fb(73); case 74: return fb(74); case 75: return fb(75);
+ case 76: { var r=R('t'); if(!r)return null; if(!children||children.length===0)return r+'return true;'; return r+'if(!Array.isArray(t))return true;for(var j=0;j=t.length)return true;for(var j='+value+';j0)c+=seq(children,'i'); return c+'return true;'; }
+ case 87: { var c=IO+'if(!Object.hasOwn(i,'+JSON.stringify(value)+'))return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
+ case 88: { var c='if(_jt(i)!=='+value+')return true;'; if(children&&children.length>0)c+=seq(children,'i'); return c+'return true;'; }
+ case 89: return 'return true;';
+ case 90: return fb(90);
+ case 91: { if(!value)return 'return true;'; if(visited&&visited.has(instruction))return fb(91); if(!visited)visited=new Set(); visited.add(instruction); var r=R('t'); if(!r)return fb(91); var c=r; for(var j=0;j true;
+ const instructions = targets[0];
+ if (instructions.length === 0) return () => true;
+
+ const capturedInstructions = [];
+ const budget = [5000000];
+ let body = '';
+ for (let index = 0; index < instructions.length; index++) {
+ const code = compileInstructionToCode(instructions[index], capturedInstructions, null, budget);
+ if (code === null) return null;
+ budget[0] -= code.length;
+ body += `if(!(function(i,d,_t,_v){${code}})(instance,0,_t,_v))return false;`;
+ }
+ body += 'return true;';
+
+ try {
+ const fn = eval(
+ '(function(_es,_jt,_ii,_ul,_e,_fh,_c,_t){' +
+ 'return function(instance,_v){' + body + '};' +
+ '})'
+ );
+ return fn(
+ effectiveTypeStrictReal, jsonTypeOf, isIntegral, unicodeLength,
+ evaluateInstructionFast, fastHandlers, capturedInstructions, template
+ );
+ } catch {
+ return null;
+ }
+}
+
class Blaze {
constructor(template) {
+ if (!Array.isArray(template) || template[0] !== JSON_VERSION) {
+ throw new Error(
+ `Only version ${JSON_VERSION} of the compiled template is supported by this version of the evaluator`);
+ }
compile(template);
this.template = template;
this.callbackMode = false;
+ this.trackMode = false;
+ this.dynamicMode = false;
+ this.callback = null;
+ this.evaluatePathLength = 0;
+ this.evaluatePathTokens = null;
+ this.instanceLocationLength = 0;
+ this.instanceLocationTokens = null;
+ this.resources = null;
+ this.evaluated = null;
+ this.propertyTarget = undefined;
+ this.propertyParent = undefined;
+ this.propertyKey = undefined;
+ this._nativeValidate = generateNativeValidator(template);
}
validate(instance, callback) {
+ if (callback === undefined && this._nativeValidate) {
+ return this._nativeValidate(instance, this);
+ }
+
const template = this.template;
- const targets = template[2];
+ const targets = template[3];
if (targets.length === 0) return true;
- const track = template[1];
- const dynamic = template[0];
+ const track = template[2];
+ const dynamic = template[1];
this.trackMode = track;
this.dynamicMode = dynamic;
this.callbackMode = callback !== undefined;
@@ -268,11 +443,11 @@ class Blaze {
}
}
- this.resources = undefined;
- this.evaluated = undefined;
- this.evaluatePathTokens = undefined;
- this.instanceLocationTokens = undefined;
- this.callback = undefined;
+ this.resources = null;
+ this.evaluated = null;
+ this.evaluatePathTokens = null;
+ this.instanceLocationTokens = null;
+ this.callback = null;
this.callbackMode = false;
return result;
}
@@ -435,7 +610,7 @@ function evaluateInstructionFast(instruction, instance, depth, template, evaluat
if (depth > DEPTH_LIMIT) {
throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');
}
- const handler = instruction[7];
+ const handler = fastHandlers[instruction[0]];
if (!handler) return true;
return handler(instruction, instance, depth, template, evaluator);
}
@@ -444,7 +619,7 @@ function evaluateInstructionTracked(instruction, instance, depth, template, eval
if (depth > DEPTH_LIMIT) {
throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');
}
- const handler = instruction[7];
+ const handler = fastHandlers[instruction[0]];
if (!handler) return true;
const type = instruction[0];
@@ -474,7 +649,7 @@ function evaluateInstructionFastCallback(instruction, instance, depth, template,
if (depth > DEPTH_LIMIT) {
throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');
}
- const handler = instruction[7];
+ const handler = handlers[instruction[0]];
if (!handler) return true;
return handler(instruction, instance, depth, template, evaluator);
}
@@ -483,7 +658,7 @@ function evaluateInstructionTrackedCallback(instruction, instance, depth, templa
if (depth > DEPTH_LIMIT) {
throw new Error('The evaluation path depth limit was reached likely due to infinite recursion');
}
- const handler = instruction[7];
+ const handler = handlers[instruction[0]];
if (!handler) return true;
const type = instruction[0];
@@ -512,9 +687,14 @@ function evaluateInstructionTrackedCallback(instruction, instance, depth, templa
let evaluateInstruction = evaluateInstructionFast;
function effectiveTypeStrictReal(value) {
- const type = jsonTypeOf(value);
- if (type === Type.Real && Number.isInteger(value)) return Type.Integer;
- return type;
+ if (value === null) return Type.Null;
+ switch (typeof value) {
+ case 'boolean': return Type.Boolean;
+ case 'number': return Number.isInteger(value) ? Type.Integer : Type.Real;
+ case 'string': return Type.String;
+ case 'object': return Array.isArray(value) ? Type.Array : Type.Object;
+ default: return Type.Null;
+ }
}
function typeSetTest(bitmask, typeIndex) {
@@ -566,12 +746,34 @@ function fastHash(value) {
}
function isUnique(array) {
- if (array.length <= 1) return true;
- const hashes = new Array(array.length);
- for (let index = 0; index < array.length; index++) {
+ const length = array.length;
+ if (length <= 1) return true;
+ const first = array[0];
+ const firstType = typeof first;
+ if (first !== null && firstType !== 'object') {
+ let allPrimitive = true;
+ for (let index = 1; index < length; index++) {
+ const element = array[index];
+ if (element === null || typeof element === 'object') {
+ allPrimitive = false;
+ break;
+ }
+ }
+ if (allPrimitive) {
+ const set = new Set();
+ for (let index = 0; index < length; index++) {
+ const size = set.size;
+ set.add(array[index]);
+ if (set.size === size) return false;
+ }
+ return true;
+ }
+ }
+ const hashes = new Array(length);
+ for (let index = 0; index < length; index++) {
hashes[index] = fastHash(array[index]);
}
- for (let index = 1; index < array.length; index++) {
+ for (let index = 1; index < length; index++) {
for (let previous = 0; previous < index; previous++) {
if (hashes[index] === hashes[previous] && jsonEqual(array[index], array[previous])) return false;
}
@@ -591,7 +793,8 @@ function unicodeLength(string) {
let count = 0;
for (let index = 0; index < string.length; index++) {
count++;
- if (string.charCodeAt(index) >= 0xD800 && string.charCodeAt(index) <= 0xDBFF) index++;
+ const code = string.charCodeAt(index);
+ if (code >= 0xD800 && code <= 0xDBFF) index++;
}
return count;
}
@@ -972,22 +1175,19 @@ function AssertionEqual(instruction, instance, depth, template, evaluator) {
function AssertionEqualsAny(instruction, instance, depth, template, evaluator) {
if (evaluator.callbackMode) evaluator.callbackPush(instruction);
- if (evaluator.propertyTarget !== undefined) {
- const values = instruction[5];
- for (let index = 0; index < values.length; index++) {
- if (jsonEqual(evaluator.propertyTarget, values[index])) {
- if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
- return true;
- }
- }
- } else {
- const target = resolveInstance(instance, instruction[2]);
- const values = instruction[5];
- for (let index = 0; index < values.length; index++) {
- if (jsonEqual(target, values[index])) {
- if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
- return true;
- }
+ const value = instruction[5];
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (value.primitive) {
+ const __result = value.set.has(target);
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
+ return __result;
+ }
+ const values = Array.isArray(value) ? value : value.values;
+ for (let index = 0; index < values.length; index++) {
+ if (jsonEqual(target, values[index])) {
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
+ return true;
}
}
if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
@@ -1088,14 +1288,9 @@ function AssertionStringType(instruction, instance, depth, template, evaluator)
? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
if (typeof target !== 'string') return true;
if (evaluator.callbackMode) evaluator.callbackPush(instruction);
- try {
- new URL(target);
- if (evaluator.callbackMode) evaluator.callbackPop(instruction, true);
- return true;
- } catch {
- if (evaluator.callbackMode) evaluator.callbackPop(instruction, false);
- return false;
- }
+ const __result = URI_REGEX.test(target);
+ if (evaluator.callbackMode) evaluator.callbackPop(instruction, __result);
+ return __result;
};
function AssertionPropertyType(instruction, instance, depth, template, evaluator) {
@@ -2331,4 +2526,1189 @@ const handlers = [
ControlJump // 91
];
+function AssertionTypeArrayBounded_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return false;
+ const range = instruction[5];
+ if (target.length < range[0]) return false;
+ if (range[1] !== null && target.length > range[1]) return false;
+ return true;
+}
+
+function LoopItemsTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return true;
+ const bitmask = instruction[5];
+ for (let index = 0; index < target.length; index++) {
+ if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[index]))) return false;
+ }
+ return true;
+}
+
+function AssertionPropertyTypeStrict_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ return effectiveTypeStrictReal(target) === instruction[5];
+}
+
+function AssertionTypeStrict_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ return effectiveTypeStrictReal(target) === instruction[5];
+}
+
+function AssertionDefinesAllStrict_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return false;
+ const strings = instruction[5];
+ for (let index = 0; index < strings.length; index++) {
+ if (!Object.hasOwn(target, strings[index])) return false;
+ }
+ return true;
+}
+
+function AssertionEqual_fast(instruction, instance, depth, template, evaluator) {
+ if (evaluator.propertyTarget !== undefined) {
+ const value = instruction[5];
+ return typeof value === 'string' && value === evaluator.propertyTarget;
+ }
+ return jsonEqual(resolveInstance(instance, instruction[2]), instruction[5]);
+}
+
+function LoopPropertiesMatch_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ const index = instruction[5][key];
+ if (index === undefined) continue;
+ const subinstruction = children[index];
+ const subchildren = subinstruction[6];
+ if (subchildren) {
+ for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {
+ if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+function LogicalOr_fast(instruction, instance, depth, template, evaluator) {
+ const children = instruction[6];
+ if (!children || children.length === 0) return true;
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const exhaustive = instruction[5];
+ let result = false;
+ if (exhaustive) {
+ for (let index = 0; index < children.length; index++) {
+ if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) result = true;
+ }
+ } else {
+ for (let index = 0; index < children.length; index++) {
+ if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return true;
+ }
+ }
+ return result;
+}
+
+function ControlJump_fast(instruction, instance, depth, template, evaluator) {
+ const jumpTarget = instruction[5];
+ if (!jumpTarget) return true;
+ const relInstance = instruction[2];
+ const resolved = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ for (let index = 0; index < jumpTarget.length; index++) {
+ if (!evaluateInstruction(jumpTarget[index], resolved, depth + 1, template, evaluator)) return false;
+ }
+ return true;
+}
+
+function AssertionEqualsAnyStringHash_fast(instruction, instance, depth, template, evaluator) {
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget
+ : resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'string') return false;
+ const value = instruction[5];
+ const entries = value[0];
+ const tableOfContents = value[1];
+ const stringSize = target.length;
+ if (stringSize < tableOfContents.length) {
+ const hint = tableOfContents[stringSize];
+ if (hint[1] === 0) return false;
+ for (let index = hint[0] - 1; index < hint[1]; index++) {
+ if (entries[index][1] === target) return true;
+ }
+ }
+ return false;
+}
+
+function LogicalXor_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const exhaustive = instruction[5];
+ const children = instruction[6];
+ let result = true;
+ let hasMatched = false;
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {
+ if (hasMatched) {
+ result = false;
+ if (!exhaustive) break;
+ } else {
+ hasMatched = true;
+ }
+ }
+ }
+ }
+ return result && hasMatched;
+}
+
+function AssertionDefinesStrict_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ return isObject(target) && Object.hasOwn(target, instruction[5]);
+}
+
+function LoopItems_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return true;
+ const children = instruction[6];
+ for (let index = 0; index < target.length; index++) {
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+function LoopPropertiesMatchClosed_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ const index = instruction[5][key];
+ if (index === undefined) return false;
+ const subinstruction = children[index];
+ const subchildren = subinstruction[6];
+ if (subchildren) {
+ for (let childIndex = 0; childIndex < subchildren.length; childIndex++) {
+ if (!evaluateInstruction(subchildren[childIndex], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+function LogicalAnd_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const children = instruction[6];
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ return true;
+}
+
+function AssertionTypeStringBounded_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (typeof target !== 'string') return false;
+ const range = instruction[5];
+ const length = unicodeLength(target);
+ if (length < range[0]) return false;
+ return range[1] === null || length <= range[1];
+}
+
+function AssertionPropertyDependencies_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ const value = instruction[5];
+ for (const property in value) {
+ if (!Object.hasOwn(target, property)) continue;
+ const dependencies = value[property];
+ for (let index = 0; index < dependencies.length; index++) {
+ if (!Object.hasOwn(target, dependencies[index])) return false;
+ }
+ }
+ return true;
+}
+
+function AssertionTypeAny_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const bitmask = instruction[5];
+ const typeIndex = jsonTypeOf(target);
+ if (typeSetTest(bitmask, typeIndex)) return true;
+ return typeSetTest(bitmask, Type.Integer) && isIntegral(target);
+}
+
+function LogicalCondition_fast(instruction, instance, depth, template, evaluator) {
+ const value = instruction[5];
+ const thenStart = value[0];
+ const elseStart = value[1];
+ const children = instruction[6];
+ const childrenSize = children ? children.length : 0;
+ let conditionEnd = childrenSize;
+ if (thenStart > 0) conditionEnd = thenStart;
+ else if (elseStart > 0) conditionEnd = elseStart;
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ let conditionResult = true;
+ for (let cursor = 0; cursor < conditionEnd; cursor++) {
+ if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {
+ conditionResult = false;
+ break;
+ }
+ }
+ const consequenceStart = conditionResult ? thenStart : elseStart;
+ const consequenceEnd = (conditionResult && elseStart > 0) ? elseStart : childrenSize;
+ if (consequenceStart > 0) {
+ if (evaluator.trackMode) {
+ evaluator.popPath(instruction[1].length);
+ }
+ let result = true;
+ for (let cursor = consequenceStart; cursor < consequenceEnd; cursor++) {
+ if (!evaluateInstruction(children[cursor], target, depth + 1, template, evaluator)) {
+ result = false;
+ break;
+ }
+ }
+ if (evaluator.trackMode) {
+ evaluator.pushPath(instruction[1]);
+ }
+ return result;
+ }
+ return true;
+}
+
+function LoopPropertiesExcept_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const filter = instruction[5];
+ const filterStrings = filter[0];
+ const filterPrefixes = filter[1];
+ const filterRegexes = filter[2];
+ const children = instruction[6];
+ for (const key in target) {
+ if (filterStrings.has(key)) continue;
+ let matched = false;
+ for (let index = 0; index < filterPrefixes.length; index++) {
+ if (key.startsWith(filterPrefixes[index])) { matched = true; break; }
+ }
+ if (matched) continue;
+ for (let index = 0; index < filterRegexes.length; index++) {
+ filterRegexes[index].lastIndex = 0;
+ if (filterRegexes[index].test(key)) { matched = true; break; }
+ }
+ if (matched) continue;
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return true;
+}
+
+function AssertionRegex_fast(instruction, instance, depth, template, evaluator) {
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'string') return true;
+ return instruction[5].test(target);
+}
+
+function LoopProperties_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return true;
+}
+
+function AssertionDefines_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ return Object.hasOwn(target, instruction[5]);
+}
+
+function LogicalWhenType_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (jsonTypeOf(target) !== instruction[5]) return true;
+ const children = instruction[6];
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ return true;
+}
+
+function LogicalWhenDefines_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ if (!Object.hasOwn(target, instruction[5])) return true;
+ const children = instruction[6];
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ return true;
+}
+
+function AssertionFail_fast() { return false; }
+
+function LoopContains_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return true;
+ const range = instruction[5];
+ const minimum = range[0];
+ const maximum = range[1];
+ const isExhaustive = range[2];
+ if (minimum === 0 && target.length === 0) return true;
+ const children = instruction[6];
+ let matchCount = 0;
+ for (let index = 0; index < target.length; index++) {
+ let subresult = true;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) {
+ subresult = false;
+ break;
+ }
+ }
+ }
+ if (subresult) {
+ matchCount++;
+ if (maximum !== null && matchCount > maximum) return false;
+ if (matchCount >= minimum && maximum === null && !isExhaustive) return true;
+ }
+ }
+ return matchCount >= minimum;
+}
+
+function LogicalNot_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const children = instruction[6];
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return true;
+ }
+ }
+ return false;
+}
+
+function LoopItemsType_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return true;
+ const expected = instruction[5];
+ for (let index = 0; index < target.length; index++) {
+ const actual = jsonTypeOf(target[index]);
+ if (actual !== expected && !(expected === Type.Integer && isIntegral(target[index]))) return false;
+ }
+ return true;
+}
+
+function LoopItemsTypeStrict_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!Array.isArray(target)) return true;
+ const expected = instruction[5];
+ for (let index = 0; index < target.length; index++) {
+ if (effectiveTypeStrictReal(target[index]) !== expected) return false;
+ }
+ return true;
+}
+
+function AssertionEqualsAny_fast(instruction, instance, depth, template, evaluator) {
+ const value = instruction[5];
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (value.primitive) return value.set.has(target);
+ const values = Array.isArray(value) ? value : value.values;
+ for (let index = 0; index < values.length; index++) {
+ if (jsonEqual(target, values[index])) return true;
+ }
+ return false;
+}
+
+function AssertionDefinesAll_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ const strings = instruction[5];
+ for (let index = 0; index < strings.length; index++) {
+ if (!Object.hasOwn(target, strings[index])) return false;
+ }
+ return true;
+}
+
+function AssertionDefinesExactly_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ let targetSize = 0;
+ for (const key in target) targetSize++;
+ const strings = instruction[5];
+ if (targetSize !== strings.length) return false;
+ for (let index = 0; index < strings.length; index++) {
+ if (!Object.hasOwn(target, strings[index])) return false;
+ }
+ return true;
+}
+
+function AssertionDefinesExactlyStrict_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return false;
+ let targetSize = 0;
+ for (const key in target) targetSize++;
+ const strings = instruction[5];
+ if (targetSize !== strings.length) return false;
+ for (let index = 0; index < strings.length; index++) {
+ if (!Object.hasOwn(target, strings[index])) return false;
+ }
+ return true;
+}
+
+function AssertionDefinesExactlyStrictHash3_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return false;
+ const entries = instruction[5][0];
+ let count = 0;
+ for (const key in target) count++;
+ if (count !== 3) return false;
+ return Object.hasOwn(target, entries[0][1]) &&
+ Object.hasOwn(target, entries[1][1]) &&
+ Object.hasOwn(target, entries[2][1]);
+}
+
+function AssertionType_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ const expected = instruction[5];
+ const actual = jsonTypeOf(target);
+ if (actual === expected) return true;
+ return expected === Type.Integer && isIntegral(target);
+}
+
+function AssertionTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ return typeSetTest(instruction[5], effectiveTypeStrictReal(target));
+}
+
+function AssertionTypeStringUpper_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ return typeof target === 'string' && unicodeLength(target) <= instruction[5];
+}
+
+function AssertionTypeArrayUpper_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ return Array.isArray(target) && target.length <= instruction[5];
+}
+
+function AssertionTypeObjectBounded_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return false;
+ const range = instruction[5];
+ const size = objectSize(target);
+ if (size < range[0]) return false;
+ return range[1] === null || size <= range[1];
+}
+
+function AssertionTypeObjectUpper_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return false;
+ return objectSize(target) <= instruction[5];
+}
+
+function AssertionStringSizeLess_fast(instruction, instance, depth, template, evaluator) {
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'string') return true;
+ return unicodeLength(target) < instruction[5];
+}
+
+function AssertionStringSizeGreater_fast(instruction, instance, depth, template, evaluator) {
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'string') return true;
+ return unicodeLength(target) > instruction[5];
+}
+
+function AssertionArraySizeLess_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ return target.length < instruction[5];
+}
+
+function AssertionArraySizeGreater_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ return target.length > instruction[5];
+}
+
+function AssertionObjectSizeLess_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ return objectSize(target) < instruction[5];
+}
+
+function AssertionObjectSizeGreater_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ return objectSize(target) > instruction[5];
+}
+
+function AssertionGreaterEqual_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'number') return true;
+ return target >= instruction[5];
+}
+
+function AssertionLessEqual_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'number') return true;
+ return target <= instruction[5];
+}
+
+function AssertionGreater_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'number') return true;
+ return target > instruction[5];
+}
+
+function AssertionLess_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'number') return true;
+ return target < instruction[5];
+}
+
+function AssertionUnique_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ return isUnique(target);
+}
+
+function AssertionDivisible_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'number') return true;
+ return isDivisibleBy(target, instruction[5]);
+}
+
+function AssertionStringType_fast(instruction, instance, depth, template, evaluator) {
+ const target = evaluator.propertyTarget !== undefined
+ ? evaluator.propertyTarget : resolveInstance(instance, instruction[2]);
+ if (typeof target !== 'string') return true;
+ return URI_REGEX.test(target);
+}
+
+function AssertionPropertyType_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ const expected = instruction[5];
+ const actual = jsonTypeOf(target);
+ return actual === expected || (expected === Type.Integer && isIntegral(target));
+}
+
+function AssertionPropertyTypeEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ const expected = instruction[5];
+ const actual = jsonTypeOf(target);
+ const result = actual === expected || (expected === Type.Integer && isIntegral(target));
+ if (result && evaluator.trackMode) {
+ const location = instruction[2];
+ evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);
+ }
+ return result;
+}
+
+function AssertionPropertyTypeStrictEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ const result = effectiveTypeStrictReal(target) === instruction[5];
+ if (result && evaluator.trackMode) {
+ const location = instruction[2];
+ evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);
+ }
+ return result;
+}
+
+function AssertionPropertyTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ return typeSetTest(instruction[5], effectiveTypeStrictReal(target));
+}
+
+function AssertionPropertyTypeStrictAnyEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ if (!isObject(instance)) return true;
+ const target = resolveInstance(instance, instruction[2]);
+ if (target === undefined) return true;
+ const result = typeSetTest(instruction[5], effectiveTypeStrictReal(target));
+ if (result && evaluator.trackMode) {
+ const location = instruction[2];
+ evaluator.markEvaluated(target, instance, location.length > 0 ? location[location.length - 1] : undefined);
+ }
+ return result;
+}
+
+function AssertionArrayPrefix_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ if (target.length === 0) return true;
+ const children = instruction[6];
+ const prefixes = children.length - 1;
+ const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;
+ const entry = children[pointer];
+ const entryChildren = entry[6];
+ if (entryChildren) {
+ for (let index = 0; index < entryChildren.length; index++) {
+ if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ return true;
+}
+
+function AssertionArrayPrefixEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ if (target.length === 0) return true;
+ const children = instruction[6];
+ const prefixes = children.length - 1;
+ const pointer = target.length === prefixes ? prefixes : Math.min(target.length, prefixes) - 1;
+ const entry = children[pointer];
+ const entryChildren = entry[6];
+ if (entryChildren) {
+ for (let index = 0; index < entryChildren.length; index++) {
+ if (!evaluateInstruction(entryChildren[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ if (evaluator.trackMode) {
+ if (target.length === prefixes) {
+ evaluator.markEvaluated(target);
+ } else {
+ for (let cursor = 0; cursor <= pointer; cursor++) {
+ evaluator.markEvaluated(target[cursor], target, cursor);
+ }
+ }
+ }
+ return true;
+}
+
+function AnnotationEmit_fast() { return true; }
+function AnnotationToParent_fast() { return true; }
+function AnnotationBasenameToParent_fast() { return true; }
+
+function Evaluate_fast(instruction, instance, depth, template, evaluator) {
+ if (evaluator.trackMode) {
+ const target = resolveInstance(instance, instruction[2]);
+ evaluator.markEvaluated(target);
+ }
+ return true;
+}
+
+function LogicalNotEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ const children = instruction[6];
+ let result = false;
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) {
+ result = true;
+ break;
+ }
+ }
+ }
+ if (evaluator.trackMode) evaluator.unevaluate();
+ return result;
+}
+
+function LogicalWhenArraySizeGreater_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target) || target.length <= instruction[5]) return true;
+ const children = instruction[6];
+ if (children) {
+ for (let index = 0; index < children.length; index++) {
+ if (!evaluateInstruction(children[index], target, depth + 1, template, evaluator)) return false;
+ }
+ }
+ return true;
+}
+
+function LoopPropertiesUnevaluated_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopPropertiesUnevaluatedExcept_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;
+ const filter = instruction[5];
+ const filterStrings = filter[0];
+ const filterPrefixes = filter[1];
+ const filterRegexes = filter[2];
+ const children = instruction[6];
+ for (const key in target) {
+ if (filterStrings.has(key)) continue;
+ let matched = false;
+ for (let index = 0; index < filterPrefixes.length; index++) {
+ if (key.startsWith(filterPrefixes[index])) { matched = true; break; }
+ }
+ if (matched) continue;
+ for (let index = 0; index < filterRegexes.length; index++) {
+ filterRegexes[index].lastIndex = 0;
+ if (filterRegexes[index].test(key)) { matched = true; break; }
+ }
+ if (matched) continue;
+ if (evaluator.trackMode && evaluator.isEvaluated(target[key], target, key)) continue;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopPropertiesEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopPropertiesRegex_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const regex = instruction[5];
+ const children = instruction[6];
+ for (const key in target) {
+ regex.lastIndex = 0;
+ if (!regex.test(key)) continue;
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return true;
+}
+
+function LoopPropertiesRegexClosed_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const regex = instruction[5];
+ const children = instruction[6];
+ for (const key in target) {
+ regex.lastIndex = 0;
+ if (!regex.test(key)) return false;
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return true;
+}
+
+function LoopPropertiesStartsWith_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const prefix = instruction[5];
+ const children = instruction[6];
+ for (const key in target) {
+ if (!key.startsWith(prefix)) continue;
+ evaluator.propertyParent = target;
+ evaluator.propertyKey = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[key], depth + 1, template, evaluator)) {
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return false;
+ }
+ }
+ }
+ }
+ evaluator.propertyParent = undefined;
+ evaluator.propertyKey = undefined;
+ return true;
+}
+
+function LoopPropertiesType_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const expected = instruction[5];
+ for (const key in target) {
+ const actual = jsonTypeOf(target[key]);
+ if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) return false;
+ }
+ return true;
+}
+
+function LoopPropertiesTypeEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const expected = instruction[5];
+ for (const key in target) {
+ const actual = jsonTypeOf(target[key]);
+ if (actual !== expected && !(expected === Type.Integer && isIntegral(target[key]))) return false;
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopPropertiesExactlyTypeStrict_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return false;
+ const value = instruction[5];
+ let count = 0;
+ for (const key in target) {
+ count++;
+ if (effectiveTypeStrictReal(target[key]) !== value[0]) return false;
+ }
+ return count === value[1].length;
+}
+
+function LoopPropertiesExactlyTypeStrictHash_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return false;
+ const value = instruction[5];
+ const entries = value[1][0];
+ const expectedCount = entries.length;
+ let count = 0;
+ for (const key in target) {
+ count++;
+ if (effectiveTypeStrictReal(target[key]) !== value[0]) return false;
+ }
+ if (count !== expectedCount) return false;
+ for (let index = 0; index < expectedCount; index++) {
+ if (!Object.hasOwn(target, entries[index][1])) return false;
+ }
+ return true;
+}
+
+function LoopPropertiesTypeStrict_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const expected = instruction[5];
+ for (const key in target) {
+ if (effectiveTypeStrictReal(target[key]) !== expected) return false;
+ }
+ return true;
+}
+
+function LoopPropertiesTypeStrictEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const expected = instruction[5];
+ for (const key in target) {
+ if (effectiveTypeStrictReal(target[key]) !== expected) return false;
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopPropertiesTypeStrictAny_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const bitmask = instruction[5];
+ for (const key in target) {
+ if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) return false;
+ }
+ return true;
+}
+
+function LoopPropertiesTypeStrictAnyEvaluate_fast(instruction, instance, depth, template, evaluator) {
+ const relInstance = instruction[2];
+ const target = relInstance.length === 0 ? instance : resolveInstance(instance, relInstance);
+ if (!isObject(target)) return true;
+ const bitmask = instruction[5];
+ for (const key in target) {
+ if (!typeSetTest(bitmask, effectiveTypeStrictReal(target[key]))) return false;
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopKeys_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!isObject(target)) return true;
+ const children = instruction[6];
+ for (const key in target) {
+ const previousPropertyTarget = evaluator.propertyTarget;
+ evaluator.propertyTarget = key;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], null, depth + 1, template, evaluator)) {
+ evaluator.propertyTarget = previousPropertyTarget;
+ return false;
+ }
+ }
+ }
+ evaluator.propertyTarget = previousPropertyTarget;
+ }
+ return true;
+}
+
+function LoopItemsFrom_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ const startIndex = instruction[5];
+ if (!Array.isArray(target) || startIndex >= target.length) return true;
+ const children = instruction[6];
+ for (let index = startIndex; index < target.length; index++) {
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+function LoopItemsUnevaluated_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return true;
+ if (evaluator.trackMode && evaluator.isEvaluated(target)) return true;
+ const children = instruction[6];
+ for (let index = 0; index < target.length; index++) {
+ if (evaluator.trackMode && evaluator.isEvaluated(target[index], target, index)) continue;
+ if (children) {
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
+ if (!evaluateInstruction(children[childIndex], target[index], depth + 1, template, evaluator)) return false;
+ }
+ }
+ }
+ if (evaluator.trackMode) evaluator.markEvaluated(target);
+ return true;
+}
+
+function LoopItemsPropertiesExactlyTypeStrictHash_fast(instruction, instance, depth, template, evaluator) {
+ const target = resolveInstance(instance, instruction[2]);
+ if (!Array.isArray(target)) return false;
+ const expectedType = instruction[5][0];
+ const entries = instruction[5][1][0];
+ const expectedCount = entries.length;
+ for (let index = 0; index < target.length; index++) {
+ const item = target[index];
+ if (!isObject(item)) return false;
+ let count = 0;
+ for (const key in item) {
+ count++;
+ if (effectiveTypeStrictReal(item[key]) !== expectedType) return false;
+ }
+ if (count !== expectedCount) return false;
+ for (let entry = 0; entry < expectedCount; entry++) {
+ if (!Object.hasOwn(item, entries[entry][1])) return false;
+ }
+ }
+ return true;
+}
+
+function ControlDynamicAnchorJump_fast(instruction, instance, depth, template, evaluator) {
+ const resolved = resolveInstance(instance, instruction[2]);
+ const anchor = instruction[5];
+ if (!evaluator.resources) return false;
+ const anchors = template[5];
+ for (let index = 0; index < evaluator.resources.length; index++) {
+ const jumpTarget = anchors.get(evaluator.resources[index] + ':' + anchor);
+ if (jumpTarget !== undefined) {
+ for (let childIndex = 0; childIndex < jumpTarget.length; childIndex++) {
+ if (!evaluateInstruction(jumpTarget[childIndex], resolved, depth + 1, template, evaluator)) return false;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+const fastHandlers = handlers.slice();
+fastHandlers[15] = AssertionTypeArrayBounded_fast;
+fastHandlers[81] = LoopItemsTypeStrictAny_fast;
+fastHandlers[38] = AssertionPropertyTypeStrict_fast;
+fastHandlers[11] = AssertionTypeStrict_fast;
+fastHandlers[4] = AssertionDefinesAllStrict_fast;
+fastHandlers[26] = AssertionEqual_fast;
+fastHandlers[59] = LoopPropertiesMatch_fast;
+fastHandlers[50] = LogicalOr_fast;
+fastHandlers[91] = ControlJump_fast;
+fastHandlers[28] = AssertionEqualsAnyStringHash_fast;
+fastHandlers[52] = LogicalXor_fast;
+fastHandlers[2] = AssertionDefinesStrict_fast;
+fastHandlers[76] = LoopItems_fast;
+fastHandlers[60] = LoopPropertiesMatchClosed_fast;
+fastHandlers[13] = AssertionTypeStringBounded_fast;
+fastHandlers[51] = LogicalAnd_fast;
+fastHandlers[8] = AssertionPropertyDependencies_fast;
+fastHandlers[10] = AssertionTypeAny_fast;
+fastHandlers[53] = LogicalCondition_fast;
+fastHandlers[66] = LoopPropertiesExcept_fast;
+fastHandlers[19] = AssertionRegex_fast;
+fastHandlers[61] = LoopProperties_fast;
+fastHandlers[1] = AssertionDefines_fast;
+fastHandlers[54] = LogicalWhenType_fast;
+fastHandlers[55] = LogicalWhenDefines_fast;
+fastHandlers[0] = AssertionFail_fast;
+fastHandlers[84] = LoopContains_fast;
+fastHandlers[48] = LogicalNot_fast;
+fastHandlers[79] = LoopItemsType_fast;
+fastHandlers[80] = LoopItemsTypeStrict_fast;
+fastHandlers[27] = AssertionEqualsAny_fast;
+fastHandlers[3] = AssertionDefinesAll_fast;
+fastHandlers[5] = AssertionDefinesExactly_fast;
+fastHandlers[6] = AssertionDefinesExactlyStrict_fast;
+fastHandlers[7] = AssertionDefinesExactlyStrictHash3_fast;
+fastHandlers[9] = AssertionType_fast;
+fastHandlers[12] = AssertionTypeStrictAny_fast;
+fastHandlers[14] = AssertionTypeStringUpper_fast;
+fastHandlers[16] = AssertionTypeArrayUpper_fast;
+fastHandlers[17] = AssertionTypeObjectBounded_fast;
+fastHandlers[18] = AssertionTypeObjectUpper_fast;
+fastHandlers[20] = AssertionStringSizeLess_fast;
+fastHandlers[21] = AssertionStringSizeGreater_fast;
+fastHandlers[22] = AssertionArraySizeLess_fast;
+fastHandlers[23] = AssertionArraySizeGreater_fast;
+fastHandlers[24] = AssertionObjectSizeLess_fast;
+fastHandlers[25] = AssertionObjectSizeGreater_fast;
+fastHandlers[29] = AssertionGreaterEqual_fast;
+fastHandlers[30] = AssertionLessEqual_fast;
+fastHandlers[31] = AssertionGreater_fast;
+fastHandlers[32] = AssertionLess_fast;
+fastHandlers[33] = AssertionUnique_fast;
+fastHandlers[34] = AssertionDivisible_fast;
+fastHandlers[35] = AssertionStringType_fast;
+fastHandlers[36] = AssertionPropertyType_fast;
+fastHandlers[37] = AssertionPropertyTypeEvaluate_fast;
+fastHandlers[39] = AssertionPropertyTypeStrictEvaluate_fast;
+fastHandlers[40] = AssertionPropertyTypeStrictAny_fast;
+fastHandlers[41] = AssertionPropertyTypeStrictAnyEvaluate_fast;
+fastHandlers[42] = AssertionArrayPrefix_fast;
+fastHandlers[43] = AssertionArrayPrefixEvaluate_fast;
+fastHandlers[44] = AnnotationEmit_fast;
+fastHandlers[45] = AnnotationToParent_fast;
+fastHandlers[46] = AnnotationBasenameToParent_fast;
+fastHandlers[47] = Evaluate_fast;
+fastHandlers[49] = LogicalNotEvaluate_fast;
+fastHandlers[56] = LogicalWhenArraySizeGreater_fast;
+fastHandlers[57] = LoopPropertiesUnevaluated_fast;
+fastHandlers[58] = LoopPropertiesUnevaluatedExcept_fast;
+fastHandlers[62] = LoopPropertiesEvaluate_fast;
+fastHandlers[63] = LoopPropertiesRegex_fast;
+fastHandlers[64] = LoopPropertiesRegexClosed_fast;
+fastHandlers[65] = LoopPropertiesStartsWith_fast;
+fastHandlers[67] = LoopPropertiesType_fast;
+fastHandlers[68] = LoopPropertiesTypeEvaluate_fast;
+fastHandlers[69] = LoopPropertiesExactlyTypeStrict_fast;
+fastHandlers[70] = LoopPropertiesExactlyTypeStrictHash_fast;
+fastHandlers[71] = LoopPropertiesTypeStrict_fast;
+fastHandlers[72] = LoopPropertiesTypeStrictEvaluate_fast;
+fastHandlers[73] = LoopPropertiesTypeStrictAny_fast;
+fastHandlers[74] = LoopPropertiesTypeStrictAnyEvaluate_fast;
+fastHandlers[75] = LoopKeys_fast;
+fastHandlers[77] = LoopItemsFrom_fast;
+fastHandlers[78] = LoopItemsUnevaluated_fast;
+fastHandlers[82] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
+fastHandlers[83] = LoopItemsPropertiesExactlyTypeStrictHash_fast;
+fastHandlers[90] = ControlDynamicAnchorJump_fast;
+
export { Blaze };
diff --git a/vendor/blaze/ports/javascript/package-lock.json b/vendor/blaze/ports/javascript/package-lock.json
index edd16080..66bc1463 100644
--- a/vendor/blaze/ports/javascript/package-lock.json
+++ b/vendor/blaze/ports/javascript/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@sourcemeta/blaze",
- "version": "0.0.1",
+ "version": "0.0.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@sourcemeta/blaze",
- "version": "0.0.1"
+ "version": "0.0.2"
}
}
}
diff --git a/vendor/blaze/ports/javascript/package.json b/vendor/blaze/ports/javascript/package.json
index 31f61255..ef08b215 100644
--- a/vendor/blaze/ports/javascript/package.json
+++ b/vendor/blaze/ports/javascript/package.json
@@ -1,10 +1,71 @@
{
"name": "@sourcemeta/blaze",
- "version": "0.0.1",
- "private": true,
+ "version": "0.0.2",
+ "description": "A pure JavaScript port of the evaluator from Blaze, a high-performance C++ JSON Schema validator. Zero dependencies. Supports Draft 4, Draft 6, Draft 7, 2019-09, and 2020-12 with schema-specific code generation for near-native speed",
"type": "module",
- "scripts": {
- "test": "node --test test.mjs trace.mjs",
- "benchmark": "node benchmark.mjs"
- }
+ "main": "./index.mjs",
+ "module": "./index.mjs",
+ "exports": {
+ ".": {
+ "import": "./index.mjs",
+ "default": "./index.mjs"
+ }
+ },
+ "types": "./index.d.mts",
+ "license": "LGPL-3.0-or-later",
+ "homepage": "https://github.com/sourcemeta/blaze",
+ "author": {
+ "email": "hello@sourcemeta.com",
+ "name": "Sourcemeta",
+ "url": "https://www.sourcemeta.com"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": "https://github.com/sponsors/sourcemeta",
+ "keywords": [
+ "jsonschema",
+ "json",
+ "schema",
+ "json-schema",
+ "validator",
+ "validation",
+ "json-schema-validator",
+ "json-schema-validation",
+ "blaze",
+ "sourcemeta",
+ "fast",
+ "performance",
+ "codegen",
+ "draft-04",
+ "draft-06",
+ "draft-07",
+ "draft4",
+ "draft6",
+ "draft7",
+ "2019-09",
+ "2020-12",
+ "ajv",
+ "ajv-alternative",
+ "$ref",
+ "validate",
+ "evaluator"
+ ],
+ "bugs": {
+ "url": "https://github.com/sourcemeta/blaze/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/sourcemeta/blaze.git",
+ "directory": "ports/javascript"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "files": [
+ "index.mjs",
+ "index.d.mts",
+ "README.md",
+ "LICENSE"
+ ]
}
diff --git a/vendor/blaze/src/compiler/compile_json.cc b/vendor/blaze/src/compiler/compile_json.cc
index 4b2583c2..89a847b0 100644
--- a/vendor/blaze/src/compiler/compile_json.cc
+++ b/vendor/blaze/src/compiler/compile_json.cc
@@ -53,6 +53,8 @@ auto to_json(const Template &schema_template) -> sourcemeta::core::JSON {
// Note that we purposely avoid objects to help consumers avoid potentially
// expensive hash-map or flat-map lookups when parsing back
auto result{sourcemeta::core::JSON::make_array()};
+ result.push_back(sourcemeta::core::JSON{
+ static_cast(sourcemeta::blaze::JSON_VERSION)});
result.push_back(sourcemeta::core::JSON{schema_template.dynamic});
result.push_back(sourcemeta::core::JSON{schema_template.track});
diff --git a/vendor/blaze/src/evaluator/evaluator_json.cc b/vendor/blaze/src/evaluator/evaluator_json.cc
index dc9720ea..62ef8159 100644
--- a/vendor/blaze/src/evaluator/evaluator_json.cc
+++ b/vendor/blaze/src/evaluator/evaluator_json.cc
@@ -119,18 +119,24 @@ auto instructions_from_json(
namespace sourcemeta::blaze {
auto from_json(const sourcemeta::core::JSON &json) -> std::optional {
- if (!json.is_array() || json.array_size() != 4) {
+ if (!json.is_array() || json.array_size() != 5) {
return std::nullopt;
}
- const auto &dynamic{json.at(0)};
- const auto &track{json.at(1)};
+ const auto &version{json.at(0)};
+ if (!version.is_integer() ||
+ version.to_integer() != static_cast(JSON_VERSION)) {
+ return std::nullopt;
+ }
+
+ const auto &dynamic{json.at(1)};
+ const auto &track{json.at(2)};
if (!dynamic.is_boolean() || !track.is_boolean()) {
return std::nullopt;
}
- const auto &targets{json.at(2)};
+ const auto &targets{json.at(3)};
if (!targets.is_array()) {
return std::nullopt;
}
@@ -146,7 +152,7 @@ auto from_json(const sourcemeta::core::JSON &json) -> std::optional {
targets_result.push_back(std::move(target_result).value());
}
- const auto &labels{json.at(3)};
+ const auto &labels{json.at(4)};
if (!labels.is_array()) {
return std::nullopt;
}
diff --git a/vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator.h b/vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator.h
index 4081c40f..04b9f380 100644
--- a/vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator.h
+++ b/vendor/blaze/src/evaluator/include/sourcemeta/blaze/evaluator.h
@@ -43,6 +43,9 @@ struct Template {
std::vector extra;
};
+/// @ingroup evaluator
+constexpr std::size_t JSON_VERSION{1};
+
/// @ingroup evaluator
/// Parse a template from JSON
auto SOURCEMETA_BLAZE_EVALUATOR_EXPORT