ata-validator 1.32.2 → 1.32.3
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/README.md +18 -0
- package/lib/clone-emit.js +11 -0
- package/lib/js-compiler.js +73 -2
- package/lib/version.js +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -7,6 +7,24 @@ JSON Schema validation that compiles for speed and still runs where code generat
|
|
|
7
7
|
|
|
8
8
|
1.0 is a stability commitment: see [docs/STABILITY.md](docs/STABILITY.md) for the semver, deprecation, and error-code guarantees.
|
|
9
9
|
|
|
10
|
+
## Who uses ata
|
|
11
|
+
|
|
12
|
+
Projects whose code depends on ata, from GitHub's dependency graph, and the framework that lists
|
|
13
|
+
its plugin, with what each does with it:
|
|
14
|
+
|
|
15
|
+
- [Socket](https://github.com/SocketDev) uses ata, compiled ahead of time, in the shared build
|
|
16
|
+
tooling of its repositories.
|
|
17
|
+
- [Fastify](https://fastify.dev/ecosystem/) lists the
|
|
18
|
+
[`fastify-ata`](https://github.com/ata-core/fastify-ata) plugin in its ecosystem.
|
|
19
|
+
- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) ships an ata
|
|
20
|
+
validator in its main repository, in a runtime and a precompiled form.
|
|
21
|
+
- [JollyPixel](https://github.com/JollyPixel/editor) parses and validates JSON on its back end
|
|
22
|
+
with ata, compiled ahead of time.
|
|
23
|
+
- [better-drizzle](https://github.com/almeidazs/better-drizzle) ships an ata plugin for queries
|
|
24
|
+
and rows.
|
|
25
|
+
- [svelte-jsonschema-form](https://github.com/x0k/svelte-jsonschema-form) publishes an ata
|
|
26
|
+
validator package, runtime and precompiled.
|
|
27
|
+
|
|
10
28
|
## Quick start
|
|
11
29
|
|
|
12
30
|
```bash
|
package/lib/clone-emit.js
CHANGED
|
@@ -272,6 +272,17 @@ function emitValueExpr(prop, read, depth) {
|
|
|
272
272
|
if (prop.$ref) return null;
|
|
273
273
|
const types = Array.isArray(prop.type) ? prop.type : [prop.type];
|
|
274
274
|
if (types.every((t) => _CLONE_PRIMITIVE.has(t))) return read;
|
|
275
|
+
// No type, but an enum or const whose values are all primitives: whatever
|
|
276
|
+
// passes can only be one of those values, so there is nothing inside it to
|
|
277
|
+
// strip and the value is copied as it is. `{ enum: ['USD', 'EUR'] }` is how
|
|
278
|
+
// such a field is usually written, and it declined parse() for the whole
|
|
279
|
+
// schema.
|
|
280
|
+
if (prop.type === undefined) {
|
|
281
|
+
const isPrim = (v) => v === null || (typeof v !== 'object' && typeof v !== 'function');
|
|
282
|
+
if (Array.isArray(prop.enum) && prop.enum.length > 0 && prop.enum.every(isPrim) &&
|
|
283
|
+
prop.const === undefined) return read;
|
|
284
|
+
if (prop.const !== undefined && isPrim(prop.const) && prop.enum === undefined) return read;
|
|
285
|
+
}
|
|
275
286
|
const isRecordable = (s) => s.properties ||
|
|
276
287
|
(s.additionalProperties && typeof s.additionalProperties === 'object');
|
|
277
288
|
if (prop.type === 'object' && isRecordable(prop)) {
|
package/lib/js-compiler.js
CHANGED
|
@@ -3509,7 +3509,75 @@ function compilePatternInline(pattern, varName) {
|
|
|
3509
3509
|
const min = parseInt(m[2]), max = parseInt(m[3])
|
|
3510
3510
|
return `${varName}.length>=${min}&&${varName}.length<=${max}&&(()=>{for(let _pi=0;_pi<${varName}.length;_pi++){if(!(${rangeCheck}))return false}return true})()`
|
|
3511
3511
|
}
|
|
3512
|
-
return
|
|
3512
|
+
return fixedSequenceInline(pattern, varName)
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
// A pattern that matches exactly one fixed-length sequence of single
|
|
3516
|
+
// characters, such as `^[A-Z]{3}-\d{4}$` for a SKU or `^\d{3}-\d{4}$` for a
|
|
3517
|
+
// code, unrolled into one character test per position. Each piece is a class
|
|
3518
|
+
// of letters, digits, `_` and `-`, a `\d`, or a literal character, repeated a
|
|
3519
|
+
// fixed number of times; anything else, including every variable-length
|
|
3520
|
+
// quantifier and any negated or escaped class, returns null and keeps the
|
|
3521
|
+
// regular path. Each piece matches exactly one UTF-16 unit in the ASCII range,
|
|
3522
|
+
// so comparing the length and each code unit is the same test the regex
|
|
3523
|
+
// makes. Such patterns went through the safe-regex matcher, which is
|
|
3524
|
+
// linear but slower than both this and the native engine: a quarter of the
|
|
3525
|
+
// time of an order body with one SKU per line item.
|
|
3526
|
+
const FIXED_LITERAL = /[A-Za-z0-9 _\-:@#%&=,;'"<>!~`\/]/
|
|
3527
|
+
function fixedSequenceInline(pattern, varName) {
|
|
3528
|
+
if (pattern.length < 3 || pattern[0] !== '^' || pattern[pattern.length - 1] !== '$' || pattern[pattern.length - 2] === '\\') return null
|
|
3529
|
+
const end = pattern.length - 1
|
|
3530
|
+
const pieces = []
|
|
3531
|
+
let i = 1
|
|
3532
|
+
while (i < end) {
|
|
3533
|
+
let piece
|
|
3534
|
+
const c = pattern[i]
|
|
3535
|
+
if (c === '[') {
|
|
3536
|
+
const j = pattern.indexOf(']', i)
|
|
3537
|
+
if (j < 0 || j >= end) return null
|
|
3538
|
+
const cls = pattern.slice(i, j + 1)
|
|
3539
|
+
if (!/^\[[\w-]+\]$/.test(cls)) return null
|
|
3540
|
+
piece = { cls }
|
|
3541
|
+
i = j + 1
|
|
3542
|
+
} else if (c === '\\') {
|
|
3543
|
+
const e = pattern[i + 1]
|
|
3544
|
+
if (e === 'd') piece = { cls: '[0-9]' }
|
|
3545
|
+
// Only the escapes that stay valid under the u flag: an escaped `-`
|
|
3546
|
+
// outside a class is a syntax error there, and the regex path is the
|
|
3547
|
+
// one that decides what to do about it.
|
|
3548
|
+
else if (e !== undefined && './()[]{}+*?^$|\\'.includes(e)) piece = { lit: e }
|
|
3549
|
+
else return null
|
|
3550
|
+
i += 2
|
|
3551
|
+
} else if (FIXED_LITERAL.test(c)) {
|
|
3552
|
+
piece = { lit: c }
|
|
3553
|
+
i += 1
|
|
3554
|
+
} else {
|
|
3555
|
+
return null
|
|
3556
|
+
}
|
|
3557
|
+
let count = 1
|
|
3558
|
+
if (pattern[i] === '{') {
|
|
3559
|
+
const q = /^\{(\d+)\}/.exec(pattern.slice(i))
|
|
3560
|
+
if (!q) return null
|
|
3561
|
+
count = Number(q[1])
|
|
3562
|
+
i += q[0].length
|
|
3563
|
+
} else if (i < end && '*+?'.includes(pattern[i])) {
|
|
3564
|
+
return null
|
|
3565
|
+
}
|
|
3566
|
+
for (let k = 0; k < count; k++) pieces.push(piece)
|
|
3567
|
+
if (pieces.length > 32) return null
|
|
3568
|
+
}
|
|
3569
|
+
if (pieces.length === 0) return null
|
|
3570
|
+
const checks = []
|
|
3571
|
+
for (let k = 0; k < pieces.length; k++) {
|
|
3572
|
+
const at = `${varName}.charCodeAt(${k})`
|
|
3573
|
+
if (pieces[k].lit !== undefined) checks.push(`${at}===${pieces[k].lit.charCodeAt(0)}`)
|
|
3574
|
+
else {
|
|
3575
|
+
const ck = charClassToCheck(pieces[k].cls, at)
|
|
3576
|
+
if (!ck) return null
|
|
3577
|
+
checks.push(`(${ck})`)
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
return `${varName}.length===${pieces.length}&&${checks.join('&&')}`
|
|
3513
3581
|
}
|
|
3514
3582
|
|
|
3515
3583
|
// Convert [charclass] to charCode range check expression.
|
|
@@ -3534,7 +3602,10 @@ function charClassToCheck(charClass, codeExpr) {
|
|
|
3534
3602
|
const checks = ranges.map(([lo, hi]) =>
|
|
3535
3603
|
lo === hi ? `${codeExpr}===${lo}` : `(${codeExpr}>=${lo}&&${codeExpr}<=${hi})`
|
|
3536
3604
|
)
|
|
3537
|
-
|
|
3605
|
+
// Parenthesised as a whole: the unrolled form joins one of these per
|
|
3606
|
+
// position with &&, and a bare a||b there bound as (len&&a)||(b&&...), so
|
|
3607
|
+
// ^[A-Za-z]{2}$ accepted "xyz" and "1a" from 0.12.1 on.
|
|
3608
|
+
return `(${checks.join('||')})`
|
|
3538
3609
|
}
|
|
3539
3610
|
|
|
3540
3611
|
// Same but for dynamic segments (array indices)
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "1.32.
|
|
3
|
+
"version": "1.32.3",
|
|
4
4
|
"description": "JSON Schema validation that compiles for speed and still runs where code generation is blocked. Compiled and interpreted engines answer identically at 100% of the official suite. TypeScript inference, Standard Schema V1, and a build step that emits dependency-free modules.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "index.mjs",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"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",
|
|
52
52
|
"build": "cmake-js build --target ata",
|
|
53
53
|
"rebuild": "cmake-js rebuild --target ata",
|
|
54
|
-
"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_v1_dialect.js && node tests/test_buffer_path_parity.js && node tests/test_buffer_gate.js && node tests/test_scanner_differential.js && node tests/test_validate_json_scanner_cost.js && node tests/test_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.js && node tests/test_exclusive_bounds.js && node tests/test_engine_differential.js && node tests/test_error_shape_differential.js && node tests/test_output_format.js && node tests/test_retry_message.js && node tests/test_describe_schema.js && node tests/test_aot_parse.js && node tests/test_draft7_semantics.js && node tests/test_metaschema_ref.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_native_loaded.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_format_mode.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_engine_option.js && node tests/test_compile_cache_order.js && node tests/test_engine_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_error_accumulator_collision.js && node tests/test_uri_helper_parity.js && node tests/test_uri_fast_path.js && node tests/test_extend_verdict.js && node tests/test_ipv4_regex.js && node tests/test_ipv6_fast_path.js && node tests/test_nested_recursion_decline.js && node tests/test_generator_error_content.js && node tests/test_inherited_key_presence.js && node tests/test_proto_accessor.js && node tests/test_hybrid_tier.js && node tests/test_plan_source.js && node tests/test_fused_remove_additional.js && node tests/test_runtime_parse.js && node tests/test_formats_single_pass.js && node tests/test_email_format_cost.js && node tests/test_format_single_error.js && node tests/test_defs_pointer_alias.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_hybrid_agreement.js && node tests/test_codegen_edge_shapes.js && node tests/test_deferred_def_scope.js && node tests/test_node_scoped_ctx_flags.js && node tests/test_fast_slot_exhaustion.js && node tests/test_ajv_errors.js && node tests/test_custom_keywords.js && node tests/test_strict_schema.js && node tests/test_aot_external_checks.js && node tests/test_ajv_parity.js && node tests/test_user_format_error_path.js && node tests/test_unevaluated_error_path.js && node tests/test_unevaluated_error_shape.js && node tests/test_pattern_properties_errors.js && node tests/test_additional_properties_scaling.js && node tests/test_additional_props_combined_cost.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_code_lookup.js && node tests/test_error_order.js && node tests/test_error_order_ordinal.js && node tests/test_rejection_shape.js && node tests/test_lazy_normalization.js && node tests/test_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_errors.js && node tests/test_single_pass_errors.js && node tests/test_lazy_json_errors.js && node tests/test_lazy_instance.js && node tests/test_cyclic_input.js && node tests/test_native_error_codes.js && node tests/test_verdict_preprocess.js && node tests/test_defaults_own_keys.js && node tests/test_plan_compiler.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_enrich_received.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_malformed_json_termination.js && node tests/test_data_positions.js && node tests/test_targeted_positions.js && node tests/test_position_map_cost.js && node tests/test_targeted_positions_cost.js && node tests/test_aot_staleness.js && node tests/test_file_positions.js && node tests/test_aot_positions_cost.js && node tests/test_schema_hash.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_additive_fields.js && node tests/test_diagnostic_source.js && node tests/test_diagnose.js && node tests/test_correlate.js && node tests/test_diagnostics_score.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",
|
|
54
|
+
"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_v1_dialect.js && node tests/test_buffer_path_parity.js && node tests/test_buffer_gate.js && node tests/test_scanner_differential.js && node tests/test_validate_json_scanner_cost.js && node tests/test_buffer_reject_cost.js && node tests/test_nan_verdict.js && node tests/test_remove_additional_nested.js && node tests/test_exclusive_bounds.js && node tests/test_engine_differential.js && node tests/test_error_shape_differential.js && node tests/test_output_format.js && node tests/test_retry_message.js && node tests/test_describe_schema.js && node tests/test_aot_parse.js && node tests/test_draft7_semantics.js && node tests/test_metaschema_ref.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_native_loaded.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_format_mode.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_engine_option.js && node tests/test_compile_cache_order.js && node tests/test_engine_diagnostic.js && node tests/test_format_engine_parity.js && node tests/test_error_accumulator_collision.js && node tests/test_uri_helper_parity.js && node tests/test_uri_fast_path.js && node tests/test_extend_verdict.js && node tests/test_ipv4_regex.js && node tests/test_ipv6_fast_path.js && node tests/test_nested_recursion_decline.js && node tests/test_generator_error_content.js && node tests/test_inherited_key_presence.js && node tests/test_proto_accessor.js && node tests/test_hybrid_tier.js && node tests/test_fixed_pattern_inline.js && node tests/test_plan_source.js && node tests/test_fused_remove_additional.js && node tests/test_runtime_parse.js && node tests/test_formats_single_pass.js && node tests/test_email_format_cost.js && node tests/test_format_single_error.js && node tests/test_defs_pointer_alias.js && node tests/test_cross_doc_root_ref.js && node tests/test_codegen_entrypoint_agreement.js && node tests/test_hybrid_agreement.js && node tests/test_codegen_edge_shapes.js && node tests/test_deferred_def_scope.js && node tests/test_node_scoped_ctx_flags.js && node tests/test_fast_slot_exhaustion.js && node tests/test_ajv_errors.js && node tests/test_custom_keywords.js && node tests/test_strict_schema.js && node tests/test_aot_external_checks.js && node tests/test_ajv_parity.js && node tests/test_user_format_error_path.js && node tests/test_unevaluated_error_path.js && node tests/test_unevaluated_error_shape.js && node tests/test_pattern_properties_errors.js && node tests/test_additional_properties_scaling.js && node tests/test_additional_props_combined_cost.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_code_lookup.js && node tests/test_error_order.js && node tests/test_error_order_ordinal.js && node tests/test_rejection_shape.js && node tests/test_lazy_normalization.js && node tests/test_value_equality.js && node tests/test_vocabulary.js && node tests/test_schema_scan.js && node tests/test_lazy_errors.js && node tests/test_single_pass_errors.js && node tests/test_lazy_json_errors.js && node tests/test_lazy_instance.js && node tests/test_cyclic_input.js && node tests/test_native_error_codes.js && node tests/test_verdict_preprocess.js && node tests/test_defaults_own_keys.js && node tests/test_plan_compiler.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_enrich_received.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_malformed_json_termination.js && node tests/test_data_positions.js && node tests/test_targeted_positions.js && node tests/test_position_map_cost.js && node tests/test_targeted_positions_cost.js && node tests/test_aot_staleness.js && node tests/test_file_positions.js && node tests/test_aot_positions_cost.js && node tests/test_schema_hash.js && node tests/test_render_shared.js && node tests/test_renderers.js && node tests/test_additive_fields.js && node tests/test_diagnostic_source.js && node tests/test_diagnose.js && node tests/test_correlate.js && node tests/test_diagnostics_score.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",
|
|
55
55
|
"bench:size": "node benchmark/bench_aot_size.mjs",
|
|
56
56
|
"test:suite": "node tests/run_suite.js && node tests/run_suite.js draft7 && node tests/run_suite.js v1",
|
|
57
57
|
"test:compat": "node tests/test_compat.js",
|
|
@@ -121,13 +121,13 @@
|
|
|
121
121
|
"LICENSE"
|
|
122
122
|
],
|
|
123
123
|
"optionalDependencies": {
|
|
124
|
-
"@ata-validator/native-darwin-arm64": "1.32.
|
|
125
|
-
"@ata-validator/native-darwin-x64": "1.32.
|
|
126
|
-
"@ata-validator/native-linux-arm64-gnu": "1.32.
|
|
127
|
-
"@ata-validator/native-linux-arm64-musl": "1.32.
|
|
128
|
-
"@ata-validator/native-linux-x64-gnu": "1.32.
|
|
129
|
-
"@ata-validator/native-linux-x64-musl": "1.32.
|
|
130
|
-
"@ata-validator/native-win32-x64": "1.32.
|
|
124
|
+
"@ata-validator/native-darwin-arm64": "1.32.3",
|
|
125
|
+
"@ata-validator/native-darwin-x64": "1.32.3",
|
|
126
|
+
"@ata-validator/native-linux-arm64-gnu": "1.32.3",
|
|
127
|
+
"@ata-validator/native-linux-arm64-musl": "1.32.3",
|
|
128
|
+
"@ata-validator/native-linux-x64-gnu": "1.32.3",
|
|
129
|
+
"@ata-validator/native-linux-x64-musl": "1.32.3",
|
|
130
|
+
"@ata-validator/native-win32-x64": "1.32.3"
|
|
131
131
|
},
|
|
132
132
|
"peerDependencies": {
|
|
133
133
|
"yaml": "^2.0.0"
|