ata-validator 1.0.2 → 1.2.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 +24 -0
- package/README.md +19 -2
- package/index.js +110 -12
- package/lib/aot.js +1 -1
- package/lib/interpreter.js +617 -0
- package/lib/js-compiler.js +32 -0
- package/lib/native-load.browser.js +1 -1
- package/lib/native-load.js +83 -11
- package/lib/t.js +90 -0
- package/lib/version.js +3 -3
- package/package.json +14 -20
- package/t.d.ts +84 -0
- package/CMakeLists.txt +0 -150
- package/binding/ata_napi.cpp +0 -1574
- package/binding-options.js +0 -4
- package/deps/simdjson/simdjson.cpp +0 -56221
- package/deps/simdjson/simdjson.h +0 -122784
- package/include/ata.h +0 -111
- package/include/ata_c.h +0 -57
- 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/scripts/check-doc-coverage.js +0 -34
- package/scripts/check-prebuilds.js +0 -54
- package/scripts/install.js +0 -23
- package/scripts/regen-error-codes-doc.js +0 -40
- package/scripts/regen-lock.js +0 -19
- package/scripts/regen-safe-regex-source.js +0 -33
- package/src/ata.cpp +0 -3146
- package/src/ata_c.cpp +0 -63
package/include/ata.h
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <cstdint>
|
|
4
|
-
#include <memory>
|
|
5
|
-
#include <optional>
|
|
6
|
-
#include <string>
|
|
7
|
-
#include <string_view>
|
|
8
|
-
#include <variant>
|
|
9
|
-
#include <vector>
|
|
10
|
-
|
|
11
|
-
#define ATA_VERSION "1.0.2"
|
|
12
|
-
|
|
13
|
-
namespace ata {
|
|
14
|
-
|
|
15
|
-
inline constexpr uint32_t VERSION_MAJOR = 1;
|
|
16
|
-
inline constexpr uint32_t VERSION_MINOR = 0;
|
|
17
|
-
inline constexpr uint32_t VERSION_REVISION = 2;
|
|
18
|
-
|
|
19
|
-
inline constexpr std::string_view version() noexcept {
|
|
20
|
-
return ATA_VERSION;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
enum class error_code : uint8_t {
|
|
24
|
-
ok = 0,
|
|
25
|
-
invalid_json,
|
|
26
|
-
invalid_schema,
|
|
27
|
-
type_mismatch,
|
|
28
|
-
required_property_missing,
|
|
29
|
-
additional_property_not_allowed,
|
|
30
|
-
enum_mismatch,
|
|
31
|
-
const_mismatch,
|
|
32
|
-
minimum_violation,
|
|
33
|
-
maximum_violation,
|
|
34
|
-
exclusive_minimum_violation,
|
|
35
|
-
exclusive_maximum_violation,
|
|
36
|
-
min_length_violation,
|
|
37
|
-
max_length_violation,
|
|
38
|
-
pattern_mismatch,
|
|
39
|
-
format_mismatch,
|
|
40
|
-
min_items_violation,
|
|
41
|
-
max_items_violation,
|
|
42
|
-
unique_items_violation,
|
|
43
|
-
min_properties_violation,
|
|
44
|
-
max_properties_violation,
|
|
45
|
-
multiple_of_violation,
|
|
46
|
-
all_of_failed,
|
|
47
|
-
any_of_failed,
|
|
48
|
-
one_of_failed,
|
|
49
|
-
not_failed,
|
|
50
|
-
ref_not_found,
|
|
51
|
-
if_then_else_failed,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
struct validation_error {
|
|
55
|
-
error_code code;
|
|
56
|
-
std::string path;
|
|
57
|
-
std::string message;
|
|
58
|
-
std::string expected;
|
|
59
|
-
std::string actual;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
struct validation_result {
|
|
63
|
-
bool valid;
|
|
64
|
-
std::vector<validation_error> errors;
|
|
65
|
-
|
|
66
|
-
explicit operator bool() const noexcept { return valid; }
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
struct compiled_schema;
|
|
70
|
-
|
|
71
|
-
struct schema_warning {
|
|
72
|
-
std::string path;
|
|
73
|
-
std::string message;
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
struct schema_ref {
|
|
77
|
-
std::shared_ptr<compiled_schema> impl;
|
|
78
|
-
std::vector<schema_warning> warnings;
|
|
79
|
-
|
|
80
|
-
explicit operator bool() const noexcept { return impl != nullptr; }
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
struct validate_options {
|
|
84
|
-
bool all_errors = true; // false = stop at first error (faster)
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// Compile a JSON Schema string into an internal representation.
|
|
88
|
-
schema_ref compile(std::string_view schema_json);
|
|
89
|
-
|
|
90
|
-
// Validate a JSON document against a compiled schema.
|
|
91
|
-
validation_result validate(const schema_ref& schema, std::string_view json,
|
|
92
|
-
const validate_options& opts = {});
|
|
93
|
-
|
|
94
|
-
// Validate a JSON document against a schema (compiles schema each time).
|
|
95
|
-
validation_result validate(std::string_view schema_json,
|
|
96
|
-
std::string_view json,
|
|
97
|
-
const validate_options& opts = {});
|
|
98
|
-
|
|
99
|
-
// Ultra-fast boolean validation — no error collection, no allocation.
|
|
100
|
-
// Input MUST have at least 64 bytes of padding after data (simdjson requirement).
|
|
101
|
-
// Use this when you only need true/false and can provide pre-padded input.
|
|
102
|
-
bool is_valid_prepadded(const schema_ref& schema, const char* data, size_t length);
|
|
103
|
-
|
|
104
|
-
// Validate raw buffer — handles padding internally via thread-local copy.
|
|
105
|
-
// Use this when input doesn't have simdjson padding (e.g., from V8 TypedArray).
|
|
106
|
-
bool is_valid_buf(const schema_ref& schema, const uint8_t* data, size_t length);
|
|
107
|
-
|
|
108
|
-
// Required padding size for is_valid_prepadded
|
|
109
|
-
inline constexpr size_t REQUIRED_PADDING = 64;
|
|
110
|
-
|
|
111
|
-
} // namespace ata
|
package/include/ata_c.h
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
#ifndef ATA_C_H
|
|
2
|
-
#define ATA_C_H
|
|
3
|
-
|
|
4
|
-
#include <stdbool.h>
|
|
5
|
-
#include <stddef.h>
|
|
6
|
-
#include <stdint.h>
|
|
7
|
-
|
|
8
|
-
#ifdef __cplusplus
|
|
9
|
-
extern "C" {
|
|
10
|
-
#endif
|
|
11
|
-
|
|
12
|
-
typedef struct ata_schema_s* ata_schema;
|
|
13
|
-
|
|
14
|
-
typedef struct {
|
|
15
|
-
const char* data;
|
|
16
|
-
size_t length;
|
|
17
|
-
} ata_string;
|
|
18
|
-
|
|
19
|
-
typedef struct {
|
|
20
|
-
bool valid;
|
|
21
|
-
size_t error_count;
|
|
22
|
-
} ata_result;
|
|
23
|
-
|
|
24
|
-
typedef struct {
|
|
25
|
-
uint32_t major;
|
|
26
|
-
uint32_t minor;
|
|
27
|
-
uint32_t revision;
|
|
28
|
-
} ata_version_components;
|
|
29
|
-
|
|
30
|
-
// Compile a JSON Schema. Returns NULL on failure.
|
|
31
|
-
ata_schema ata_compile(const char* schema_json, size_t length);
|
|
32
|
-
|
|
33
|
-
// Free a compiled schema. NULL-safe.
|
|
34
|
-
void ata_schema_free(ata_schema schema);
|
|
35
|
-
|
|
36
|
-
// Validate JSON against a compiled schema.
|
|
37
|
-
ata_result ata_validate(ata_schema schema, const char* json, size_t length);
|
|
38
|
-
|
|
39
|
-
// Validate JSON against a schema string (compiles each time).
|
|
40
|
-
ata_result ata_validate_oneshot(const char* schema_json, size_t schema_length,
|
|
41
|
-
const char* json, size_t json_length);
|
|
42
|
-
|
|
43
|
-
// Get error message at index from last validation.
|
|
44
|
-
ata_string ata_get_error_message(size_t index);
|
|
45
|
-
|
|
46
|
-
// Get error path at index from last validation.
|
|
47
|
-
ata_string ata_get_error_path(size_t index);
|
|
48
|
-
|
|
49
|
-
// Version info
|
|
50
|
-
const char* ata_get_version(void);
|
|
51
|
-
ata_version_components ata_get_version_components(void);
|
|
52
|
-
|
|
53
|
-
#ifdef __cplusplus
|
|
54
|
-
}
|
|
55
|
-
#endif
|
|
56
|
-
|
|
57
|
-
#endif // ATA_C_H
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const { all } = require('../lib/error-codes');
|
|
7
|
-
|
|
8
|
-
const doc = fs.readFileSync(path.join(__dirname, '..', 'docs', 'error-codes.md'), 'utf8');
|
|
9
|
-
|
|
10
|
-
const missing = [];
|
|
11
|
-
const placeholder = [];
|
|
12
|
-
for (const code of all()) {
|
|
13
|
-
const headingRe = new RegExp(`^### ${code}\\b`, 'm');
|
|
14
|
-
if (!headingRe.test(doc)) {
|
|
15
|
-
missing.push(code);
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
// Find the section, ensure it doesn't still say "_TODO — fill before release._"
|
|
19
|
-
const start = doc.search(headingRe);
|
|
20
|
-
const next = doc.slice(start + 4).search(/^### /m);
|
|
21
|
-
const section = next === -1 ? doc.slice(start) : doc.slice(start, start + 4 + next);
|
|
22
|
-
if (section.includes('_TODO')) placeholder.push(code);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (missing.length) {
|
|
26
|
-
console.error(`docs/error-codes.md is missing entries for: ${missing.join(', ')}`);
|
|
27
|
-
process.exit(1);
|
|
28
|
-
}
|
|
29
|
-
if (placeholder.length && process.env.ATA_ALLOW_DOC_PLACEHOLDERS !== '1') {
|
|
30
|
-
console.error(`docs/error-codes.md has placeholder _TODO sections for: ${placeholder.join(', ')}`);
|
|
31
|
-
console.error('Run: ATA_ALLOW_DOC_PLACEHOLDERS=1 node scripts/check-doc-coverage.js (development only)');
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
console.log(`ok: ${all().length} codes documented`);
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Refuse to publish a tarball that is missing platform prebuilds.
|
|
4
|
-
// Local `npm publish` only carries whatever the publisher's machine built,
|
|
5
|
-
// which silently drops every other platform's prebuild from the tarball.
|
|
6
|
-
// Publishing must go through the release workflow so all platforms are present.
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const cp = require('child_process');
|
|
11
|
-
|
|
12
|
-
const required = [
|
|
13
|
-
'ata-linux-x64',
|
|
14
|
-
'ata-linux-arm64',
|
|
15
|
-
'ata-linux-x64-musl',
|
|
16
|
-
'ata-linux-arm64-musl',
|
|
17
|
-
'ata-darwin-arm64',
|
|
18
|
-
'ata-win32-x64',
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
const root = path.resolve(__dirname, '..');
|
|
22
|
-
const missing = required.filter(
|
|
23
|
-
(dir) => !fs.existsSync(path.join(root, 'prebuilds', dir, 'node-napi-v10.node')),
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
if (missing.length) {
|
|
27
|
-
console.error(
|
|
28
|
-
'\n[ata-validator] Refusing to publish, missing prebuilds:\n' +
|
|
29
|
-
missing.map((d) => ' - ' + d).join('\n') +
|
|
30
|
-
'\n\nPublish through the GitHub release workflow so every platform is built.\n',
|
|
31
|
-
);
|
|
32
|
-
process.exit(1);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// When publishing from a Mac, verify the darwin code signatures too. strip
|
|
36
|
-
// invalidates the linker signature, and an unsigned arm64 addon is killed on
|
|
37
|
-
// load. The release workflow re-signs and verifies, this is the local net.
|
|
38
|
-
if (process.platform === 'darwin') {
|
|
39
|
-
for (const dir of required) {
|
|
40
|
-
if (!dir.startsWith('ata-darwin-')) continue;
|
|
41
|
-
const f = path.join(root, 'prebuilds', dir, 'node-napi-v10.node');
|
|
42
|
-
const r = cp.spawnSync('codesign', ['--verify', f], { encoding: 'utf8' });
|
|
43
|
-
if (r.status !== 0) {
|
|
44
|
-
console.error(
|
|
45
|
-
'\n[ata-validator] Refusing to publish, invalid code signature:\n' +
|
|
46
|
-
' ' + f + '\n' + (r.stderr || '').trim() +
|
|
47
|
-
'\n\nRe-sign with: codesign --force --sign - "' + f + '"\n',
|
|
48
|
-
);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
console.log('[ata-validator] prebuilds present for all ' + required.length + ' platforms');
|
package/scripts/install.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const root = path.resolve(__dirname, '..');
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
execSync('pkg-prebuilds-verify ./binding-options.js', { cwd: root, stdio: 'ignore' });
|
|
10
|
-
process.exit(0);
|
|
11
|
-
} catch {}
|
|
12
|
-
|
|
13
|
-
// No prebuild for this platform — try cmake-js if available
|
|
14
|
-
try {
|
|
15
|
-
execSync('cmake-js compile --target ata', { cwd: root, stdio: 'inherit' });
|
|
16
|
-
process.exit(0);
|
|
17
|
-
} catch {}
|
|
18
|
-
|
|
19
|
-
console.log(
|
|
20
|
-
'\n[ata-validator] No native prebuild found for ' + process.platform + '-' + process.arch + '.\n' +
|
|
21
|
-
'Falling back to JS engine (still works, ~2-3x slower for buffer APIs).\n' +
|
|
22
|
-
'To build from source: install cmake, RE2, abseil, then run `npx cmake-js compile --target ata`\n'
|
|
23
|
-
);
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const { CODES, all } = require('../lib/error-codes');
|
|
7
|
-
|
|
8
|
-
const lines = [];
|
|
9
|
-
lines.push('# ata Error Codes');
|
|
10
|
-
lines.push('');
|
|
11
|
-
lines.push('Stable registry of `ATA####` codes emitted by ata-validator. Each section is the target of `https://ata-validator.com/e/<code>`.');
|
|
12
|
-
lines.push('');
|
|
13
|
-
|
|
14
|
-
const byCategory = {};
|
|
15
|
-
for (const c of all()) {
|
|
16
|
-
const cat = CODES[c].category;
|
|
17
|
-
(byCategory[cat] ||= []).push(c);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const order = ['type', 'shape', 'constraint', 'format', 'enum', 'composition', 'ref', 'system'];
|
|
21
|
-
for (const cat of order) {
|
|
22
|
-
if (!byCategory[cat]) continue;
|
|
23
|
-
lines.push(`## ${cat}`);
|
|
24
|
-
lines.push('');
|
|
25
|
-
for (const code of byCategory[cat]) {
|
|
26
|
-
const meta = CODES[code];
|
|
27
|
-
lines.push(`### ${code} — ${meta.headline}`);
|
|
28
|
-
lines.push('');
|
|
29
|
-
lines.push(`Keyword: \`${meta.keyword}\`${meta.format ? ` (format: \`${meta.format}\`)` : ''}`);
|
|
30
|
-
lines.push('');
|
|
31
|
-
lines.push('**Cause.** _TODO — fill before release._');
|
|
32
|
-
lines.push('');
|
|
33
|
-
lines.push('**Fix.** _TODO — fill before release._');
|
|
34
|
-
lines.push('');
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const docPath = path.join(__dirname, '..', 'docs', 'error-codes.md');
|
|
39
|
-
fs.writeFileSync(docPath, lines.join('\n') + '\n');
|
|
40
|
-
console.log(`wrote ${all().length} sections to docs/error-codes.md`);
|
package/scripts/regen-lock.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const { CODES, all } = require('../lib/error-codes');
|
|
7
|
-
|
|
8
|
-
const out = {};
|
|
9
|
-
for (const c of all()) {
|
|
10
|
-
out[c] = {
|
|
11
|
-
keyword: CODES[c].keyword,
|
|
12
|
-
category: CODES[c].category,
|
|
13
|
-
format: CODES[c].format || null,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const lockPath = path.join(__dirname, '..', 'tests', 'error-codes.lock.json');
|
|
18
|
-
fs.writeFileSync(lockPath, JSON.stringify(out, null, 2) + '\n');
|
|
19
|
-
console.log(`wrote ${all().length} codes to ${path.relative(process.cwd(), lockPath)}`);
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Bake `lib/safe-regex.js` into `lib/safe-regex-source.js` as a plain string
|
|
4
|
-
// export so the AOT path (`lib/aot.js`) can embed the engine into generated
|
|
5
|
-
// modules without reading from disk at runtime. The runtime read used to be
|
|
6
|
-
// the reason browser bundles broke on first AOT call (and the reason the
|
|
7
|
-
// default entry had to carry `__dirname`/`fs`/`path`).
|
|
8
|
-
//
|
|
9
|
-
// Run from `prepublishOnly` and from a sync test so the bundled string never
|
|
10
|
-
// drifts from the engine source.
|
|
11
|
-
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
|
|
15
|
-
const root = path.resolve(__dirname, '..');
|
|
16
|
-
const src = fs.readFileSync(path.join(root, 'lib', 'safe-regex.js'), 'utf8').replace(/\r\n/g, '\n');
|
|
17
|
-
|
|
18
|
-
const out =
|
|
19
|
-
"'use strict';\n\n" +
|
|
20
|
-
"// Auto-generated by scripts/regen-safe-regex-source.js — do not edit.\n" +
|
|
21
|
-
"// Mirrors `lib/safe-regex.js` verbatim so `lib/aot.js` can embed the engine\n" +
|
|
22
|
-
"// into standalone output without a runtime `fs` read. Kept in sync by\n" +
|
|
23
|
-
"// `tests/test_safe_regex_source_sync.js`.\n\n" +
|
|
24
|
-
'module.exports = ' + JSON.stringify(src) + ';\n';
|
|
25
|
-
|
|
26
|
-
const outPath = path.join(root, 'lib', 'safe-regex-source.js');
|
|
27
|
-
const prev = fs.existsSync(outPath) ? fs.readFileSync(outPath, 'utf8') : '';
|
|
28
|
-
if (prev === out) {
|
|
29
|
-
console.log('lib/safe-regex-source.js: up to date');
|
|
30
|
-
} else {
|
|
31
|
-
fs.writeFileSync(outPath, out);
|
|
32
|
-
console.log('lib/safe-regex-source.js: regenerated');
|
|
33
|
-
}
|