ata-validator 1.6.2 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +15 -5
- package/build.d.ts +12 -0
- package/index.d.ts +7 -0
- package/index.js +178 -57
- package/lib/aot-build.js +1 -0
- package/lib/aot.js +70 -20
- package/lib/buffer-gate.js +132 -0
- package/lib/draft7.js +24 -2
- package/lib/interpreter.js +644 -208
- package/lib/js-compiler.js +187 -55
- package/lib/metaschemas.js +21 -0
- package/lib/plan-compiler.js +545 -0
- package/lib/safe-regex-source.js +1 -1
- package/lib/safe-regex.js +209 -29
- package/lib/version.js +1 -1
- package/package.json +8 -8
package/lib/js-compiler.js
CHANGED
|
@@ -53,7 +53,8 @@ function buildErrorLiteral (opts) {
|
|
|
53
53
|
function _cpLen(s) {
|
|
54
54
|
const len = s.length;
|
|
55
55
|
for (let i = 0; i < len; i++) {
|
|
56
|
-
|
|
56
|
+
// Wraparound test: one compare classifies a high surrogate.
|
|
57
|
+
if (((s.charCodeAt(i) - 0xD800) >>> 0) < 0x400) {
|
|
57
58
|
// Found a high surrogate — count code points the slow way
|
|
58
59
|
let n = 0; for (const _ of s) n++; return n;
|
|
59
60
|
}
|
|
@@ -108,6 +109,14 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
if (!defs && needsBaseTracking(schema, schemaMap, new Set())) return null
|
|
112
|
+
if (!defs && externalDocsNeedInterpreter(schema, schemaMap)) return null
|
|
113
|
+
|
|
114
|
+
// unevaluatedProperties / unevaluatedItems need annotation tracking this
|
|
115
|
+
// path does not do. Decline so the schema reaches an engine that does.
|
|
116
|
+
if (!defs) {
|
|
117
|
+
const str = JSON.stringify(schema)
|
|
118
|
+
if (str.includes('"unevaluatedProperties"') || str.includes('"unevaluatedItems"')) return null
|
|
119
|
+
}
|
|
111
120
|
|
|
112
121
|
// Collect $defs early so sub-schemas can resolve $ref
|
|
113
122
|
const rootDefs = defs || collectDefs(schema)
|
|
@@ -158,13 +167,13 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
158
167
|
const primitives = vals.filter(v => v === null || typeof v !== 'object')
|
|
159
168
|
const objects = vals.filter(v => v !== null && typeof v === 'object')
|
|
160
169
|
const primSet = new Set(primitives.map(v => v === null ? 'null' : typeof v === 'string' ? 's:' + v : 'n:' + v))
|
|
161
|
-
const objStrs = objects.map(v =>
|
|
170
|
+
const objStrs = objects.map(v => _canonical(v))
|
|
162
171
|
checks.push((d) => {
|
|
163
172
|
// Fast primitive check
|
|
164
173
|
const key = d === null ? 'null' : typeof d === 'string' ? 's:' + d : typeof d === 'number' || typeof d === 'boolean' ? 'n:' + d : null
|
|
165
174
|
if (key !== null && primSet.has(key)) return true
|
|
166
|
-
// Slow object check
|
|
167
|
-
const ds =
|
|
175
|
+
// Slow object check, key order independent
|
|
176
|
+
const ds = _canonical(d)
|
|
168
177
|
for (let i = 0; i < objStrs.length; i++) {
|
|
169
178
|
if (ds === objStrs[i]) return true
|
|
170
179
|
}
|
|
@@ -182,15 +191,15 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
182
191
|
if (cv === null || typeof cv !== 'object') {
|
|
183
192
|
checks.push((d) => d === cv)
|
|
184
193
|
} else {
|
|
185
|
-
const cs =
|
|
186
|
-
checks.push((d) =>
|
|
194
|
+
const cs = _canonical(cv)
|
|
195
|
+
checks.push((d) => _canonical(d) === cs)
|
|
187
196
|
}
|
|
188
197
|
}
|
|
189
198
|
|
|
190
|
-
// required
|
|
199
|
+
// required applies to objects only; other types are ignored.
|
|
191
200
|
if (schema.required && Array.isArray(schema.required)) {
|
|
192
201
|
for (const key of schema.required) {
|
|
193
|
-
checks.push((d) => typeof d
|
|
202
|
+
checks.push((d) => typeof d !== 'object' || d === null || Array.isArray(d) || d[key] !== undefined)
|
|
194
203
|
}
|
|
195
204
|
}
|
|
196
205
|
|
|
@@ -206,10 +215,10 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
206
215
|
}
|
|
207
216
|
}
|
|
208
217
|
|
|
209
|
-
// additionalProperties
|
|
210
|
-
if (schema.additionalProperties !== undefined
|
|
218
|
+
// additionalProperties (with or without a properties map)
|
|
219
|
+
if (schema.additionalProperties !== undefined) {
|
|
211
220
|
if (schema.additionalProperties === false) {
|
|
212
|
-
const allowed = new Set(Object.keys(schema.properties))
|
|
221
|
+
const allowed = new Set(Object.keys(schema.properties || {}))
|
|
213
222
|
checks.push((d) => {
|
|
214
223
|
if (typeof d !== 'object' || d === null || Array.isArray(d)) return true
|
|
215
224
|
const keys = Object.keys(d)
|
|
@@ -246,13 +255,14 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
246
255
|
}
|
|
247
256
|
}
|
|
248
257
|
|
|
249
|
-
// items
|
|
258
|
+
// items, applied after the prefixItems positions
|
|
250
259
|
if (schema.items) {
|
|
251
260
|
const itemCheck = compileToJS(schema.items, rootDefs)
|
|
252
261
|
if (!itemCheck) return null
|
|
262
|
+
const start = Array.isArray(schema.prefixItems) ? schema.prefixItems.length : 0
|
|
253
263
|
checks.push((d) => {
|
|
254
264
|
if (!Array.isArray(d)) return true
|
|
255
|
-
for (let i =
|
|
265
|
+
for (let i = start; i < d.length; i++) {
|
|
256
266
|
if (!itemCheck(d[i])) return false
|
|
257
267
|
}
|
|
258
268
|
return true
|
|
@@ -330,7 +340,11 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
330
340
|
}
|
|
331
341
|
if (schema.multipleOf !== undefined) {
|
|
332
342
|
const div = schema.multipleOf
|
|
333
|
-
checks.push((d) =>
|
|
343
|
+
checks.push((d) => {
|
|
344
|
+
if (typeof d !== 'number') return true
|
|
345
|
+
const r = d % div
|
|
346
|
+
return Math.abs(r) <= 1e-8 || Math.abs(r - div) <= 1e-8
|
|
347
|
+
})
|
|
334
348
|
}
|
|
335
349
|
|
|
336
350
|
// string
|
|
@@ -341,7 +355,7 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
341
355
|
}
|
|
342
356
|
if (schema.maxLength !== undefined) {
|
|
343
357
|
const max = schema.maxLength
|
|
344
|
-
checks.push((d) => typeof d !== 'string' || d.length <= max || _cpLen(d) <= max)
|
|
358
|
+
checks.push((d) => typeof d !== 'string' || d.length <= max || (d.length <= 2 * max + 1 && _cpLen(d) <= max))
|
|
345
359
|
}
|
|
346
360
|
if (schema.pattern) {
|
|
347
361
|
try {
|
|
@@ -352,10 +366,12 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
352
366
|
}
|
|
353
367
|
}
|
|
354
368
|
|
|
355
|
-
// format — hand-written fast checks
|
|
369
|
+
// format — hand-written fast checks. A format the code generator asserts
|
|
370
|
+
// but this path cannot is a decline, not a pass.
|
|
356
371
|
if (schema.format) {
|
|
357
372
|
const fc = FORMAT_CHECKS[schema.format]
|
|
358
373
|
if (fc) checks.push((d) => typeof d !== 'string' || fc(d))
|
|
374
|
+
else if (FORMAT_CODEGEN[schema.format]) return null
|
|
359
375
|
}
|
|
360
376
|
|
|
361
377
|
// array size
|
|
@@ -371,11 +387,11 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
371
387
|
// object size
|
|
372
388
|
if (schema.minProperties !== undefined) {
|
|
373
389
|
const min = schema.minProperties
|
|
374
|
-
checks.push((d) => typeof d !== 'object' || d === null || Object.keys(d).length >= min)
|
|
390
|
+
checks.push((d) => typeof d !== 'object' || d === null || Array.isArray(d) || Object.keys(d).length >= min)
|
|
375
391
|
}
|
|
376
392
|
if (schema.maxProperties !== undefined) {
|
|
377
393
|
const max = schema.maxProperties
|
|
378
|
-
checks.push((d) => typeof d !== 'object' || d === null || Object.keys(d).length <= max)
|
|
394
|
+
checks.push((d) => typeof d !== 'object' || d === null || Array.isArray(d) || Object.keys(d).length <= max)
|
|
379
395
|
}
|
|
380
396
|
|
|
381
397
|
// allOf
|
|
@@ -558,7 +574,7 @@ function walkJsonPointer(root, fragment) {
|
|
|
558
574
|
for (const p of parts) {
|
|
559
575
|
if (target == null || typeof target !== 'object') return null
|
|
560
576
|
if (!(p in target)) {
|
|
561
|
-
const alt = p === 'definitions' ? '$defs' : p === '$defs' ? 'definitions' : null
|
|
577
|
+
const alt = p === 'definitions' ? '$defs' : p === '$defs' ? 'definitions' : p === 'items' && Array.isArray(target.prefixItems) ? 'prefixItems' : null
|
|
562
578
|
if (alt !== null && alt in target) { target = target[alt]; continue }
|
|
563
579
|
return null
|
|
564
580
|
}
|
|
@@ -597,8 +613,9 @@ function resolveCrossSchemaRef(ref, schemaMap) {
|
|
|
597
613
|
}
|
|
598
614
|
|
|
599
615
|
function resolveRef(ref, defs, schemaMap) {
|
|
600
|
-
// Self-reference: "#"
|
|
601
|
-
|
|
616
|
+
// Self-reference: "#" cannot be expressed as a closure without a recursion
|
|
617
|
+
// guard. Decline rather than substitute a vacuous check.
|
|
618
|
+
if (ref === '#') return null
|
|
602
619
|
|
|
603
620
|
// 1. Local ref
|
|
604
621
|
if (defs) {
|
|
@@ -660,6 +677,13 @@ const TYPE_CHECKS = {
|
|
|
660
677
|
object: (d) => typeof d === 'object' && d !== null && !Array.isArray(d),
|
|
661
678
|
}
|
|
662
679
|
|
|
680
|
+
// Key-order independent JSON rendering for const/enum comparison.
|
|
681
|
+
function _canonical(x) {
|
|
682
|
+
if (x === null || typeof x !== 'object') return JSON.stringify(x)
|
|
683
|
+
if (Array.isArray(x)) return '[' + x.map(_canonical).join(',') + ']'
|
|
684
|
+
return '{' + Object.keys(x).sort().map((k) => JSON.stringify(k) + ':' + _canonical(x[k])).join(',') + '}'
|
|
685
|
+
}
|
|
686
|
+
|
|
663
687
|
const FORMAT_CHECKS = {
|
|
664
688
|
email: (s) => { const at = s.indexOf('@'); return at > 0 && at < s.length - 1 && s.indexOf('.', at) > at + 1 },
|
|
665
689
|
date: (s) => { if (s.length !== 10 || !/^\d{4}-\d{2}-\d{2}$/.test(s)) return false; const m = +s.slice(5, 7), d = +s.slice(8, 10); return m >= 1 && m <= 12 && d >= 1 && d <= 31 },
|
|
@@ -1147,14 +1171,85 @@ function hasUnresolvableRef(node, rootDefs, anchors, schemaMap, seen) {
|
|
|
1147
1171
|
return false
|
|
1148
1172
|
}
|
|
1149
1173
|
|
|
1174
|
+
|
|
1175
|
+
// --- The one gate every code generation entry point runs first ---
|
|
1176
|
+
//
|
|
1177
|
+
// Four entry points build four contexts, and three times a bail present in
|
|
1178
|
+
// one was missing from another; each time the generator emitted nothing for
|
|
1179
|
+
// a construct it could not represent and returned the empty program as
|
|
1180
|
+
// always-valid. The checks that do not depend on an entry point's own anchor
|
|
1181
|
+
// map live here, so adding a bail is one edit. Entry-point-specific checks
|
|
1182
|
+
// (hasUnresolvableRef against each path's anchors) still run after this.
|
|
1183
|
+
// tests/test_codegen_entrypoint_agreement.js holds the four to one verdict.
|
|
1184
|
+
|
|
1185
|
+
function collectExternalRefKeys(node, out, seen) {
|
|
1186
|
+
if (typeof node !== 'object' || node === null) return
|
|
1187
|
+
if (seen.has(node)) return
|
|
1188
|
+
seen.add(node)
|
|
1189
|
+
if (Array.isArray(node)) { for (const n of node) collectExternalRefKeys(n, out, seen); return }
|
|
1190
|
+
for (const key of Object.keys(node)) {
|
|
1191
|
+
const v = node[key]
|
|
1192
|
+
if ((key === '$ref' || key === '$dynamicRef') && typeof v === 'string' && !v.startsWith('#')) out.add(v.split('#')[0])
|
|
1193
|
+
else if (typeof v === 'object' && v !== null && key !== 'enum' && key !== 'const' && key !== 'default' && key !== 'examples') collectExternalRefKeys(v, out, seen)
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
function lookupExternal(key, schemaMap) {
|
|
1198
|
+
if (schemaMap.has(key)) return schemaMap.get(key)
|
|
1199
|
+
if (!key.includes('://')) {
|
|
1200
|
+
for (const [id, doc] of schemaMap) if (id.endsWith('/' + key)) return doc
|
|
1201
|
+
}
|
|
1202
|
+
return null
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// Documents reachable from `schema` through cross-document references.
|
|
1206
|
+
function reachableExternalDocs(schema, schemaMap) {
|
|
1207
|
+
const docs = new Set()
|
|
1208
|
+
if (!schemaMap || schemaMap.size === 0) return docs
|
|
1209
|
+
const queue = [schema]
|
|
1210
|
+
const seenDocs = new Set([schema])
|
|
1211
|
+
while (queue.length) {
|
|
1212
|
+
const doc = queue.shift()
|
|
1213
|
+
const keys = new Set()
|
|
1214
|
+
collectExternalRefKeys(doc, keys, new Set())
|
|
1215
|
+
for (const key of keys) {
|
|
1216
|
+
const target = lookupExternal(key, schemaMap)
|
|
1217
|
+
if (target && !seenDocs.has(target)) { seenDocs.add(target); docs.add(target); queue.push(target) }
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return docs
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// Dynamic scope and annotation tracking across documents is interpreter
|
|
1224
|
+
// work. A referenced document that uses either must decline the whole
|
|
1225
|
+
// schema, or the generator emits a vacuous check for the reference.
|
|
1226
|
+
function externalDocsNeedInterpreter(schema, schemaMap) {
|
|
1227
|
+
for (const doc of reachableExternalDocs(schema, schemaMap)) {
|
|
1228
|
+
const str = JSON.stringify(doc)
|
|
1229
|
+
if (str.includes('"$dynamicRef"') || str.includes('"$dynamicAnchor"') ||
|
|
1230
|
+
str.includes('"unevaluatedProperties"') || str.includes('"unevaluatedItems"')) return true
|
|
1231
|
+
// An embedded $id inside a referenced document opens a resource the
|
|
1232
|
+
// generator never registers, so references to it would be vacuous.
|
|
1233
|
+
if (typeof doc === 'object' && doc !== null && hasNestedIdScope(doc)) return true
|
|
1234
|
+
}
|
|
1235
|
+
return false
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
function sharedCodegenGate(schema, schemaMap) {
|
|
1239
|
+
if (typeof schema !== 'object' || schema === null) return true
|
|
1240
|
+
if (!codegenSafe(schema, schemaMap)) return false
|
|
1241
|
+
if (needsBaseTracking(schema, schemaMap, new Set())) return false
|
|
1242
|
+
if (externalDocsNeedInterpreter(schema, schemaMap)) return false
|
|
1243
|
+
return true
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1150
1246
|
// --- Codegen mode: generates a single Function (NOT CSP-safe) ---
|
|
1151
1247
|
// This matches ajv's approach: one monolithic function, V8 JIT fully inlines it
|
|
1152
1248
|
function compileToJSCodegen(schema, schemaMap, userFormats) {
|
|
1153
1249
|
if (typeof schema === 'boolean') return schema ? () => true : () => false
|
|
1154
1250
|
if (typeof schema !== 'object' || schema === null) return null
|
|
1155
1251
|
|
|
1156
|
-
|
|
1157
|
-
if (!codegenSafe(schema, schemaMap)) return null
|
|
1252
|
+
if (!sharedCodegenGate(schema, schemaMap)) return null
|
|
1158
1253
|
|
|
1159
1254
|
// Collect defs for $ref resolution
|
|
1160
1255
|
const rootDefs = schema.$defs || schema.definitions || null
|
|
@@ -1290,7 +1385,13 @@ function compileToJSCodegen(schema, schemaMap, userFormats) {
|
|
|
1290
1385
|
const fmtEntries = []
|
|
1291
1386
|
for (let i = 0; i < closureNames.length; i++) {
|
|
1292
1387
|
if (closureNames[i].startsWith('_uf_')) {
|
|
1293
|
-
|
|
1388
|
+
// The format's own name, so an emitter can look it up at runtime
|
|
1389
|
+
// instead of embedding the function.
|
|
1390
|
+
let format = null
|
|
1391
|
+
for (const key of Object.keys(ctx.userFormats)) {
|
|
1392
|
+
if (ctx.userFormats[key] === closureValues[i]) { format = key; break }
|
|
1393
|
+
}
|
|
1394
|
+
fmtEntries.push({ name: closureNames[i], fn: closureValues[i], format })
|
|
1294
1395
|
}
|
|
1295
1396
|
}
|
|
1296
1397
|
if (fmtEntries.length) boolFn._formatClosures = fmtEntries
|
|
@@ -1434,7 +1535,7 @@ function tryGenCombined(schema, access, ctx) {
|
|
|
1434
1535
|
if (schema.maximum !== undefined) conds.push(`_v>${schema.maximum}`)
|
|
1435
1536
|
if (schema.exclusiveMinimum !== undefined) conds.push(`_v<=${schema.exclusiveMinimum}`)
|
|
1436
1537
|
if (schema.exclusiveMaximum !== undefined) conds.push(`_v>=${schema.exclusiveMaximum}`)
|
|
1437
|
-
if (schema.multipleOf !== undefined) conds.push(`_v%${schema.multipleOf}
|
|
1538
|
+
if (schema.multipleOf !== undefined) conds.push(`(Math.abs(_v%${schema.multipleOf})>1e-8&&Math.abs(_v%${schema.multipleOf}-${schema.multipleOf})>1e-8)`)
|
|
1438
1539
|
if (conds.length < 2) return null
|
|
1439
1540
|
return bind(conds)
|
|
1440
1541
|
}
|
|
@@ -1445,7 +1546,7 @@ function tryGenCombined(schema, access, ctx) {
|
|
|
1445
1546
|
if (schema.maximum !== undefined) conds.push(`_v>${schema.maximum}`)
|
|
1446
1547
|
if (schema.exclusiveMinimum !== undefined) conds.push(`_v<=${schema.exclusiveMinimum}`)
|
|
1447
1548
|
if (schema.exclusiveMaximum !== undefined) conds.push(`_v>=${schema.exclusiveMaximum}`)
|
|
1448
|
-
if (schema.multipleOf !== undefined) conds.push(`_v%${schema.multipleOf}
|
|
1549
|
+
if (schema.multipleOf !== undefined) conds.push(`(Math.abs(_v%${schema.multipleOf})>1e-8&&Math.abs(_v%${schema.multipleOf}-${schema.multipleOf})>1e-8)`)
|
|
1449
1550
|
if (conds.length < 2) return null
|
|
1450
1551
|
return bind(conds)
|
|
1451
1552
|
}
|
|
@@ -1458,7 +1559,9 @@ function tryGenCombined(schema, access, ctx) {
|
|
|
1458
1559
|
// function is only safe when we're at the root (`v === 'd'`). For nested
|
|
1459
1560
|
// nodes, emit inline so block-scoped variables like `_o0` stay in scope.
|
|
1460
1561
|
function _deferOrInline(ctx, lines, v, check) {
|
|
1461
|
-
|
|
1562
|
+
// Deferring is only sound at the top level of the root function. Inside a
|
|
1563
|
+
// conditional applicator (dependentSchemas) the check must stay in its block.
|
|
1564
|
+
if (v === 'd' && !ctx.condDepth) {
|
|
1462
1565
|
if (!ctx.deferredChecks) ctx.deferredChecks = []
|
|
1463
1566
|
ctx.deferredChecks.push(check)
|
|
1464
1567
|
} else {
|
|
@@ -1599,7 +1702,7 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1599
1702
|
const isArr = effectiveType === 'array'
|
|
1600
1703
|
const isStr = effectiveType === 'string'
|
|
1601
1704
|
const isNum = effectiveType === 'number' || effectiveType === 'integer'
|
|
1602
|
-
const objGuard = isObj ? '' : `typeof ${v}==='object'&&${v}!==null&&`
|
|
1705
|
+
const objGuard = isObj ? '' : `typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&`
|
|
1603
1706
|
const objCheck = isObj ? '' : `if(typeof ${v}!=='object'||${v}===null)return false;`
|
|
1604
1707
|
|
|
1605
1708
|
// enum
|
|
@@ -1619,7 +1722,12 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1619
1722
|
if (cv === null || typeof cv !== 'object') {
|
|
1620
1723
|
lines.push(`if(${v}!==${JSON.stringify(cv)})return false`)
|
|
1621
1724
|
} else {
|
|
1622
|
-
|
|
1725
|
+
// Key-order independent comparison, defined inline so every emitter
|
|
1726
|
+
// (runtime, hybrid, standalone) carries it.
|
|
1727
|
+
const ci = ctx.varCounter++
|
|
1728
|
+
const canonFn = `_cnB${ci}`
|
|
1729
|
+
const expected = _canonical(cv)
|
|
1730
|
+
lines.push(`{const ${canonFn}=function(x){if(x===null||typeof x!=='object')return JSON.stringify(x);if(Array.isArray(x))return'['+x.map(${canonFn}).join(',')+']';return'{'+Object.keys(x).sort().map(function(k){return JSON.stringify(k)+':'+${canonFn}(x[k])}).join(',')+'}'};if(${canonFn}(${v})!==${JSON.stringify(expected)})return false}`)
|
|
1623
1731
|
}
|
|
1624
1732
|
}
|
|
1625
1733
|
|
|
@@ -1647,9 +1755,9 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1647
1755
|
const checks = schema.required.map(key => `${v}[${JSON.stringify(key)}]===undefined`)
|
|
1648
1756
|
lines.push(`if(${checks.join('||')})return false`)
|
|
1649
1757
|
} else {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
}
|
|
1758
|
+
// required applies to objects only; other types are ignored.
|
|
1759
|
+
const checks = schema.required.map(key => `${v}[${JSON.stringify(key)}]===undefined`)
|
|
1760
|
+
lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&(${checks.join('||')}))return false`)
|
|
1653
1761
|
}
|
|
1654
1762
|
}
|
|
1655
1763
|
|
|
@@ -1679,7 +1787,11 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1679
1787
|
if (schema.maximum !== undefined) lines.push(isNum ? `if(${v}>${schema.maximum})return false` : `if(typeof ${v}==='number'&&${v}>${schema.maximum})return false`)
|
|
1680
1788
|
if (schema.exclusiveMinimum !== undefined) lines.push(isNum ? `if(${v}<=${schema.exclusiveMinimum})return false` : `if(typeof ${v}==='number'&&${v}<=${schema.exclusiveMinimum})return false`)
|
|
1681
1789
|
if (schema.exclusiveMaximum !== undefined) lines.push(isNum ? `if(${v}>=${schema.exclusiveMaximum})return false` : `if(typeof ${v}==='number'&&${v}>=${schema.exclusiveMaximum})return false`)
|
|
1682
|
-
if (schema.multipleOf !== undefined)
|
|
1790
|
+
if (schema.multipleOf !== undefined) {
|
|
1791
|
+
const m = schema.multipleOf
|
|
1792
|
+
const bad = `(Math.abs(${v}%${m})>1e-8&&Math.abs(${v}%${m}-${m})>1e-8)`
|
|
1793
|
+
lines.push(isNum ? `if${bad}return false` : `if(typeof ${v}==='number'&&${bad})return false`)
|
|
1794
|
+
}
|
|
1683
1795
|
|
|
1684
1796
|
// string length — skip type guard if known string.
|
|
1685
1797
|
// s.length (UTF-16 code units) is an upper bound on cpLen, and at least cpLen
|
|
@@ -1938,7 +2050,9 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
1938
2050
|
for (const [key, depSchema] of Object.entries(schema.dependentSchemas)) {
|
|
1939
2051
|
const guard = isObj ? '' : `typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&`
|
|
1940
2052
|
lines.push(`if(${guard}${JSON.stringify(key)} in ${v}){`)
|
|
2053
|
+
ctx.condDepth = (ctx.condDepth || 0) + 1
|
|
1941
2054
|
genCode(depSchema, v, lines, ctx, effectiveType)
|
|
2055
|
+
ctx.condDepth--
|
|
1942
2056
|
lines.push(`}`)
|
|
1943
2057
|
}
|
|
1944
2058
|
}
|
|
@@ -2015,9 +2129,11 @@ function genCode(schema, v, lines, ctx, knownType) {
|
|
|
2015
2129
|
const idx = `_j${ctx.varCounter}`
|
|
2016
2130
|
const elem = `_e${ctx.varCounter}`
|
|
2017
2131
|
ctx.varCounter++
|
|
2132
|
+
// items applies after the prefixItems positions (Draft 2020-12).
|
|
2133
|
+
const start = Array.isArray(schema.prefixItems) ? schema.prefixItems.length : 0
|
|
2018
2134
|
lines.push(isArr
|
|
2019
|
-
? `for(let ${idx}
|
|
2020
|
-
: `if(Array.isArray(${v})){for(let ${idx}
|
|
2135
|
+
? `for(let ${idx}=${start};${idx}<${v}.length;${idx}++){const ${elem}=${v}[${idx}]`
|
|
2136
|
+
: `if(Array.isArray(${v})){for(let ${idx}=${start};${idx}<${v}.length;${idx}++){const ${elem}=${v}[${idx}]`)
|
|
2021
2137
|
genCode(schema.items, elem, lines, ctx)
|
|
2022
2138
|
lines.push(isArr ? `}` : `}}`)
|
|
2023
2139
|
}
|
|
@@ -2682,6 +2798,9 @@ const FORMAT_CODEGEN = {
|
|
|
2682
2798
|
|
|
2683
2799
|
// Safe key escaping: use JSON.stringify to handle all special chars (newlines, null bytes, etc.)
|
|
2684
2800
|
function esc(s) { return JSON.stringify(s).slice(1, -1) }
|
|
2801
|
+
// A schema pointer segment for a pattern: JSON Pointer escaping, then made
|
|
2802
|
+
// safe for the single-quoted literal the error emitters use.
|
|
2803
|
+
function ptrSeg(s) { return s.replace(/~/g, '~0').replace(/\//g, '~1').replace(/\\/g, '\\\\').replace(/'/g, "\\'") }
|
|
2685
2804
|
|
|
2686
2805
|
// Resolve child path at codegen time when parent is a static string literal.
|
|
2687
2806
|
// This enables frozen pre-allocation for ALL nested error objects.
|
|
@@ -2828,7 +2947,7 @@ function compileToJSCodegenWithErrors(schema, schemaMap, userFormats, sourceOpts
|
|
|
2828
2947
|
: () => ({ valid: false, errors: [{ keyword: 'false schema', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
|
|
2829
2948
|
}
|
|
2830
2949
|
if (typeof schema !== 'object' || schema === null) return null
|
|
2831
|
-
if (!
|
|
2950
|
+
if (!sharedCodegenGate(schema, schemaMap)) return null
|
|
2832
2951
|
if (schema.patternProperties) {
|
|
2833
2952
|
for (const [pat, sub] of Object.entries(schema.patternProperties)) {
|
|
2834
2953
|
if (typeof sub === 'boolean') return null
|
|
@@ -3226,13 +3345,30 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3226
3345
|
lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})&&Object.keys(${v}).length>${schema.maxProperties}){${fail('maxProperties', 'maxProperties', `{limit:${schema.maxProperties}}`, `'must NOT have more than ${schema.maxProperties} properties'`)}}`)
|
|
3227
3346
|
}
|
|
3228
3347
|
|
|
3229
|
-
// additionalProperties: false
|
|
3230
|
-
|
|
3231
|
-
|
|
3348
|
+
// additionalProperties: false. A key matched by any patternProperties
|
|
3349
|
+
// entry is not additional, so those patterns are consulted here as well.
|
|
3350
|
+
if (schema.additionalProperties === false && (schema.properties || schema.patternProperties)) {
|
|
3351
|
+
const allowed = Object.keys(schema.properties || {}).map(k => `${JSON.stringify(k)}`).join(',')
|
|
3232
3352
|
const ci = ctx.varCounter++
|
|
3233
3353
|
const apSp = `${schemaPrefix}/additionalProperties`
|
|
3234
3354
|
const apLit = buildErrorLiteral({ keyword: 'additionalProperties', schemaPath: apSp, sourceMap: ctx.sourceMap })
|
|
3235
|
-
const
|
|
3355
|
+
const patChecks = []
|
|
3356
|
+
for (const pat of Object.keys(schema.patternProperties || {})) {
|
|
3357
|
+
const pattern = JSON.stringify(pat)
|
|
3358
|
+
if (!ctx.regExpMap.has(pattern)) {
|
|
3359
|
+
const ri = ctx.varCounter++
|
|
3360
|
+
ctx.regExpMap.set(pattern, ri)
|
|
3361
|
+
if (patternIsSafe(pat)) {
|
|
3362
|
+
ctx.helperCode.push(`const _re${ri}=__ataSafeRe(${pattern})`)
|
|
3363
|
+
ctx.usesSafeRe = true
|
|
3364
|
+
} else {
|
|
3365
|
+
ctx.helperCode.push(`const _re${ri}=new RegExp(${pattern})`)
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
patChecks.push(`_re${ctx.regExpMap.get(pattern)}.test(_k${ci}[_i])`)
|
|
3369
|
+
}
|
|
3370
|
+
const isAdditional = patChecks.length ? `!_a${ci}.has(_k${ci}[_i])&&!(${patChecks.join('||')})` : `!_a${ci}.has(_k${ci}[_i])`
|
|
3371
|
+
const inner = `const _k${ci}=Object.keys(${v});const _a${ci}=new Set([${allowed}]);for(let _i=0;_i<_k${ci}.length;_i++){if(${isAdditional}){_e.push({code:'${apLit.codeStr}',keyword:'additionalProperties',instancePath:${pathExpr||'""'},schemaPath:'${apSp}',params:{additionalProperty:_k${ci}[_i]},message:'must NOT have additional properties',docUrl:'${apLit.docUrl}'${apLit.frame}});if(!_all)return{valid:false,errors:_e}}}`
|
|
3236
3372
|
lines.push(isObj ? `{${inner}}` : `if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})){${inner}}`)
|
|
3237
3373
|
}
|
|
3238
3374
|
|
|
@@ -3275,7 +3411,8 @@ function genCodeE(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3275
3411
|
const ki = ctx.varCounter++
|
|
3276
3412
|
lines.push(`if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v})){for(const _k${ki} in ${v}){if(_re${ri}.test(_k${ki})){`)
|
|
3277
3413
|
const p = pathExpr ? `${pathExpr}+'/'+_k${ki}` : `'/'+_k${ki}`
|
|
3278
|
-
|
|
3414
|
+
// The real pointer, so source maps can locate the failing keyword.
|
|
3415
|
+
genCodeE(sub, `${v}[_k${ki}]`, p, lines, ctx, schemaPrefix + '/patternProperties/' + pat.replace(/~/g, '~0').replace(/\//g, '~1'))
|
|
3279
3416
|
lines.push(`}}}`)
|
|
3280
3417
|
}
|
|
3281
3418
|
}
|
|
@@ -3454,7 +3591,7 @@ function compileToJSCombined(schema, VALID_RESULT, schemaMap, userFormats) {
|
|
|
3454
3591
|
: () => ({ valid: false, errors: [{ keyword: 'false schema', instancePath: '', schemaPath: '#', params: {}, message: 'boolean schema is false' }] })
|
|
3455
3592
|
}
|
|
3456
3593
|
if (typeof schema !== 'object' || schema === null) return null
|
|
3457
|
-
if (!
|
|
3594
|
+
if (!sharedCodegenGate(schema, schemaMap)) return null
|
|
3458
3595
|
if (schema.patternProperties) {
|
|
3459
3596
|
for (const [pat, sub] of Object.entries(schema.patternProperties)) {
|
|
3460
3597
|
if (typeof sub === 'boolean') return null
|
|
@@ -3888,17 +4025,6 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3888
4025
|
}
|
|
3889
4026
|
}
|
|
3890
4027
|
|
|
3891
|
-
// Build sub-schema validators as closure vars
|
|
3892
|
-
for (let i = 0; i < ppEntries.length; i++) {
|
|
3893
|
-
const [, sub] = ppEntries[i]
|
|
3894
|
-
const subLines = []
|
|
3895
|
-
genCode(sub, `_ppv`, subLines, ctx)
|
|
3896
|
-
const fnBody = subLines.length === 0 ? `return true` : `${subLines.join(';')};return true`
|
|
3897
|
-
const fnVar = `_ppf${pi}_${i}`
|
|
3898
|
-
ctx.closureVars.push(fnVar)
|
|
3899
|
-
ctx.closureVals.push(new Function('_ppv', fnBody))
|
|
3900
|
-
}
|
|
3901
|
-
|
|
3902
4028
|
const guard = isObj ? '' : `if(typeof ${v}==='object'&&${v}!==null&&!Array.isArray(${v}))`
|
|
3903
4029
|
const kVar = `_k${pi}`
|
|
3904
4030
|
|
|
@@ -3942,7 +4068,11 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3942
4068
|
const matchExpr = keyCheck || `_as${pi}.has(${kVar})`
|
|
3943
4069
|
lines.push(`let _m${pi}=${matchExpr}`)
|
|
3944
4070
|
for (let i = 0; i < ppEntries.length; i++) {
|
|
3945
|
-
|
|
4071
|
+
// The subschema is generated in place so its own keywords report
|
|
4072
|
+
// the real instance path and schema pointer.
|
|
4073
|
+
lines.push(`if(${matchers[i].check}){_m${pi}=true;{const _ppv${pi}_${i}=${v}[${kVar}]`)
|
|
4074
|
+
genCodeC(ppEntries[i][1], `_ppv${pi}_${i}`, childPathDynExpr(pathExpr, kVar), lines, ctx, schemaPrefix + '/patternProperties/' + ptrSeg(ppEntries[i][0]))
|
|
4075
|
+
lines.push(`}}`)
|
|
3946
4076
|
}
|
|
3947
4077
|
lines.push(`if(!_m${pi}){${fail('additionalProperties', 'additionalProperties', `{additionalProperty:${kVar}}`, "'must NOT have additional properties'")}}`)
|
|
3948
4078
|
lines.push(`}}`)
|
|
@@ -3972,7 +4102,9 @@ function genCodeC(schema, v, pathExpr, lines, ctx, schemaPrefix) {
|
|
|
3972
4102
|
}
|
|
3973
4103
|
}
|
|
3974
4104
|
for (let i = 0; i < ppEntries.length; i++) {
|
|
3975
|
-
lines.push(`if(${matchers[i].check}
|
|
4105
|
+
lines.push(`if(${matchers[i].check}){const _ppv${pi}_${i}=${v}[${kVar}]`)
|
|
4106
|
+
genCodeC(ppEntries[i][1], `_ppv${pi}_${i}`, childPathDynExpr(pathExpr, kVar), lines, ctx, schemaPrefix + '/patternProperties/' + ptrSeg(ppEntries[i][0]))
|
|
4107
|
+
lines.push(`}`)
|
|
3976
4108
|
}
|
|
3977
4109
|
lines.push(`}}`)
|
|
3978
4110
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The official meta-schemas, vendored so a `$ref` to one of them resolves
|
|
4
|
+
// without a network. Draft 2020-12 is eight documents joined by $dynamicRef;
|
|
5
|
+
// draft-07 is one. Sources: https://json-schema.org/draft/2020-12/schema and
|
|
6
|
+
// http://json-schema.org/draft-07/schema, fetched 2026-08-23, unmodified.
|
|
7
|
+
// Keyed by $id; index.js also registers the http/https and trailing-# spellings.
|
|
8
|
+
|
|
9
|
+
const METASCHEMAS = new Map([
|
|
10
|
+
["https://json-schema.org/draft/2020-12/schema", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/schema","$vocabulary":{"https://json-schema.org/draft/2020-12/vocab/core":true,"https://json-schema.org/draft/2020-12/vocab/applicator":true,"https://json-schema.org/draft/2020-12/vocab/unevaluated":true,"https://json-schema.org/draft/2020-12/vocab/validation":true,"https://json-schema.org/draft/2020-12/vocab/meta-data":true,"https://json-schema.org/draft/2020-12/vocab/format-annotation":true,"https://json-schema.org/draft/2020-12/vocab/content":true},"$dynamicAnchor":"meta","title":"Core and Validation specifications meta-schema","allOf":[{"$ref":"meta/core"},{"$ref":"meta/applicator"},{"$ref":"meta/unevaluated"},{"$ref":"meta/validation"},{"$ref":"meta/meta-data"},{"$ref":"meta/format-annotation"},{"$ref":"meta/content"}],"type":["object","boolean"],"$comment":"This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.","properties":{"definitions":{"$comment":"\"definitions\" has been replaced by \"$defs\".","type":"object","additionalProperties":{"$dynamicRef":"#meta"},"deprecated":true,"default":{}},"dependencies":{"$comment":"\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.","type":"object","additionalProperties":{"anyOf":[{"$dynamicRef":"#meta"},{"$ref":"meta/validation#/$defs/stringArray"}]},"deprecated":true,"default":{}},"$recursiveAnchor":{"$comment":"\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".","$ref":"meta/core#/$defs/anchorString","deprecated":true},"$recursiveRef":{"$comment":"\"$recursiveRef\" has been replaced by \"$dynamicRef\".","$ref":"meta/core#/$defs/uriReferenceString","deprecated":true}}}],
|
|
11
|
+
["https://json-schema.org/draft/2020-12/meta/core", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/core","$dynamicAnchor":"meta","title":"Core vocabulary meta-schema","type":["object","boolean"],"properties":{"$id":{"$ref":"#/$defs/uriReferenceString","$comment":"Non-empty fragments not allowed.","pattern":"^[^#]*#?$"},"$schema":{"$ref":"#/$defs/uriString"},"$ref":{"$ref":"#/$defs/uriReferenceString"},"$anchor":{"$ref":"#/$defs/anchorString"},"$dynamicRef":{"$ref":"#/$defs/uriReferenceString"},"$dynamicAnchor":{"$ref":"#/$defs/anchorString"},"$vocabulary":{"type":"object","propertyNames":{"$ref":"#/$defs/uriString"},"additionalProperties":{"type":"boolean"}},"$comment":{"type":"string"},"$defs":{"type":"object","additionalProperties":{"$dynamicRef":"#meta"}}},"$defs":{"anchorString":{"type":"string","pattern":"^[A-Za-z_][-A-Za-z0-9._]*$"},"uriString":{"type":"string","format":"uri"},"uriReferenceString":{"type":"string","format":"uri-reference"}}}],
|
|
12
|
+
["https://json-schema.org/draft/2020-12/meta/applicator", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/applicator","$dynamicAnchor":"meta","title":"Applicator vocabulary meta-schema","type":["object","boolean"],"properties":{"prefixItems":{"$ref":"#/$defs/schemaArray"},"items":{"$dynamicRef":"#meta"},"contains":{"$dynamicRef":"#meta"},"additionalProperties":{"$dynamicRef":"#meta"},"properties":{"type":"object","additionalProperties":{"$dynamicRef":"#meta"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$dynamicRef":"#meta"},"propertyNames":{"format":"regex"},"default":{}},"dependentSchemas":{"type":"object","additionalProperties":{"$dynamicRef":"#meta"},"default":{}},"propertyNames":{"$dynamicRef":"#meta"},"if":{"$dynamicRef":"#meta"},"then":{"$dynamicRef":"#meta"},"else":{"$dynamicRef":"#meta"},"allOf":{"$ref":"#/$defs/schemaArray"},"anyOf":{"$ref":"#/$defs/schemaArray"},"oneOf":{"$ref":"#/$defs/schemaArray"},"not":{"$dynamicRef":"#meta"}},"$defs":{"schemaArray":{"type":"array","minItems":1,"items":{"$dynamicRef":"#meta"}}}}],
|
|
13
|
+
["https://json-schema.org/draft/2020-12/meta/validation", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/validation","$dynamicAnchor":"meta","title":"Validation vocabulary meta-schema","type":["object","boolean"],"properties":{"type":{"anyOf":[{"$ref":"#/$defs/simpleTypes"},{"type":"array","items":{"$ref":"#/$defs/simpleTypes"},"minItems":1,"uniqueItems":true}]},"const":true,"enum":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/$defs/nonNegativeInteger"},"minLength":{"$ref":"#/$defs/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"maxItems":{"$ref":"#/$defs/nonNegativeInteger"},"minItems":{"$ref":"#/$defs/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"maxContains":{"$ref":"#/$defs/nonNegativeInteger"},"minContains":{"$ref":"#/$defs/nonNegativeInteger","default":1},"maxProperties":{"$ref":"#/$defs/nonNegativeInteger"},"minProperties":{"$ref":"#/$defs/nonNegativeIntegerDefault0"},"required":{"$ref":"#/$defs/stringArray"},"dependentRequired":{"type":"object","additionalProperties":{"$ref":"#/$defs/stringArray"}}},"$defs":{"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"$ref":"#/$defs/nonNegativeInteger","default":0},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}}}],
|
|
14
|
+
["https://json-schema.org/draft/2020-12/meta/meta-data", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/meta-data","$dynamicAnchor":"meta","title":"Meta-data vocabulary meta-schema","type":["object","boolean"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"default":true,"deprecated":{"type":"boolean","default":false},"readOnly":{"type":"boolean","default":false},"writeOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true}}}],
|
|
15
|
+
["https://json-schema.org/draft/2020-12/meta/format-annotation", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/format-annotation","$dynamicAnchor":"meta","title":"Format vocabulary meta-schema for annotation results","type":["object","boolean"],"properties":{"format":{"type":"string"}}}],
|
|
16
|
+
["https://json-schema.org/draft/2020-12/meta/content", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/content","$dynamicAnchor":"meta","title":"Content vocabulary meta-schema","type":["object","boolean"],"properties":{"contentEncoding":{"type":"string"},"contentMediaType":{"type":"string"},"contentSchema":{"$dynamicRef":"#meta"}}}],
|
|
17
|
+
["https://json-schema.org/draft/2020-12/meta/unevaluated", {"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://json-schema.org/draft/2020-12/meta/unevaluated","$dynamicAnchor":"meta","title":"Unevaluated applicator vocabulary meta-schema","type":["object","boolean"],"properties":{"unevaluatedItems":{"$dynamicRef":"#meta"},"unevaluatedProperties":{"$dynamicRef":"#meta"}}}],
|
|
18
|
+
["http://json-schema.org/draft-07/schema#", {"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"writeOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}],
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
module.exports = { METASCHEMAS };
|