ata-validator 1.61.0 → 1.61.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/lib/verify.js CHANGED
@@ -195,8 +195,72 @@ function mutate (doc, r) {
195
195
  }
196
196
  }
197
197
 
198
- // Documents for `schema`: `count` made, half of them with one rule broken.
199
- function generate (schema, count, seed) {
198
+ // The values on either side of each bound the schema states, for the value
199
+ // at one place: a module that wrote a bound off by one (`< 12` for a minimum
200
+ // of 13) answers every random document as the runtime does, and differs only
201
+ // here. A bound is where a hand edit, a stale module or a generator bug shows.
202
+ function boundaryValues (schema, type) {
203
+ const out = []
204
+ const int = type === 'integer'
205
+ const step = int ? 1 : 0.5
206
+ const num = (b) => typeof b === 'number' && Number.isFinite(b)
207
+ if (type === 'integer' || type === 'number') {
208
+ if (num(schema.minimum)) out.push(schema.minimum, schema.minimum - step)
209
+ if (num(schema.maximum)) out.push(schema.maximum, schema.maximum + step)
210
+ if (num(schema.exclusiveMinimum)) out.push(schema.exclusiveMinimum, schema.exclusiveMinimum + step)
211
+ if (num(schema.exclusiveMaximum)) out.push(schema.exclusiveMaximum, schema.exclusiveMaximum - step)
212
+ if (num(schema.multipleOf) && schema.multipleOf > 0) out.push(schema.multipleOf, schema.multipleOf * 1.5)
213
+ }
214
+ if (type === 'string') {
215
+ const str = (n) => 'abcdefghij'.repeat(Math.ceil(n / 10) + 1).slice(0, n)
216
+ if (num(schema.minLength)) { out.push(str(schema.minLength)); if (schema.minLength > 0) out.push(str(schema.minLength - 1)) }
217
+ if (num(schema.maxLength) && schema.maxLength < 4096) out.push(str(schema.maxLength), str(schema.maxLength + 1))
218
+ }
219
+ return out
220
+ }
221
+
222
+ // Documents that differ from a valid one at a single place, by a value on
223
+ // either side of a bound stated there: properties, nested objects, the first
224
+ // element of an array, through local references. At most `limit` of them.
225
+ function boundaryDocs (schema, r, defs, limit, accepts) {
226
+ // A base the runtime accepts, where the caller can say, so that a bound
227
+ // read wrong changes the verdict and not only the error list.
228
+ let base = makeValid(schema, r, defs, 0)
229
+ if (accepts) for (let i = 0; i < 50 && base !== undefined && !accepts(base); i++) base = makeValid(schema, r, defs, 0)
230
+ if (base === undefined) return []
231
+ const out = []
232
+ const visit = (sub, path, depth) => {
233
+ if (out.length >= limit || depth > 8 || !sub || typeof sub !== 'object') return
234
+ if (typeof sub.$ref === 'string') { const t = resolveLocal(sub.$ref, defs); if (t !== undefined) visit(t, path, depth + 1); return }
235
+ if (Array.isArray(sub.allOf)) { visit(mergeAllOf(sub), path, depth + 1); return }
236
+ const types = Array.isArray(sub.type) ? sub.type : sub.type !== undefined ? [sub.type] : []
237
+ for (const t of types.length ? types : ['integer', 'number', 'string']) {
238
+ for (const val of boundaryValues(sub, t)) {
239
+ if (out.length >= limit) return
240
+ const d = clone(base)
241
+ if (path.length === 0) { out.push(val); continue }
242
+ let o = d
243
+ for (let i = 0; i < path.length - 1; i++) {
244
+ if (o[path[i]] === undefined || o[path[i]] === null || typeof o[path[i]] !== 'object') o[path[i]] = typeof path[i + 1] === 'number' ? [] : {}
245
+ o = o[path[i]]
246
+ }
247
+ o[path[path.length - 1]] = val
248
+ out.push(d)
249
+ }
250
+ }
251
+ if (sub.properties && typeof sub.properties === 'object') {
252
+ for (const k of Object.keys(sub.properties)) if (k !== '__proto__') visit(sub.properties[k], [...path, k], depth + 1)
253
+ }
254
+ const item = Array.isArray(sub.prefixItems) ? sub.prefixItems[0] : sub.items && typeof sub.items === 'object' && !Array.isArray(sub.items) ? sub.items : null
255
+ if (item) visit(item, [...path, 0], depth + 1)
256
+ }
257
+ visit(schema, [], 0)
258
+ return out
259
+ }
260
+
261
+ // Documents for `schema`: `count` made, half of them with one rule broken,
262
+ // then the documents on either side of each bound (up to `count` more).
263
+ function generate (schema, count, seed, accepts) {
200
264
  const r = rng(seed)
201
265
  const defs = { $defs: schema && schema.$defs, definitions: schema && schema.definitions }
202
266
  const docs = []
@@ -205,6 +269,7 @@ function generate (schema, count, seed) {
205
269
  if (i % 2 === 1 && d !== undefined) d = mutate(clone(d), r)
206
270
  docs.push(d)
207
271
  }
272
+ for (const d of boundaryDocs(schema, r, defs, count, accepts)) docs.push(d)
208
273
  return docs
209
274
  }
210
275
 
@@ -256,7 +321,7 @@ async function verifyOne ({ schemaFile, moduleFile, schema, generate: count = 20
256
321
  if (mod.schemaHash !== undefined && mod.schemaHash !== hash) report.stale = true
257
322
  let runtime
258
323
  try { runtime = new Validator(schema, {}) } catch (e) { report.error = `schema does not compile: ${e.message}`; return report }
259
- const docs = generate(schema, count, seed).map((d, i) => ({ source: `generated #${i + 1}`, doc: d }))
324
+ const docs = generate(schema, count, seed, (d) => { try { return runtime.isValidObject(clone(d)) } catch { return false } }).map((d, i) => ({ source: `generated #${i + 1}`, doc: d }))
260
325
  report.generated = docs.length
261
326
  const sampleDocs = readSamples(samples)
262
327
  report.samples = sampleDocs.length
package/lib/version.js CHANGED
@@ -7,4 +7,4 @@
7
7
  //
8
8
  // Kept in lockstep with package.json by `tests/test_version_sync.js`.
9
9
 
10
- module.exports = '1.61.0';
10
+ module.exports = '1.61.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ata-validator",
3
- "version": "1.61.0",
3
+ "version": "1.61.1",
4
4
  "description": "JSON Schema validator that compiles to plain JavaScript, still runs where code generation is blocked, and can be compiled away at build time. Passes the full official test suite.",
5
5
  "type": "commonjs",
6
6
  "main": "index.js",
@@ -60,6 +60,25 @@
60
60
  "import": "./compiled-verdict.mjs",
61
61
  "require": "./compiled-verdict.js"
62
62
  },
63
+ "./compiled-object": {
64
+ "types": "./compiled-object.d.ts",
65
+ "import": "./compiled-object.mjs",
66
+ "require": "./compiled-object.js"
67
+ },
68
+ "./compiled-plain": {
69
+ "types": "./compiled-plain.d.ts",
70
+ "import": "./compiled-plain.mjs",
71
+ "require": "./compiled-plain.js"
72
+ },
73
+ "./compiled-bare": {
74
+ "types": "./compiled-bare.d.ts",
75
+ "import": "./compiled-bare.mjs",
76
+ "require": "./compiled-bare.js"
77
+ },
78
+ "./compiled-bare-rich": {
79
+ "types": "./compiled-bare-rich.d.ts",
80
+ "default": "./lib/compiled-bare-rich.js"
81
+ },
63
82
  "./lite": {
64
83
  "types": "./lite.d.ts",
65
84
  "import": "./lite.mjs",
@@ -89,7 +108,12 @@
89
108
  "./lib/aot.js": "./lib/aot.browser.js",
90
109
  "./lib/buffer-gate.js": "./lib/buffer-gate.browser.js",
91
110
  "./lib/interpreter.js": "./lib/interpreter.browser.js",
92
- "./lib/aot-order.js": false
111
+ "./lib/aot-order.js": false,
112
+ "./lib/compiled-defaults.js": "./lib/compiled-defaults.browser.js",
113
+ "./lib/native-message.js": "./lib/native.browser.js",
114
+ "./lib/native-codes.js": "./lib/native.browser.js",
115
+ "./lib/email-literal.js": false,
116
+ "./lib/native-positions.js": "./lib/native.browser.js"
93
117
  },
94
118
  "scripts": {
95
119
  "prepublishOnly": "node tests/test_pack_purity.js && ATA_ALLOW_DOC_PLACEHOLDERS=1 node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js && node tests/test_safe_regex_embed.js && node tests/test_version_sync.js",
@@ -173,6 +197,16 @@
173
197
  "compiled-verdict.js",
174
198
  "compiled-verdict.mjs",
175
199
  "compiled-verdict.d.ts",
200
+ "compiled-object.js",
201
+ "compiled-object.mjs",
202
+ "compiled-object.d.ts",
203
+ "compiled-plain.js",
204
+ "compiled-plain.mjs",
205
+ "compiled-plain.d.ts",
206
+ "compiled-bare.js",
207
+ "compiled-bare.mjs",
208
+ "compiled-bare.d.ts",
209
+ "compiled-bare-rich.d.ts",
176
210
  "lite.js",
177
211
  "lite.mjs",
178
212
  "lite.d.ts",
@@ -187,13 +221,13 @@
187
221
  "codegen.d.ts"
188
222
  ],
189
223
  "optionalDependencies": {
190
- "@ata-validator/native-darwin-arm64": "1.61.0",
191
- "@ata-validator/native-darwin-x64": "1.61.0",
192
- "@ata-validator/native-linux-arm64-gnu": "1.61.0",
193
- "@ata-validator/native-linux-arm64-musl": "1.61.0",
194
- "@ata-validator/native-linux-x64-gnu": "1.61.0",
195
- "@ata-validator/native-linux-x64-musl": "1.61.0",
196
- "@ata-validator/native-win32-x64": "1.61.0"
224
+ "@ata-validator/native-darwin-arm64": "1.61.1",
225
+ "@ata-validator/native-darwin-x64": "1.61.1",
226
+ "@ata-validator/native-linux-arm64-gnu": "1.61.1",
227
+ "@ata-validator/native-linux-arm64-musl": "1.61.1",
228
+ "@ata-validator/native-linux-x64-gnu": "1.61.1",
229
+ "@ata-validator/native-linux-x64-musl": "1.61.1",
230
+ "@ata-validator/native-win32-x64": "1.61.1"
197
231
  },
198
232
  "peerDependencies": {
199
233
  "yaml": "^2.0.0"