ata-validator 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/index.js +4 -1
- package/lib/interpreter.js +27 -0
- package/lib/js-compiler.js +6 -0
- package/lib/version.js +1 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to ata-validator are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/), and this project adheres to semantic versioning.
|
|
4
4
|
|
|
5
|
+
## 1.5.0 - 2026-08-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `propertyDependencies`, a JSON Schema v1 [proposal](https://github.com/json-schema-org/json-schema-spec/blob/main/specs/proposals/propertyDependencies.md), selects a subschema by the value of a property rather than by its presence. It replaces the `oneOf` and `if`/`then` patterns normally used to branch on a discriminator field, and reads as `{ "propertyDependencies": { "type": { "customer": { ... }, "employee": { ... } } } }`. The proposal defines the keyword as equivalent to an `if`/`then` on `const`, and `tests/test_property_dependencies.js` checks that equivalence case by case rather than asserting a separate expectation, alongside the proposal's own test files from the official suite: 36 of 38, the two remaining being a `$dynamicRef` scope gap the `if`/`then` form of the same schema hits identically.
|
|
10
|
+
- The keyword is implemented in the interpreted engine. Both JS compiler paths decline a schema that uses it rather than emitting nothing for a keyword they do not know, which would make the constraint vacuous.
|
|
11
|
+
|
|
5
12
|
## 1.4.0 - 2026-08-04
|
|
6
13
|
|
|
7
14
|
### Fixed
|
package/index.js
CHANGED
|
@@ -1061,8 +1061,11 @@ class Validator {
|
|
|
1061
1061
|
this._ensureNative();
|
|
1062
1062
|
const _hasDynRef = this._schemaStr.includes('"$dynamicRef"') || this._schemaStr.includes('"$dynamicAnchor"')
|
|
1063
1063
|
const _hasUneval = this._schemaStr.includes('"unevaluatedProperties"') || this._schemaStr.includes('"unevaluatedItems"')
|
|
1064
|
+
// propertyDependencies exists only in the interpreted engine, so a schema
|
|
1065
|
+
// using it goes there even when it also uses $dynamicRef.
|
|
1066
|
+
const _hasPropDeps = this._schemaStr.includes('"propertyDependencies"')
|
|
1064
1067
|
let _validate;
|
|
1065
|
-
if (_hasDynRef && !_hasUneval) {
|
|
1068
|
+
if (_hasDynRef && !_hasUneval && !_hasPropDeps) {
|
|
1066
1069
|
// validateJSON is the C++ path with full anchor-map support; the NAPI
|
|
1067
1070
|
// direct V8 `validate` path has no anchor maps.
|
|
1068
1071
|
_validate = (data) => this._compiled.validateJSON(JSON.stringify(data));
|
package/lib/interpreter.js
CHANGED
|
@@ -102,6 +102,16 @@ function walkSchema(node, baseUri, state, isResourceRoot) {
|
|
|
102
102
|
const list = node[kw];
|
|
103
103
|
if (Array.isArray(list)) for (const sub of list) walkSchema(sub, baseUri, state, false);
|
|
104
104
|
}
|
|
105
|
+
// propertyDependencies nests one level deeper than the other maps:
|
|
106
|
+
// property name -> property value -> schema.
|
|
107
|
+
const propDeps = node.propertyDependencies;
|
|
108
|
+
if (propDeps && typeof propDeps === 'object' && !Array.isArray(propDeps)) {
|
|
109
|
+
for (const choices of Object.values(propDeps)) {
|
|
110
|
+
if (choices && typeof choices === 'object' && !Array.isArray(choices)) {
|
|
111
|
+
for (const sub of Object.values(choices)) walkSchema(sub, baseUri, state, false);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
// ---------- ref resolution ----------
|
|
@@ -504,6 +514,23 @@ class Interpreter {
|
|
|
504
514
|
}
|
|
505
515
|
}
|
|
506
516
|
}
|
|
517
|
+
// propertyDependencies: like dependentSchemas but keyed on the property's
|
|
518
|
+
// value rather than its presence. Only string values can match, since the
|
|
519
|
+
// inner keys are object keys. Equivalent to
|
|
520
|
+
// `if: { properties: { p: { const: v } }, required: [p] }, then: <schema>`.
|
|
521
|
+
if (schema.propertyDependencies && typeof schema.propertyDependencies === 'object') {
|
|
522
|
+
for (const [key, choices] of Object.entries(schema.propertyDependencies)) {
|
|
523
|
+
if (!choices || typeof choices !== 'object' || Array.isArray(choices)) continue;
|
|
524
|
+
if (!Object.prototype.hasOwnProperty.call(data, key)) continue;
|
|
525
|
+
const value = data[key];
|
|
526
|
+
if (typeof value !== 'string') continue;
|
|
527
|
+
if (!Object.prototype.hasOwnProperty.call(choices, value)) continue;
|
|
528
|
+
const sub = { props: null, items: null };
|
|
529
|
+
const branchPath = schemaPath + '/propertyDependencies/' + escapePointer(key) + '/' + escapePointer(value);
|
|
530
|
+
if (!this.eval(choices[value], data, base, dynScope, errors, instancePath, branchPath, stack, sub)) valid = false;
|
|
531
|
+
else mergeAnnotations(local, sub);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
507
534
|
}
|
|
508
535
|
|
|
509
536
|
// in-place applicators
|
package/lib/js-compiler.js
CHANGED
|
@@ -115,6 +115,7 @@ function compileToJS(schema, defs, schemaMap) {
|
|
|
115
115
|
// Bail on features that are too complex for JS fast path
|
|
116
116
|
if (schema.patternProperties ||
|
|
117
117
|
schema.dependentSchemas ||
|
|
118
|
+
schema.propertyDependencies ||
|
|
118
119
|
schema.propertyNames) {
|
|
119
120
|
return null
|
|
120
121
|
}
|
|
@@ -749,6 +750,11 @@ function codegenSafe(schema, schemaMap) {
|
|
|
749
750
|
if (typeof schema === 'boolean') return true
|
|
750
751
|
if (typeof schema !== 'object' || schema === null) return true
|
|
751
752
|
|
|
753
|
+
// propertyDependencies is a proposal the interpreted engine implements and
|
|
754
|
+
// neither JS path does. Emitting nothing for it would make the keyword
|
|
755
|
+
// vacuous, so hand the schema over rather than silently ignore a constraint.
|
|
756
|
+
if (schema.propertyDependencies !== undefined) return false
|
|
757
|
+
|
|
752
758
|
// Only bail on $dynamicRef if it can't be resolved at compile time
|
|
753
759
|
if (schema.$dynamicRef && !schema.$dynamicRef.startsWith('#')) return false
|
|
754
760
|
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "JSON Schema validation with first-class TypeScript and zero runtime cost. AOT compile to per-schema ESM modules with zero validator dependency. Generic Validator<T> for TypeBox/Zod/Valibot composition. Optional runtime API. Standard Schema V1 compatible.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"release:check": "node scripts/regen-safe-regex-source.js && node tests/test_pack_purity.js && node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js && node tests/test_safe_regex_source_sync.js && node tests/test_version_sync.js",
|
|
45
45
|
"build": "cmake-js build --target ata",
|
|
46
46
|
"rebuild": "cmake-js rebuild --target ata",
|
|
47
|
-
"test": "node test.js && node tests/test_removed_aot_methods.js && node tests/test_no_native.js && node tests/test_no_eval.js && node tests/test_pure_js_unsupported.js && node tests/test_native_load_order.js && node tests/test_pack_purity.js && node tests/test_make_native_package.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_version_sync.js && node tests/test_safe_regex_source_sync.js && node tests/test_t_builder.js && node tests/test_async_refine.js && node tests/test_safe_regex.js && node tests/test_safe_regex_integration.js && node tests/test_aot_build.js && node tests/test_aot_differential.js && node tests/test_aot_cli_build.js && node tests/test_aot_cli_smoke.js && node tests/test_bundle_standalone.js && node tests/test_standalone_anyof.js && node tests/test_standalone_formats.js && node tests/test_aot_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_engine_routing.js && node tests/test_format_engine_parity.js && node tests/test_defs_pointer_alias.js && node tests/test_no_input_mutation.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.js && node tests/test_error_order.js && node tests/test_nullable.js && node tests/test_validate_and_parse.js && node tests/test_validate_data.js && node tests/test_enrich_error.js && node tests/test_rich_errors_optout.js && node tests/test_error_messages.js && node tests/test_source_positions.js && node tests/fuzz_positions.js && node tests/test_data_positions.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_runtime_error_dx.js && node tests/test_aot_error_dx.js && node tests/test_abort_early.js && node tests/test_branch_collapse.js && node tests/test_suggestions.js && node tests/test_cli_validate.js && node tests/test_cli_version.js && node benchmark/bench_aot_size.mjs",
|
|
47
|
+
"test": "node test.js && node tests/test_removed_aot_methods.js && node tests/test_no_native.js && node tests/test_no_eval.js && node tests/test_property_dependencies.js && node tests/test_pure_js_unsupported.js && node tests/test_native_load_order.js && node tests/test_pack_purity.js && node tests/test_make_native_package.js && node tests/test_browser_nofs.js && node tests/test_browser_imports_guard.js && node tests/test_version_sync.js && node tests/test_safe_regex_source_sync.js && node tests/test_t_builder.js && node tests/test_async_refine.js && node tests/test_safe_regex.js && node tests/test_safe_regex_integration.js && node tests/test_aot_build.js && node tests/test_aot_differential.js && node tests/test_aot_cli_build.js && node tests/test_aot_cli_smoke.js && node tests/test_bundle_standalone.js && node tests/test_standalone_anyof.js && node tests/test_standalone_formats.js && node tests/test_aot_additional_props_errors.js && node tests/test_id_anchor_refs.js && node tests/test_engine_routing.js && node tests/test_format_engine_parity.js && node tests/test_defs_pointer_alias.js && node tests/test_no_input_mutation.js && node tests/test_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.js && node tests/test_error_order.js && node tests/test_nullable.js && node tests/test_validate_and_parse.js && node tests/test_validate_data.js && node tests/test_enrich_error.js && node tests/test_rich_errors_optout.js && node tests/test_error_messages.js && node tests/test_source_positions.js && node tests/fuzz_positions.js && node tests/test_data_positions.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_runtime_error_dx.js && node tests/test_aot_error_dx.js && node tests/test_abort_early.js && node tests/test_branch_collapse.js && node tests/test_suggestions.js && node tests/test_cli_validate.js && node tests/test_cli_version.js && node benchmark/bench_aot_size.mjs",
|
|
48
48
|
"bench:size": "node benchmark/bench_aot_size.mjs",
|
|
49
49
|
"test:suite": "node tests/run_suite.js && node tests/run_suite.js draft7",
|
|
50
50
|
"test:compat": "node tests/test_compat.js",
|
|
@@ -112,12 +112,12 @@
|
|
|
112
112
|
"LICENSE"
|
|
113
113
|
],
|
|
114
114
|
"optionalDependencies": {
|
|
115
|
-
"@ata-validator/native-darwin-arm64": "1.
|
|
116
|
-
"@ata-validator/native-linux-x64-gnu": "1.
|
|
117
|
-
"@ata-validator/native-linux-arm64-gnu": "1.
|
|
118
|
-
"@ata-validator/native-linux-x64-musl": "1.
|
|
119
|
-
"@ata-validator/native-linux-arm64-musl": "1.
|
|
120
|
-
"@ata-validator/native-win32-x64": "1.
|
|
115
|
+
"@ata-validator/native-darwin-arm64": "1.5.0",
|
|
116
|
+
"@ata-validator/native-linux-x64-gnu": "1.5.0",
|
|
117
|
+
"@ata-validator/native-linux-arm64-gnu": "1.5.0",
|
|
118
|
+
"@ata-validator/native-linux-x64-musl": "1.5.0",
|
|
119
|
+
"@ata-validator/native-linux-arm64-musl": "1.5.0",
|
|
120
|
+
"@ata-validator/native-win32-x64": "1.5.0"
|
|
121
121
|
},
|
|
122
122
|
"peerDependencies": {
|
|
123
123
|
"yaml": "^2.0.0"
|