ata-validator 0.12.4 → 0.12.6
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/index.d.ts +6 -2
- package/index.js +39 -12
- package/lib/js-compiler.js +108 -6
- package/package.json +1 -1
- package/prebuilds/ata-darwin-arm64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-arm64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-arm64-musl/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-x64/node-napi-v10.node +0 -0
- package/prebuilds/ata-linux-x64-musl/node-napi-v10.node +0 -0
- package/prebuilds/ata-win32-x64/node-napi-v10.node +0 -0
- package/prebuilds/darwin-arm64/ata-validator.node +0 -0
package/index.d.ts
CHANGED
|
@@ -140,8 +140,12 @@ export class Validator {
|
|
|
140
140
|
*/
|
|
141
141
|
static bundleStandalone(schemas: object[], options?: BundleStandaloneOptions): string;
|
|
142
142
|
|
|
143
|
-
/**
|
|
144
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Bundle multiple schemas with deduplicated shared templates. Smaller output
|
|
145
|
+
* than bundle(). Accepts the same options as bundleStandalone, including
|
|
146
|
+
* `format: 'esm' | 'cjs'` and cross-schema `$ref` resolution.
|
|
147
|
+
*/
|
|
148
|
+
static bundleCompact(schemas: object[], options?: BundleStandaloneOptions): string;
|
|
145
149
|
|
|
146
150
|
/** Load a bundle created by Validator.bundle(). Returns array of Validator instances. */
|
|
147
151
|
static loadBundle(mods: object[], schemas: object[], options?: ValidatorOptions): Validator[];
|
package/index.js
CHANGED
|
@@ -1187,10 +1187,12 @@ Validator.bundle = function (schemas, opts) {
|
|
|
1187
1187
|
|
|
1188
1188
|
// Zero-dependency self-contained bundle — no require('ata-validator') needed at runtime.
|
|
1189
1189
|
// opts.format: 'cjs' (default) or 'esm'.
|
|
1190
|
+
// opts.formats: { name: fn } — embedded in the output via Function#toString.
|
|
1190
1191
|
Validator.bundleStandalone = function (schemas, opts) {
|
|
1191
|
-
// Cross-schema $ref resolution:
|
|
1192
|
-
//
|
|
1193
|
-
const
|
|
1192
|
+
// Cross-schema $ref resolution: only meaningful when at least one schema has
|
|
1193
|
+
// an $id. Skip the schemas-as-map plumbing when none of them do.
|
|
1194
|
+
const haveIds = schemas.some((s) => s && typeof s === 'object' && s.$id);
|
|
1195
|
+
const bundleOpts = haveIds ? { ...(opts || {}), schemas } : (opts || {});
|
|
1194
1196
|
const format = (opts && opts.format) || 'cjs';
|
|
1195
1197
|
const R = "Object.freeze({valid:true,errors:Object.freeze([])})";
|
|
1196
1198
|
const fns = schemas.map((schema) => {
|
|
@@ -1201,12 +1203,25 @@ Validator.bundleStandalone = function (schemas, opts) {
|
|
|
1201
1203
|
const jsErrFn = compileToJSCodegenWithErrors(
|
|
1202
1204
|
typeof schema === "string" ? JSON.parse(schema) : schema,
|
|
1203
1205
|
v._schemaMap,
|
|
1206
|
+
v._userFormats,
|
|
1204
1207
|
);
|
|
1205
1208
|
const errBody =
|
|
1206
1209
|
jsErrFn && jsErrFn._errSource
|
|
1207
1210
|
? jsErrFn._errSource
|
|
1208
1211
|
: "return{valid:false,errors:[{code:'error',path:'',message:'validation failed'}]}";
|
|
1209
|
-
|
|
1212
|
+
// Serialize custom format closures so the bundle has no runtime dep on ata.
|
|
1213
|
+
let preamble = '';
|
|
1214
|
+
if (jsFn._formatClosures) {
|
|
1215
|
+
preamble = jsFn._formatClosures
|
|
1216
|
+
.map(({ name, fn }) => `var ${name}=${fn.toString()};`)
|
|
1217
|
+
.join('\n');
|
|
1218
|
+
}
|
|
1219
|
+
if (opts && opts.verbose) {
|
|
1220
|
+
// Embed the schema and a small resolver so errors carry parentSchema.
|
|
1221
|
+
const schemaLit = JSON.stringify(typeof schema === 'string' ? JSON.parse(schema) : schema);
|
|
1222
|
+
return `(function(R){${preamble}var _S=${schemaLit};function _PS(p){if(!p||p[0]!=='#')return undefined;var s=p.slice(1);if(!s)return _S;var ps=s.split('/').filter(Boolean).map(function(x){return x.replace(/~1/g,'/').replace(/~0/g,'~')});var t=_S;for(var i=0;i<ps.length-1;i++){if(t==null||typeof t!=='object')return undefined;t=t[ps[i]]}return t}var E=function(d){var _all=true;${errBody}};var _v=function(d){${jsFn._hybridSource}};return function(d){var r=_v(d);if(r&&r.valid===false&&r.errors){var es=[];for(var i=0;i<r.errors.length;i++){var e=r.errors[i];es.push(Object.assign({},e,{parentSchema:_PS(e.schemaPath)}))}return{valid:false,errors:es}}return r}})(R)`;
|
|
1223
|
+
}
|
|
1224
|
+
return `(function(R){${preamble}var E=function(d){var _all=true;${errBody}};return function(d){${jsFn._hybridSource}}})(R)`;
|
|
1210
1225
|
});
|
|
1211
1226
|
const arr = `[${fns.join(",")}]`;
|
|
1212
1227
|
if (format === 'esm') {
|
|
@@ -1217,15 +1232,20 @@ Validator.bundleStandalone = function (schemas, opts) {
|
|
|
1217
1232
|
|
|
1218
1233
|
// Compact bundle: deduplicated code. Shared template functions + per-schema params.
|
|
1219
1234
|
// Much smaller file → faster V8 parse → faster startup.
|
|
1235
|
+
// opts.format: 'cjs' (default) or 'esm'.
|
|
1220
1236
|
Validator.bundleCompact = function (schemas, opts) {
|
|
1237
|
+
const haveIds = schemas.some((s) => s && typeof s === 'object' && s.$id);
|
|
1238
|
+
const bundleOpts = haveIds ? { ...(opts || {}), schemas } : (opts || {});
|
|
1239
|
+
const format = (opts && opts.format) || 'cjs';
|
|
1221
1240
|
// Analyze schemas and group by structure
|
|
1222
1241
|
const entries = schemas.map((schema) => {
|
|
1223
|
-
const v = new Validator(schema,
|
|
1242
|
+
const v = new Validator(schema, bundleOpts);
|
|
1224
1243
|
v._ensureCompiled();
|
|
1225
1244
|
const jsFn = v._jsFn;
|
|
1226
1245
|
if (!jsFn || !jsFn._hybridSource) return null;
|
|
1227
1246
|
const jsErrFn = compileToJSCodegenWithErrors(
|
|
1228
1247
|
typeof schema === "string" ? JSON.parse(schema) : schema,
|
|
1248
|
+
v._schemaMap,
|
|
1229
1249
|
);
|
|
1230
1250
|
return {
|
|
1231
1251
|
hybrid: jsFn._hybridSource,
|
|
@@ -1260,31 +1280,38 @@ Validator.bundleCompact = function (schemas, opts) {
|
|
|
1260
1280
|
});
|
|
1261
1281
|
|
|
1262
1282
|
// Generate compact bundle
|
|
1263
|
-
|
|
1264
|
-
out
|
|
1283
|
+
const isEsm = format === 'esm';
|
|
1284
|
+
let out = isEsm
|
|
1285
|
+
? "// Auto-generated by ata-validator — do not edit\n"
|
|
1286
|
+
: "'use strict';\n";
|
|
1287
|
+
const declKW = isEsm ? "const" : "var";
|
|
1288
|
+
out += `${declKW} R=Object.freeze({valid:true,errors:Object.freeze([])});\n`;
|
|
1265
1289
|
|
|
1266
1290
|
// Shared hybrid factories
|
|
1267
|
-
out +=
|
|
1291
|
+
out += `${declKW} H=[\n`;
|
|
1268
1292
|
out += bodies
|
|
1269
1293
|
.map((b) => `function(R,E){return function(d){${b}}}`)
|
|
1270
1294
|
.join(",\n");
|
|
1271
1295
|
out += "\n];\n";
|
|
1272
1296
|
|
|
1273
1297
|
// Shared error functions
|
|
1274
|
-
out +=
|
|
1298
|
+
out += `${declKW} EF=[\n`;
|
|
1275
1299
|
out += errBodies.map((b) => `function(d){var _all=true;${b}}`).join(",\n");
|
|
1276
1300
|
out += "\n];\n";
|
|
1277
1301
|
|
|
1278
1302
|
// Build validators from shared templates
|
|
1279
|
-
|
|
1280
|
-
out += indices
|
|
1303
|
+
const arrBody = indices
|
|
1281
1304
|
.map(([hi, ei]) => {
|
|
1282
1305
|
if (hi < 0) return "null";
|
|
1283
1306
|
if (ei >= 0) return `H[${hi}](R,EF[${ei}])`;
|
|
1284
1307
|
return `H[${hi}](R,function(){return{valid:false,errors:[]}})`;
|
|
1285
1308
|
})
|
|
1286
1309
|
.join(",");
|
|
1287
|
-
|
|
1310
|
+
if (isEsm) {
|
|
1311
|
+
out += `const validators=[${arrBody}];\nexport default validators;\nexport { validators };\n`;
|
|
1312
|
+
} else {
|
|
1313
|
+
out += `module.exports=[${arrBody}];\n`;
|
|
1314
|
+
}
|
|
1288
1315
|
|
|
1289
1316
|
return out;
|
|
1290
1317
|
};
|
package/lib/js-compiler.js
CHANGED
|
@@ -496,6 +496,50 @@ function collectDefs(schema) {
|
|
|
496
496
|
return defs
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
+
// Walk a JSON-pointer fragment ("/foo/bar/0") into a schema object.
|
|
500
|
+
// Returns the target node, or null if any segment is missing.
|
|
501
|
+
function walkJsonPointer(root, fragment) {
|
|
502
|
+
if (!fragment || fragment === '/' || fragment === '#') return root
|
|
503
|
+
const path = fragment.startsWith('#') ? fragment.slice(1) : fragment
|
|
504
|
+
if (!path.startsWith('/')) return null
|
|
505
|
+
const parts = path.split('/').slice(1).map(s => s.replace(/~1/g, '/').replace(/~0/g, '~'))
|
|
506
|
+
let target = root
|
|
507
|
+
for (const p of parts) {
|
|
508
|
+
if (target == null || typeof target !== 'object') return null
|
|
509
|
+
target = target[p]
|
|
510
|
+
}
|
|
511
|
+
return target == null ? null : target
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Resolve a cross-schema $ref of the form "<id>#/<json-pointer>" (or just "<id>").
|
|
515
|
+
// Returns { schema, fullId } where fullId is the resolved $id of the host schema.
|
|
516
|
+
function resolveCrossSchemaRef(ref, schemaMap) {
|
|
517
|
+
if (!schemaMap) return null
|
|
518
|
+
const hashIdx = ref.indexOf('#')
|
|
519
|
+
const baseId = hashIdx >= 0 ? ref.slice(0, hashIdx) : ref
|
|
520
|
+
const fragment = hashIdx >= 0 ? ref.slice(hashIdx) : ''
|
|
521
|
+
if (!baseId) return null
|
|
522
|
+
|
|
523
|
+
let baseSchema = null
|
|
524
|
+
let fullId = null
|
|
525
|
+
if (schemaMap.has(baseId)) {
|
|
526
|
+
baseSchema = schemaMap.get(baseId)
|
|
527
|
+
fullId = baseId
|
|
528
|
+
} else if (!ref.includes('://')) {
|
|
529
|
+
for (const [id] of schemaMap) {
|
|
530
|
+
if (id.endsWith('/' + baseId)) {
|
|
531
|
+
baseSchema = schemaMap.get(id)
|
|
532
|
+
fullId = id
|
|
533
|
+
break
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (!baseSchema) return null
|
|
538
|
+
const target = fragment ? walkJsonPointer(baseSchema, fragment) : baseSchema
|
|
539
|
+
if (target == null) return null
|
|
540
|
+
return { schema: target, fullId }
|
|
541
|
+
}
|
|
542
|
+
|
|
499
543
|
function resolveRef(ref, defs, schemaMap) {
|
|
500
544
|
// Self-reference: "#" — treat as permissive to avoid infinite recursion
|
|
501
545
|
if (ref === '#') return () => true
|
|
@@ -520,7 +564,15 @@ function resolveRef(ref, defs, schemaMap) {
|
|
|
520
564
|
const fn = compileToJS(resolved, null, schemaMap)
|
|
521
565
|
return fn || (() => true)
|
|
522
566
|
}
|
|
523
|
-
// 3. Cross-schema ref
|
|
567
|
+
// 3. Cross-schema ref with JSON pointer fragment ("<id>#/<path>")
|
|
568
|
+
if (schemaMap && ref.includes('#')) {
|
|
569
|
+
const r = resolveCrossSchemaRef(ref, schemaMap)
|
|
570
|
+
if (r) {
|
|
571
|
+
const fn = compileToJS(r.schema, null, schemaMap)
|
|
572
|
+
return fn || (() => true)
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
// 4. Cross-schema ref (relative URI resolution, no fragment)
|
|
524
576
|
if (schemaMap && !ref.includes('://') && !ref.startsWith('#')) {
|
|
525
577
|
for (const [id] of schemaMap) {
|
|
526
578
|
if (id.endsWith('/' + ref)) {
|
|
@@ -652,6 +704,11 @@ function codegenSafe(schema, schemaMap) {
|
|
|
652
704
|
if (id.endsWith('/' + schema.$ref)) { isResolvable = true; resolvedTarget = schemaMap.get(id); break }
|
|
653
705
|
}
|
|
654
706
|
}
|
|
707
|
+
// Cross-schema ref with JSON pointer fragment: "<id>#/<path>"
|
|
708
|
+
if (!isLocal && !isResolvable && schemaMap && schema.$ref.includes('#') && !schema.$ref.startsWith('#')) {
|
|
709
|
+
const r = resolveCrossSchemaRef(schema.$ref, schemaMap)
|
|
710
|
+
if (r) { isResolvable = true; resolvedTarget = r.schema }
|
|
711
|
+
}
|
|
655
712
|
// Anchor-style ref: #name (not #/path, not bare #) — resolvable at compile time via anchors map
|
|
656
713
|
const isAnchorRef = !isLocal && !isResolvable && schema.$ref.length > 1 && schema.$ref.startsWith('#') && !schema.$ref.startsWith('#/')
|
|
657
714
|
if (!isLocal && !isResolvable && !isAnchorRef) return false
|
|
@@ -889,6 +946,17 @@ function compileToJSCodegen(schema, schemaMap, userFormats) {
|
|
|
889
946
|
boolFn._source = helperStr + body
|
|
890
947
|
boolFn._preambleSource = preambleStr
|
|
891
948
|
boolFn._hybridSource = helperStr + hybridBody
|
|
949
|
+
// Custom-format closure entries that the bundle output needs to recreate.
|
|
950
|
+
// Stored as { name, fn } so consumers can serialize via Function#toString.
|
|
951
|
+
if (ctx.userFormats) {
|
|
952
|
+
const fmtEntries = []
|
|
953
|
+
for (let i = 0; i < closureNames.length; i++) {
|
|
954
|
+
if (closureNames[i].startsWith('_uf_')) {
|
|
955
|
+
fmtEntries.push({ name: closureNames[i], fn: closureValues[i] })
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
if (fmtEntries.length) boolFn._formatClosures = fmtEntries
|
|
959
|
+
}
|
|
892
960
|
|
|
893
961
|
return boolFn
|
|
894
962
|
} catch {
|
|
@@ -1093,13 +1161,17 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1093
1161
|
}
|
|
1094
1162
|
}
|
|
1095
1163
|
} else if (schema.$ref !== '#' && ctx.schemaMap) {
|
|
1096
|
-
// 2. Cross-schema ref (exact match or
|
|
1164
|
+
// 2. Cross-schema ref (exact match, relative URI, or JSON pointer fragment)
|
|
1097
1165
|
let resolved = ctx.schemaMap.get(schema.$ref)
|
|
1098
1166
|
if (!resolved && !schema.$ref.includes('://') && !schema.$ref.startsWith('#')) {
|
|
1099
1167
|
for (const [id, s] of ctx.schemaMap) {
|
|
1100
1168
|
if (id.endsWith('/' + schema.$ref)) { resolved = s; break }
|
|
1101
1169
|
}
|
|
1102
1170
|
}
|
|
1171
|
+
if (!resolved && schema.$ref.includes('#') && !schema.$ref.startsWith('#')) {
|
|
1172
|
+
const r = resolveCrossSchemaRef(schema.$ref, ctx.schemaMap)
|
|
1173
|
+
if (r) resolved = r.schema
|
|
1174
|
+
}
|
|
1103
1175
|
if (resolved) {
|
|
1104
1176
|
if (ctx.refStack.has(schema.$ref)) { if (!hasSiblings) return }
|
|
1105
1177
|
else {
|
|
@@ -2387,7 +2459,7 @@ function genCharCodeSwitch(keys, v) {
|
|
|
2387
2459
|
// --- Error-collecting codegen: same checks, but pushes errors instead of returning false ---
|
|
2388
2460
|
// Returns a function: (data, allErrors) => { valid, errors }
|
|
2389
2461
|
// Valid path is still fast — only error path does extra work.
|
|
2390
|
-
function compileToJSCodegenWithErrors(schema, schemaMap) {
|
|
2462
|
+
function compileToJSCodegenWithErrors(schema, schemaMap, userFormats) {
|
|
2391
2463
|
// Bail on unevaluated keywords — error codegen doesn't support them yet
|
|
2392
2464
|
if (typeof schema === 'object' && schema !== null) {
|
|
2393
2465
|
const s = JSON.stringify(schema)
|
|
@@ -2448,7 +2520,7 @@ function compileToJSCodegenWithErrors(schema, schemaMap) {
|
|
|
2448
2520
|
}
|
|
2449
2521
|
}
|
|
2450
2522
|
|
|
2451
|
-
const ctx = { varCounter: 0, helperCode: [], rootDefs: eRootDefs, refStack: new Set(), schemaMap: schemaMap || null, anchors: eAnchors, rootSchema: schema }
|
|
2523
|
+
const ctx = { varCounter: 0, helperCode: [], rootDefs: eRootDefs, refStack: new Set(), schemaMap: schemaMap || null, anchors: eAnchors, rootSchema: schema, userFormats: userFormats || null }
|
|
2452
2524
|
ctx.helperCode.push('const _cpLen=s=>{let n=0;for(const _ of s)n++;return n}')
|
|
2453
2525
|
const lines = []
|
|
2454
2526
|
genCodeE(schema, 'd', '', lines, ctx, '#')
|
|
@@ -2516,6 +2588,17 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
2516
2588
|
ctx.refStack.delete(schema.$ref)
|
|
2517
2589
|
return
|
|
2518
2590
|
}
|
|
2591
|
+
// Cross-schema ref with JSON pointer fragment ("<id>#/<path>")
|
|
2592
|
+
if (ctx.schemaMap && schema.$ref.includes('#') && !schema.$ref.startsWith('#')) {
|
|
2593
|
+
const r = resolveCrossSchemaRef(schema.$ref, ctx.schemaMap)
|
|
2594
|
+
if (r) {
|
|
2595
|
+
if (ctx.refStack.has(schema.$ref)) return
|
|
2596
|
+
ctx.refStack.add(schema.$ref)
|
|
2597
|
+
genCodeE(r.schema, v, pathExpr, lines, ctx, schemaPrefix)
|
|
2598
|
+
ctx.refStack.delete(schema.$ref)
|
|
2599
|
+
return
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2519
2602
|
}
|
|
2520
2603
|
|
|
2521
2604
|
// $dynamicRef — resolve via anchors map
|
|
@@ -2661,15 +2744,23 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
2661
2744
|
}
|
|
2662
2745
|
if (schema.format) {
|
|
2663
2746
|
const fc = FORMAT_CODEGEN[schema.format]
|
|
2747
|
+
const failPush = `_e.push({keyword:'format',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/format',params:{format:'${esc(schema.format)}'},message:'must match format "${esc(schema.format)}"'});if(!_all)return{valid:false,errors:_e}`
|
|
2664
2748
|
// Format errors use the boolean codegen — just wrap with error push
|
|
2665
2749
|
if (fc) {
|
|
2666
2750
|
const ri = ctx.varCounter++
|
|
2667
2751
|
const boolLines = []
|
|
2668
2752
|
boolLines.push(fc(v, isStr))
|
|
2669
2753
|
// Replace `return false` with error push in the format check
|
|
2670
|
-
const fmtCode = boolLines.join(';').replace(/return false/g,
|
|
2671
|
-
`{_e.push({keyword:'format',instancePath:${pathExpr||'""'},schemaPath:'${schemaPrefix}/format',params:{format:'${esc(schema.format)}'},message:'must match format "${esc(schema.format)}"'});if(!_all)return{valid:false,errors:_e}}`)
|
|
2754
|
+
const fmtCode = boolLines.join(';').replace(/return false/g, `{${failPush}}`)
|
|
2672
2755
|
lines.push(fmtCode)
|
|
2756
|
+
} else if (ctx.userFormats && typeof ctx.userFormats[schema.format] === 'function') {
|
|
2757
|
+
// User-supplied format checker on the error path. Same closure plumbing
|
|
2758
|
+
// as the boolean codegen — but error codegen has no closure factory, so
|
|
2759
|
+
// bundle output serializes the function via Function#toString separately.
|
|
2760
|
+
const safeName = schema.format.replace(/[^a-zA-Z0-9_]/g, '_')
|
|
2761
|
+
const closureName = `_uf_${safeName}`
|
|
2762
|
+
const guard = isStr ? '' : `typeof ${v}==='string'&&`
|
|
2763
|
+
lines.push(`if(${guard}!${closureName}(${v})){${failPush}}`)
|
|
2673
2764
|
}
|
|
2674
2765
|
}
|
|
2675
2766
|
|
|
@@ -3022,6 +3113,17 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3022
3113
|
ctx.refStack.delete(schema.$ref)
|
|
3023
3114
|
return
|
|
3024
3115
|
}
|
|
3116
|
+
// Cross-schema ref with JSON pointer fragment ("<id>#/<path>")
|
|
3117
|
+
if (ctx.schemaMap && schema.$ref.includes('#') && !schema.$ref.startsWith('#')) {
|
|
3118
|
+
const r = resolveCrossSchemaRef(schema.$ref, ctx.schemaMap)
|
|
3119
|
+
if (r) {
|
|
3120
|
+
if (ctx.refStack.has(schema.$ref)) return
|
|
3121
|
+
ctx.refStack.add(schema.$ref)
|
|
3122
|
+
genCodeC(r.schema, v, pathExpr, lines, ctx, schemaPrefix)
|
|
3123
|
+
ctx.refStack.delete(schema.$ref)
|
|
3124
|
+
return
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3025
3127
|
}
|
|
3026
3128
|
|
|
3027
3129
|
// $dynamicRef — resolve via anchors map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.6",
|
|
4
4
|
"description": "Ultra-fast JSON Schema validator. 5x faster validation, 159,000x faster compilation. Works without native addon. Cross-schema $ref, Draft 2020-12 + Draft 7, V8-optimized JS codegen, simdjson, RE2, multi-core. Standard Schema V1 compatible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|