ata-validator 0.18.2 → 0.21.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 +44 -0
- package/README.md +67 -0
- package/build.d.ts +28 -0
- package/build.mjs +3 -0
- package/index.browser.mjs +1 -1
- package/index.d.ts +58 -3
- package/index.js +101 -370
- package/index.mjs +1 -1
- package/lib/aot-build.js +30 -1
- package/lib/aot.js +410 -0
- package/lib/error-messages.js +88 -0
- package/lib/native-load.browser.js +8 -0
- package/lib/native-load.js +21 -0
- package/lib/refine.js +68 -0
- package/lib/safe-regex-source.js +8 -0
- package/lib/t.js +149 -0
- package/lib/version.js +10 -0
- package/package.json +14 -5
- package/scripts/regen-safe-regex-source.js +33 -0
- package/t.d.ts +205 -0
- package/t.js +9 -0
- package/t.mjs +6 -0
package/lib/t.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Chainable schema builder. Each `t.X(...)` returns a plain JSON Schema
|
|
4
|
+
// object, so the output drops straight into `new Validator(...)`,
|
|
5
|
+
// `defineSchema`, `Infer<S>`, and the AOT pipeline with no adapter. The
|
|
6
|
+
// builder is pure: no runtime state, no class instances, no closures held
|
|
7
|
+
// across calls.
|
|
8
|
+
//
|
|
9
|
+
// Optionality is carried by a Symbol-keyed marker that JSON Schema
|
|
10
|
+
// consumers (including ata's own codegen) never see, because they iterate
|
|
11
|
+
// `Object.keys`, which excludes Symbol keys. `t.object` reads the marker
|
|
12
|
+
// to compute `required` and strips it from the emitted property schema.
|
|
13
|
+
|
|
14
|
+
const OPTIONAL = Symbol.for('ata.t.optional');
|
|
15
|
+
const { attach: attachRefine } = require('./refine');
|
|
16
|
+
|
|
17
|
+
function string(opts) {
|
|
18
|
+
return Object.assign({ type: 'string' }, opts);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function number(opts) {
|
|
22
|
+
return Object.assign({ type: 'number' }, opts);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function integer(opts) {
|
|
26
|
+
return Object.assign({ type: 'integer' }, opts);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function boolean() {
|
|
30
|
+
return { type: 'boolean' };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function nul() {
|
|
34
|
+
return { type: 'null' };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function literal(value) {
|
|
38
|
+
return { const: value };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function constant(value) {
|
|
42
|
+
return { const: value };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function enumOf(values) {
|
|
46
|
+
return { enum: values };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function array(items, opts) {
|
|
50
|
+
return Object.assign({ type: 'array', items }, opts);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function tuple(items, opts) {
|
|
54
|
+
// JSON Schema 2020-12 uses `prefixItems` for tuples. `items: false`
|
|
55
|
+
// closes the tail, and a default `minItems` matching the tuple length
|
|
56
|
+
// enforces "exactly N elements" so the runtime check matches the
|
|
57
|
+
// TypeScript tuple type that `Infer<S>` produces. A caller can override
|
|
58
|
+
// either bound through `opts`.
|
|
59
|
+
return Object.assign(
|
|
60
|
+
{ type: 'array', prefixItems: items, items: false, minItems: items.length },
|
|
61
|
+
opts,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function record(values, opts) {
|
|
66
|
+
return Object.assign({ type: 'object', additionalProperties: values }, opts);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function object(properties, opts) {
|
|
70
|
+
const props = {};
|
|
71
|
+
const required = [];
|
|
72
|
+
const keys = Object.keys(properties);
|
|
73
|
+
for (const key of keys) {
|
|
74
|
+
const schema = properties[key];
|
|
75
|
+
if (schema && schema[OPTIONAL] === true) {
|
|
76
|
+
const { [OPTIONAL]: _drop, ...rest } = schema;
|
|
77
|
+
props[key] = rest;
|
|
78
|
+
} else {
|
|
79
|
+
props[key] = schema;
|
|
80
|
+
required.push(key);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const out = { type: 'object', properties: props };
|
|
84
|
+
if (required.length) out.required = required;
|
|
85
|
+
return Object.assign(out, opts);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function optional(schema) {
|
|
89
|
+
// Brand the schema so the parent `t.object` can detect it. The Symbol
|
|
90
|
+
// key is invisible to Object.keys / JSON.stringify and to ata's codegen,
|
|
91
|
+
// so a standalone `t.optional(t.string())` still validates as a string
|
|
92
|
+
// if passed directly to `new Validator(...)`.
|
|
93
|
+
return Object.assign({}, schema, { [OPTIONAL]: true });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function union(schemas) {
|
|
97
|
+
return { anyOf: schemas };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function intersect(schemas) {
|
|
101
|
+
return { allOf: schemas };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function ref(pointer) {
|
|
105
|
+
return { $ref: pointer };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function any() {
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function unknown() {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function never() {
|
|
117
|
+
return { not: {} };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function refine(schema, check, opts) {
|
|
121
|
+
// Attach an async/sync refinement. The schema stays plain JSON Schema for
|
|
122
|
+
// structural validation; the refinement is carried on a Symbol key and only
|
|
123
|
+
// runs via validateAsync()/parseAsync(). Compose by wrapping again.
|
|
124
|
+
return attachRefine(schema, check, opts);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
module.exports = {
|
|
128
|
+
string,
|
|
129
|
+
number,
|
|
130
|
+
integer,
|
|
131
|
+
boolean,
|
|
132
|
+
null: nul,
|
|
133
|
+
literal,
|
|
134
|
+
const: constant,
|
|
135
|
+
enum: enumOf,
|
|
136
|
+
array,
|
|
137
|
+
tuple,
|
|
138
|
+
record,
|
|
139
|
+
object,
|
|
140
|
+
optional,
|
|
141
|
+
union,
|
|
142
|
+
intersect,
|
|
143
|
+
ref,
|
|
144
|
+
any,
|
|
145
|
+
unknown,
|
|
146
|
+
never,
|
|
147
|
+
refine,
|
|
148
|
+
OPTIONAL,
|
|
149
|
+
};
|
package/lib/version.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// The package version, exported as a plain string so neither the default nor
|
|
4
|
+
// the browser entry has to `require('./package.json')`. Bundling package.json
|
|
5
|
+
// would drag dependency strings (e.g. `pkg-prebuilds`) into browser builds
|
|
6
|
+
// even though the runtime never touches them.
|
|
7
|
+
//
|
|
8
|
+
// Kept in lockstep with package.json by `tests/test_version_sync.js`.
|
|
9
|
+
|
|
10
|
+
module.exports = '0.21.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ata-validator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.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",
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"import": "./build.mjs",
|
|
26
26
|
"require": "./build.js"
|
|
27
27
|
},
|
|
28
|
+
"./t": {
|
|
29
|
+
"types": "./t.d.ts",
|
|
30
|
+
"import": "./t.mjs",
|
|
31
|
+
"require": "./t.js"
|
|
32
|
+
},
|
|
28
33
|
"./package.json": "./package.json"
|
|
29
34
|
},
|
|
30
35
|
"sideEffects": false,
|
|
@@ -32,17 +37,18 @@
|
|
|
32
37
|
"ata": "bin/ata.js"
|
|
33
38
|
},
|
|
34
39
|
"browser": {
|
|
35
|
-
"pkg-prebuilds": false
|
|
40
|
+
"pkg-prebuilds": false,
|
|
41
|
+
"./lib/native-load.js": "./lib/native-load.browser.js"
|
|
36
42
|
},
|
|
37
43
|
"scripts": {
|
|
38
44
|
"install": "node scripts/install.js",
|
|
39
|
-
"prepublishOnly": "node scripts/check-prebuilds.js && ATA_ALLOW_DOC_PLACEHOLDERS=1 node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js",
|
|
40
|
-
"release:check": "node scripts/check-prebuilds.js && node scripts/check-doc-coverage.js && node tests/test_error_codes_lock.js",
|
|
45
|
+
"prepublishOnly": "node scripts/regen-safe-regex-source.js && node scripts/check-prebuilds.js && ATA_ALLOW_DOC_PLACEHOLDERS=1 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",
|
|
46
|
+
"release:check": "node scripts/regen-safe-regex-source.js && node scripts/check-prebuilds.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",
|
|
41
47
|
"build": "cmake-js build --target ata",
|
|
42
48
|
"rebuild": "cmake-js rebuild --target ata",
|
|
43
49
|
"prebuild": "pkg-prebuilds-copy --baseDir build/Release --source ata.node --name=ata --strip --napi_version=10",
|
|
44
50
|
"prebuild-all": "npm run prebuild -- --arch x64 && npm run prebuild -- --arch arm64",
|
|
45
|
-
"test": "node test.js && node tests/test_no_native.js && node tests/test_browser_nofs.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_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.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_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",
|
|
51
|
+
"test": "node test.js && node tests/test_no_native.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_typed_validator_runner.js && node tests/test_define_schema.js && node tests/test_error_codes_lock.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",
|
|
46
52
|
"bench:size": "node benchmark/bench_aot_size.mjs",
|
|
47
53
|
"test:suite": "node tests/run_suite.js",
|
|
48
54
|
"test:compat": "node tests/test_compat.js",
|
|
@@ -101,6 +107,9 @@
|
|
|
101
107
|
"build.js",
|
|
102
108
|
"build.mjs",
|
|
103
109
|
"build.d.ts",
|
|
110
|
+
"t.js",
|
|
111
|
+
"t.mjs",
|
|
112
|
+
"t.d.ts",
|
|
104
113
|
"binding-options.js",
|
|
105
114
|
"binding/",
|
|
106
115
|
"include/",
|
|
@@ -0,0 +1,33 @@
|
|
|
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');
|
|
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
|
+
}
|
package/t.d.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// Chainable builder for ata. Each function returns a plain JSON Schema
|
|
2
|
+
// literal, so `Infer<typeof X>` from the main entry resolves the inferred
|
|
3
|
+
// TypeScript type with no additional plumbing.
|
|
4
|
+
//
|
|
5
|
+
// import { t } from 'ata-validator/t'
|
|
6
|
+
// import { Validator, Infer } from 'ata-validator'
|
|
7
|
+
//
|
|
8
|
+
// const User = t.object({
|
|
9
|
+
// name: t.string({ minLength: 1 }),
|
|
10
|
+
// age: t.integer({ minimum: 0 }),
|
|
11
|
+
// email: t.optional(t.string({ format: 'email' })),
|
|
12
|
+
// })
|
|
13
|
+
// type User = Infer<typeof User>
|
|
14
|
+
// // { name: string; age: number; email?: string }
|
|
15
|
+
//
|
|
16
|
+
// const v = new Validator(User) // schema is plain JSON Schema
|
|
17
|
+
|
|
18
|
+
import type { JSONSchema, Infer } from './index.js';
|
|
19
|
+
|
|
20
|
+
export declare const OPTIONAL: unique symbol;
|
|
21
|
+
|
|
22
|
+
/** Options for {@link TBuilder.refine}. */
|
|
23
|
+
export interface RefineOptions {
|
|
24
|
+
/** Message attached to the error when the refinement fails. */
|
|
25
|
+
message?: string;
|
|
26
|
+
/** instancePath the error points at (e.g. `/email`). Defaults to the root. */
|
|
27
|
+
path?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A refinement check: receives the structurally-valid value, returns (a promise of) a boolean. */
|
|
31
|
+
export type RefineCheck<T> = (value: T) => boolean | Promise<boolean>;
|
|
32
|
+
|
|
33
|
+
export type TOptional<S> = S & { readonly [OPTIONAL]: true };
|
|
34
|
+
|
|
35
|
+
export type TSchema = JSONSchema;
|
|
36
|
+
|
|
37
|
+
export interface StringOptions {
|
|
38
|
+
minLength?: number;
|
|
39
|
+
maxLength?: number;
|
|
40
|
+
pattern?: string;
|
|
41
|
+
format?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
title?: string;
|
|
44
|
+
default?: string;
|
|
45
|
+
examples?: readonly string[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface NumericOptions {
|
|
49
|
+
minimum?: number;
|
|
50
|
+
maximum?: number;
|
|
51
|
+
exclusiveMinimum?: number;
|
|
52
|
+
exclusiveMaximum?: number;
|
|
53
|
+
multipleOf?: number;
|
|
54
|
+
description?: string;
|
|
55
|
+
title?: string;
|
|
56
|
+
default?: number;
|
|
57
|
+
examples?: readonly number[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ArrayOptions {
|
|
61
|
+
minItems?: number;
|
|
62
|
+
maxItems?: number;
|
|
63
|
+
uniqueItems?: boolean;
|
|
64
|
+
description?: string;
|
|
65
|
+
title?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ObjectOptions {
|
|
69
|
+
additionalProperties?: boolean | JSONSchema;
|
|
70
|
+
description?: string;
|
|
71
|
+
title?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface RecordOptions {
|
|
75
|
+
minProperties?: number;
|
|
76
|
+
maxProperties?: number;
|
|
77
|
+
description?: string;
|
|
78
|
+
title?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// `Omit` against an `OPTIONAL`-branded schema collapses literal property types
|
|
82
|
+
// through the JSONSchema index signature, which breaks downstream `Infer`. The
|
|
83
|
+
// branded property is a Symbol key, so it doesn't intersect with any string
|
|
84
|
+
// index lookup; we leave it in place and just compute `RequiredKeys` from it.
|
|
85
|
+
// Infer reads `type`, `properties`, etc. and ignores extra phantom keys.
|
|
86
|
+
|
|
87
|
+
type RequiredKeysOf<T> = {
|
|
88
|
+
[K in keyof T]: T[K] extends { readonly [OPTIONAL]: true } ? never : K;
|
|
89
|
+
}[keyof T];
|
|
90
|
+
|
|
91
|
+
type StrippedProperties<T> = { [K in keyof T]: T[K] };
|
|
92
|
+
|
|
93
|
+
export interface TString extends JSONSchema {
|
|
94
|
+
type: 'string';
|
|
95
|
+
minLength?: number;
|
|
96
|
+
maxLength?: number;
|
|
97
|
+
pattern?: string;
|
|
98
|
+
format?: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
title?: string;
|
|
101
|
+
default?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface TNumber extends JSONSchema {
|
|
105
|
+
type: 'number';
|
|
106
|
+
minimum?: number;
|
|
107
|
+
maximum?: number;
|
|
108
|
+
exclusiveMinimum?: number;
|
|
109
|
+
exclusiveMaximum?: number;
|
|
110
|
+
multipleOf?: number;
|
|
111
|
+
description?: string;
|
|
112
|
+
title?: string;
|
|
113
|
+
default?: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface TInteger extends JSONSchema {
|
|
117
|
+
type: 'integer';
|
|
118
|
+
minimum?: number;
|
|
119
|
+
maximum?: number;
|
|
120
|
+
exclusiveMinimum?: number;
|
|
121
|
+
exclusiveMaximum?: number;
|
|
122
|
+
multipleOf?: number;
|
|
123
|
+
description?: string;
|
|
124
|
+
title?: string;
|
|
125
|
+
default?: number;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface TBoolean extends JSONSchema { type: 'boolean' }
|
|
129
|
+
export interface TNull extends JSONSchema { type: 'null' }
|
|
130
|
+
|
|
131
|
+
export interface TLiteral<V extends string | number | boolean | null> extends JSONSchema { const: V }
|
|
132
|
+
export interface TEnum<V extends readonly (string | number | boolean | null)[]> extends JSONSchema { enum: V }
|
|
133
|
+
|
|
134
|
+
export interface TArray<S extends JSONSchema> extends JSONSchema {
|
|
135
|
+
type: 'array';
|
|
136
|
+
items: S;
|
|
137
|
+
minItems?: number;
|
|
138
|
+
maxItems?: number;
|
|
139
|
+
uniqueItems?: boolean;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface TTuple<S extends ReadonlyArray<JSONSchema>> extends JSONSchema {
|
|
143
|
+
type: 'array';
|
|
144
|
+
prefixItems: S;
|
|
145
|
+
items: false;
|
|
146
|
+
minItems?: number;
|
|
147
|
+
maxItems?: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface TRecord<S extends JSONSchema> extends JSONSchema {
|
|
151
|
+
type: 'object';
|
|
152
|
+
additionalProperties: S;
|
|
153
|
+
minProperties?: number;
|
|
154
|
+
maxProperties?: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface TObject<T extends Record<string, JSONSchema>> extends JSONSchema {
|
|
158
|
+
type: 'object';
|
|
159
|
+
properties: StrippedProperties<T>;
|
|
160
|
+
required: ReadonlyArray<Extract<RequiredKeysOf<T>, string>>;
|
|
161
|
+
additionalProperties?: boolean | JSONSchema;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface TUnion<S extends ReadonlyArray<JSONSchema>> extends JSONSchema { anyOf: S }
|
|
165
|
+
export interface TIntersect<S extends ReadonlyArray<JSONSchema>> extends JSONSchema { allOf: S }
|
|
166
|
+
export interface TRef extends JSONSchema { $ref: string }
|
|
167
|
+
export interface TAny extends JSONSchema {}
|
|
168
|
+
export interface TNever extends JSONSchema { not: {} }
|
|
169
|
+
|
|
170
|
+
export interface TBuilder {
|
|
171
|
+
string(opts?: StringOptions): TString;
|
|
172
|
+
number(opts?: NumericOptions): TNumber;
|
|
173
|
+
integer(opts?: NumericOptions): TInteger;
|
|
174
|
+
boolean(): TBoolean;
|
|
175
|
+
null(): TNull;
|
|
176
|
+
|
|
177
|
+
literal<const V extends string | number | boolean | null>(value: V): TLiteral<V>;
|
|
178
|
+
const<const V extends string | number | boolean | null>(value: V): TLiteral<V>;
|
|
179
|
+
enum<const V extends readonly (string | number | boolean | null)[]>(values: V): TEnum<V>;
|
|
180
|
+
|
|
181
|
+
array<S extends JSONSchema>(items: S, opts?: ArrayOptions): TArray<S>;
|
|
182
|
+
tuple<const S extends ReadonlyArray<JSONSchema>>(items: S, opts?: ArrayOptions): TTuple<S>;
|
|
183
|
+
record<S extends JSONSchema>(values: S, opts?: RecordOptions): TRecord<S>;
|
|
184
|
+
|
|
185
|
+
object<const T extends Record<string, JSONSchema>>(properties: T, opts?: ObjectOptions): TObject<T>;
|
|
186
|
+
optional<S extends JSONSchema>(schema: S): TOptional<S>;
|
|
187
|
+
|
|
188
|
+
union<const S extends ReadonlyArray<JSONSchema>>(schemas: S): TUnion<S>;
|
|
189
|
+
intersect<const S extends ReadonlyArray<JSONSchema>>(schemas: S): TIntersect<S>;
|
|
190
|
+
ref(pointer: string): TRef;
|
|
191
|
+
|
|
192
|
+
any(): TAny;
|
|
193
|
+
unknown(): TAny;
|
|
194
|
+
never(): TNever;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Attach an async (or sync) refinement to a schema. The schema stays plain
|
|
198
|
+
* JSON Schema for structural validation; the refinement runs only via
|
|
199
|
+
* `validateAsync()` / `parseAsync()`. Compose by wrapping again. The returned
|
|
200
|
+
* schema infers the same type, so `Infer<typeof refined>` is unchanged.
|
|
201
|
+
*/
|
|
202
|
+
refine<S extends JSONSchema>(schema: S, check: RefineCheck<Infer<S>>, opts?: RefineOptions): S;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export declare const t: TBuilder;
|
package/t.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// CJS entry for `ata-validator/t`. The implementation lives in `lib/t.js`
|
|
4
|
+
// so the default entry can lazy-require it for users who never touch the
|
|
5
|
+
// builder. Re-export shape matches the `TBuilder` interface in `t.d.ts`.
|
|
6
|
+
|
|
7
|
+
const t = require('./lib/t');
|
|
8
|
+
|
|
9
|
+
module.exports = { t, OPTIONAL: t.OPTIONAL };
|