ascertain 0.14.39 → 0.15.0-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/LICENSE +21 -0
- package/README.md +51 -10
- package/build/index.cjs +221 -58
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +65 -34
- package/build/index.js +210 -56
- package/build/index.js.map +1 -1
- package/package.json +22 -12
- package/src/index.js +0 -201
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2019-2024 Ivan Zakharchanka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -12,19 +12,56 @@
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- and/or validation
|
|
20
|
-
- object keys validation
|
|
21
|
-
- object values validation
|
|
15
|
+
- Type-safe validation: Ensures your data conforms to predefined schemas.
|
|
16
|
+
- Composite schemas: Supports logical AND, OR, and optional schemas.
|
|
17
|
+
- Type casting: Automatically parse and cast strings to other types.
|
|
18
|
+
- Error handling: Provides detailed error messages for invalid data.
|
|
22
19
|
|
|
23
20
|
## Usage Example
|
|
24
21
|
|
|
22
|
+
### Schema compilation
|
|
23
|
+
```typescript
|
|
24
|
+
import { compile, optional, and, or, $keys, $values, Schema, as } from 'ascertain';
|
|
25
|
+
|
|
26
|
+
const validate = compile({
|
|
27
|
+
number: Number,
|
|
28
|
+
string: String,
|
|
29
|
+
boolean: Boolean,
|
|
30
|
+
function: Function,
|
|
31
|
+
array: Array,
|
|
32
|
+
object: Object,
|
|
33
|
+
date: and(Date, { toJSON: Function }),
|
|
34
|
+
regexp: /regexp/,
|
|
35
|
+
oneOfValue: or(1, 2, 3),
|
|
36
|
+
arrayOfNumbers: [Number],
|
|
37
|
+
objectSchema: {
|
|
38
|
+
number: Number,
|
|
39
|
+
},
|
|
40
|
+
optional: optional({
|
|
41
|
+
number: Number,
|
|
42
|
+
}),
|
|
43
|
+
keyValue: {
|
|
44
|
+
[$keys]: /^key[A-Z]/,
|
|
45
|
+
[$values]: Number
|
|
46
|
+
},
|
|
47
|
+
parsedNumber: Number,
|
|
48
|
+
parsedString: String,
|
|
49
|
+
parsedBoolean: Boolean,
|
|
50
|
+
parsedArray: [String],
|
|
51
|
+
parsedJSON: {
|
|
52
|
+
number: 1,
|
|
53
|
+
},
|
|
54
|
+
parsedBase64: String,
|
|
55
|
+
parsedTime: 2 * 60 * 1000, // two minutes
|
|
56
|
+
parsedDate: Date,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Runtime validation
|
|
25
62
|
Create data ascertain
|
|
26
63
|
```typescript
|
|
27
|
-
import ascertain,
|
|
64
|
+
import { ascertain, optional, and, or, $keys, $values, Schema, as } from 'ascertain';
|
|
28
65
|
|
|
29
66
|
// create data sample
|
|
30
67
|
const data = {
|
|
@@ -49,11 +86,13 @@ const data = {
|
|
|
49
86
|
},
|
|
50
87
|
// fault tolernat type casting
|
|
51
88
|
parsedNumber: as.number('1'),
|
|
52
|
-
parsedString: as.
|
|
89
|
+
parsedString: as.string('string'),
|
|
53
90
|
parsedBoolean: as.boolean('false'),
|
|
54
91
|
parsedArray: as.array('1,2,3,4,5', ','),
|
|
55
92
|
parsedJSON: as.json('{ "number": 1 }'),
|
|
56
93
|
parsedBase64: as.base64('dGVzdA=='),
|
|
94
|
+
parsedTime: as.time('2m'),
|
|
95
|
+
parsedDate: as.date('31-12-2024'),
|
|
57
96
|
};
|
|
58
97
|
|
|
59
98
|
// create data schema
|
|
@@ -86,6 +125,8 @@ const schema: Schema<typeof data> = {
|
|
|
86
125
|
number: 1,
|
|
87
126
|
},
|
|
88
127
|
parsedBase64: String,
|
|
128
|
+
parsedTime: 2 * 60 * 1000, // two minutes
|
|
129
|
+
parsedDate: Date,
|
|
89
130
|
};
|
|
90
131
|
|
|
91
132
|
// validate
|
|
@@ -94,7 +135,7 @@ const validate = ascertain<typeof data>(schema, data, '[DATA]');
|
|
|
94
135
|
|
|
95
136
|
## License
|
|
96
137
|
License [The MIT License](http://opensource.org/licenses/MIT)
|
|
97
|
-
Copyright (c) 2024 Ivan Zakharchanka
|
|
138
|
+
Copyright (c) 2019-2024 Ivan Zakharchanka
|
|
98
139
|
|
|
99
140
|
[npm-url]: https://www.npmjs.com/package/ascertain
|
|
100
141
|
[downloads-image]: https://img.shields.io/npm/dw/ascertain.svg?maxAge=43200
|
package/build/index.cjs
CHANGED
|
@@ -15,6 +15,12 @@ _export(exports, {
|
|
|
15
15
|
$values: function() {
|
|
16
16
|
return $values;
|
|
17
17
|
},
|
|
18
|
+
AssertError: function() {
|
|
19
|
+
return AssertError;
|
|
20
|
+
},
|
|
21
|
+
Context: function() {
|
|
22
|
+
return Context;
|
|
23
|
+
},
|
|
18
24
|
and: function() {
|
|
19
25
|
return and;
|
|
20
26
|
},
|
|
@@ -24,8 +30,8 @@ _export(exports, {
|
|
|
24
30
|
ascertain: function() {
|
|
25
31
|
return ascertain;
|
|
26
32
|
},
|
|
27
|
-
|
|
28
|
-
return
|
|
33
|
+
compile: function() {
|
|
34
|
+
return compile;
|
|
29
35
|
},
|
|
30
36
|
fromBase64: function() {
|
|
31
37
|
return fromBase64;
|
|
@@ -35,63 +41,53 @@ _export(exports, {
|
|
|
35
41
|
},
|
|
36
42
|
or: function() {
|
|
37
43
|
return or;
|
|
44
|
+
},
|
|
45
|
+
tuple: function() {
|
|
46
|
+
return tuple;
|
|
38
47
|
}
|
|
39
48
|
});
|
|
40
|
-
|
|
49
|
+
class AssertError extends TypeError {
|
|
50
|
+
value;
|
|
51
|
+
expected;
|
|
52
|
+
path;
|
|
53
|
+
subject;
|
|
54
|
+
static join(errors, separator = ' or ') {
|
|
55
|
+
return new AssertError(errors[0].value, errors.map((e)=>`${e.expected}`).join(separator), errors[0].path, errors[0].subject);
|
|
56
|
+
}
|
|
41
57
|
constructor(value, expected, path, subject = 'value'){
|
|
58
|
+
super(`Invalid ${subject} ${JSON.stringify(value)} for path ${path}, expected ${expected}.`);
|
|
42
59
|
this.value = value;
|
|
43
60
|
this.expected = expected;
|
|
44
61
|
this.path = path;
|
|
45
62
|
this.subject = subject;
|
|
46
63
|
}
|
|
47
|
-
toString() {
|
|
48
|
-
return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
function findFirstError(array, map) {
|
|
52
|
-
for(let i = 0; i < array.length; i++){
|
|
53
|
-
const error = map(array[i], i);
|
|
54
|
-
if (error) {
|
|
55
|
-
return error;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return false;
|
|
59
64
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
} else {
|
|
67
|
-
errors.push(error);
|
|
65
|
+
class Operation {
|
|
66
|
+
schemas;
|
|
67
|
+
constructor(schemas){
|
|
68
|
+
this.schemas = schemas;
|
|
69
|
+
if (schemas.length === 0) {
|
|
70
|
+
throw new TypeError(`Operation schema ${this.constructor.name} must have at least one element`);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
|
-
return errors.reduce((result, error)=>{
|
|
71
|
-
return new AssertError(result.value, [
|
|
72
|
-
result.expected,
|
|
73
|
-
error.expected
|
|
74
|
-
].join(' or '), result.path, result.string);
|
|
75
|
-
});
|
|
76
73
|
}
|
|
77
|
-
|
|
78
|
-
this.schema = schema;
|
|
74
|
+
class Or extends Operation {
|
|
79
75
|
}
|
|
80
|
-
|
|
81
|
-
|
|
76
|
+
const or = (...schemas)=>new Or(schemas);
|
|
77
|
+
class And extends Operation {
|
|
82
78
|
}
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
const and = (...schemas)=>new And(schemas);
|
|
80
|
+
class Optional extends Operation {
|
|
81
|
+
constructor(schema){
|
|
82
|
+
super([
|
|
83
|
+
schema
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
85
86
|
}
|
|
86
|
-
const optional = (schema)=>
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
const
|
|
90
|
-
return new And(schema);
|
|
91
|
-
};
|
|
92
|
-
const or = (...schema)=>{
|
|
93
|
-
return new Or(schema);
|
|
94
|
-
};
|
|
87
|
+
const optional = (schema)=>new Optional(schema);
|
|
88
|
+
class Tuple extends Operation {
|
|
89
|
+
}
|
|
90
|
+
const tuple = (...schemas)=>new Tuple(schemas);
|
|
95
91
|
const $keys = Symbol.for('@@keys');
|
|
96
92
|
const $values = Symbol.for('@@values');
|
|
97
93
|
const fromBase64 = typeof Buffer === 'undefined' ? (value)=>atob(value) : (value)=>Buffer.from(value, 'base64').toString('utf-8');
|
|
@@ -118,7 +114,7 @@ const as = {
|
|
|
118
114
|
time: (value)=>{
|
|
119
115
|
const matches = value?.match(/^(\d+)(ms|s|m|h|d|w)?$/);
|
|
120
116
|
if (matches) {
|
|
121
|
-
const [
|
|
117
|
+
const [, amount, unit = 'ms'] = matches;
|
|
122
118
|
return parseInt(amount, 10) * MULTIPLIERS[unit];
|
|
123
119
|
}
|
|
124
120
|
return undefined;
|
|
@@ -140,28 +136,196 @@ const as = {
|
|
|
140
136
|
}
|
|
141
137
|
}
|
|
142
138
|
};
|
|
143
|
-
|
|
139
|
+
class Context {
|
|
140
|
+
options;
|
|
141
|
+
Error;
|
|
142
|
+
errors;
|
|
143
|
+
registry;
|
|
144
|
+
varIndex;
|
|
145
|
+
constructor(options = {}){
|
|
146
|
+
this.options = options;
|
|
147
|
+
this.errors = [];
|
|
148
|
+
this.registry = [];
|
|
149
|
+
this.varIndex = 0;
|
|
150
|
+
this.Error = options.error ?? AssertError;
|
|
151
|
+
}
|
|
152
|
+
error(errors) {
|
|
153
|
+
this.errors.push(...errors);
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
register(value) {
|
|
157
|
+
if (!this.registry.includes(value)) {
|
|
158
|
+
this.registry.push(value);
|
|
159
|
+
}
|
|
160
|
+
return this.registry.indexOf(value);
|
|
161
|
+
}
|
|
162
|
+
unique(prefix) {
|
|
163
|
+
return `${prefix}$$${this.varIndex++}`;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const codeGen = (schema, context, valuePath, path)=>{
|
|
167
|
+
if (schema instanceof And) {
|
|
168
|
+
const valueAlias = context.unique('v');
|
|
169
|
+
const errorsAlias = context.unique('err');
|
|
170
|
+
const code = schema.schemas.map((s)=>`try { ${codeGen(s, context, valueAlias, path)} } catch (e) { ${errorsAlias}.push(e); }`).join('\n');
|
|
171
|
+
return `// And
|
|
172
|
+
const ${errorsAlias} = [];
|
|
173
|
+
const ${valueAlias} = ${valuePath};
|
|
174
|
+
${code}
|
|
175
|
+
if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ' and '); }
|
|
176
|
+
`;
|
|
177
|
+
} else if (schema instanceof Or) {
|
|
178
|
+
const valueAlias = context.unique('v');
|
|
179
|
+
const errorsAlias = context.unique('err');
|
|
180
|
+
const code = schema.schemas.map((s)=>codeGen(s, context, valueAlias, path)).reduceRight((result, code)=>`try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw ctx.Error.join(${errorsAlias}, ' or ')`);
|
|
181
|
+
return `// Or
|
|
182
|
+
const ${errorsAlias} = [];
|
|
183
|
+
const ${valueAlias} = ${valuePath};
|
|
184
|
+
${code}
|
|
185
|
+
`;
|
|
186
|
+
} else if (schema instanceof Optional) {
|
|
187
|
+
const valueAlias = context.unique('v');
|
|
188
|
+
return `// Optional
|
|
189
|
+
const ${valueAlias} = ${valuePath};
|
|
190
|
+
if (${valueAlias} !== undefined && ${valueAlias} !== null) { ${codeGen(schema.schemas[0], context, valueAlias, path)} }
|
|
191
|
+
`;
|
|
192
|
+
} else if (schema instanceof Tuple) {
|
|
193
|
+
const valueAlias = context.unique('v');
|
|
194
|
+
const errorsAlias = context.unique('err');
|
|
195
|
+
const code = schema.schemas.map((s, idx)=>`try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`).join('\n');
|
|
196
|
+
return `// Tuple
|
|
197
|
+
const ${valueAlias} = ${valuePath};
|
|
198
|
+
const ${errorsAlias} = [];
|
|
199
|
+
if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'Array', \`${path}\`); }
|
|
200
|
+
${code}
|
|
201
|
+
if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
if (typeof schema === 'function') {
|
|
205
|
+
const index = context.register(schema);
|
|
206
|
+
const valueAlias = context.unique('v');
|
|
207
|
+
const registryAlias = context.unique('r');
|
|
208
|
+
return `
|
|
209
|
+
const ${valueAlias} = ${valuePath};
|
|
210
|
+
const ${registryAlias} = ctx.registry[${index}];
|
|
211
|
+
if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'a non-nullable', \`${path}\`); }
|
|
212
|
+
if (typeof ${valueAlias} === 'object' && !(${valueAlias} instanceof ${registryAlias})) { throw new ctx.Error(${valueAlias}?.constructor?.name, \`instance of \${${registryAlias}.name}\`, \`${path}\`, 'instance of'); }
|
|
213
|
+
else if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \`${path}\`, 'type'); }
|
|
214
|
+
`;
|
|
215
|
+
} else if (Array.isArray(schema)) {
|
|
216
|
+
const valueAlias = context.unique('v');
|
|
217
|
+
const code = [
|
|
218
|
+
`const ${valueAlias} = ${valuePath};`,
|
|
219
|
+
`if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`
|
|
220
|
+
];
|
|
221
|
+
if (schema.length > 0) {
|
|
222
|
+
const value = context.unique('val');
|
|
223
|
+
const key = context.unique('key');
|
|
224
|
+
const errorsAlias = context.unique('err');
|
|
225
|
+
const orCode = schema.map((s)=>codeGen(s, context, value, `${path}[\${${key}}]`)).reduceRight((result, code)=>`try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw ctx.Error.join(${errorsAlias}, ' or ')`);
|
|
226
|
+
code.push(`for(const ${key} in ${valueAlias}) {`, `const ${errorsAlias} = [];`, `const ${value} = ${valueAlias}[${key}];`, orCode, `}`);
|
|
227
|
+
}
|
|
228
|
+
return code.join('\n');
|
|
229
|
+
} else if (typeof schema === 'object' && schema !== null) {
|
|
230
|
+
if (schema instanceof RegExp) {
|
|
231
|
+
const valueAlias = context.unique('v');
|
|
232
|
+
return `
|
|
233
|
+
const ${valueAlias} = ${valuePath};
|
|
234
|
+
if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valueAlias}, 'matching ${schema.toString()}', \`${path}\`); }
|
|
235
|
+
`;
|
|
236
|
+
} else {
|
|
237
|
+
const valueAlias = context.unique('v');
|
|
238
|
+
const code = [
|
|
239
|
+
`const ${valueAlias} = ${valuePath};`,
|
|
240
|
+
`if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`,
|
|
241
|
+
`if (${valueAlias} === null) { throw new ctx.Error(${valueAlias}, 'object', \`${path}\`); }`
|
|
242
|
+
];
|
|
243
|
+
if ($keys in schema) {
|
|
244
|
+
const keysAlias = context.unique('key');
|
|
245
|
+
const errorsAlias = context.unique('err');
|
|
246
|
+
const value = context.unique('v');
|
|
247
|
+
code.push(`
|
|
248
|
+
const ${keysAlias} = Object.keys(${valueAlias});
|
|
249
|
+
const ${errorsAlias} = ${keysAlias}.map((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).flat().filter(Boolean);
|
|
250
|
+
if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
|
|
251
|
+
`);
|
|
252
|
+
}
|
|
253
|
+
if ($values in schema) {
|
|
254
|
+
const vAlias = context.unique('val');
|
|
255
|
+
const valuesAlias = context.unique('vals');
|
|
256
|
+
const errorsAlias = context.unique('err');
|
|
257
|
+
code.push(`{
|
|
258
|
+
const ${valuesAlias} = Object.values(${valuePath});
|
|
259
|
+
const ${errorsAlias} = ${valuesAlias}.map((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).flat().filter(Boolean);
|
|
260
|
+
if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
|
|
261
|
+
}`);
|
|
262
|
+
}
|
|
263
|
+
const keys = Object.keys(schema);
|
|
264
|
+
code.push(...keys.map((key)=>codeGen(schema[key], context, `${valueAlias}['${key}']`, `${path}.${key}`)));
|
|
265
|
+
return `{${code.join('\n')}}`;
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
const valueAlias = context.unique('v');
|
|
269
|
+
return `
|
|
270
|
+
const ${valueAlias} = ${valuePath};
|
|
271
|
+
if (${valueAlias} !== ${schema}) { throw new ctx.Error(${valueAlias}, ${schema}, \`${path}\`); }
|
|
272
|
+
`;
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
const compile = (schema, rootName, options = {})=>{
|
|
276
|
+
const context = new Context(options);
|
|
277
|
+
const code = codeGen(schema, context, 'data', rootName);
|
|
278
|
+
const validator = new Function('ctx', 'data', code);
|
|
279
|
+
return (data)=>validator(context, data);
|
|
280
|
+
};
|
|
281
|
+
const findFirstError = (array, map)=>{
|
|
282
|
+
for(let i = 0; i < array.length; i++){
|
|
283
|
+
const error = map(array[i], i);
|
|
284
|
+
if (error) {
|
|
285
|
+
return error;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return false;
|
|
289
|
+
};
|
|
290
|
+
const findNotError = (array, map)=>{
|
|
291
|
+
const errors = [];
|
|
292
|
+
for(let i = 0; i < array.length; i++){
|
|
293
|
+
const error = map(array[i], i);
|
|
294
|
+
if (!error) {
|
|
295
|
+
return false;
|
|
296
|
+
} else {
|
|
297
|
+
errors.push(error);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return errors.reduce((result, error)=>{
|
|
301
|
+
return new AssertError(result.value, [
|
|
302
|
+
result.expected,
|
|
303
|
+
error.expected
|
|
304
|
+
].join(' or '), result.path, result.subject);
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
const assert = (target, schema, path, optional = false)=>{
|
|
144
308
|
if (schema === null || typeof schema === 'undefined') {
|
|
145
309
|
return new AssertError(schema, 'any value', path, 'schema value');
|
|
146
310
|
}
|
|
147
311
|
if (schema instanceof Optional) {
|
|
148
|
-
return
|
|
312
|
+
return assert(target, schema.schemas[0], path, true);
|
|
149
313
|
}
|
|
150
314
|
const isValue = target !== null && typeof target !== 'undefined';
|
|
151
315
|
if (!isValue && optional) {
|
|
152
316
|
return;
|
|
153
317
|
}
|
|
154
318
|
if (schema instanceof Or) {
|
|
155
|
-
if (!schema.
|
|
319
|
+
if (!schema.schemas.length) {
|
|
156
320
|
return new AssertError(target, 'values', path, 'OR schema');
|
|
157
321
|
}
|
|
158
|
-
return findNotError(schema.
|
|
322
|
+
return findNotError(schema.schemas, (schema)=>assert(target, schema, path));
|
|
159
323
|
}
|
|
160
324
|
if (schema instanceof And) {
|
|
161
|
-
if (!schema.
|
|
325
|
+
if (!schema.schemas.length) {
|
|
162
326
|
return new AssertError(target, 'values', path, 'AND schema');
|
|
163
327
|
}
|
|
164
|
-
return findFirstError(schema.
|
|
328
|
+
return findFirstError(schema.schemas, (schema)=>assert(target, schema, path));
|
|
165
329
|
}
|
|
166
330
|
if (typeof schema === 'function') {
|
|
167
331
|
if (!isValue) {
|
|
@@ -178,7 +342,7 @@ function certain(target, schema, path, optional) {
|
|
|
178
342
|
return new AssertError(target, schema.constructor.name, path);
|
|
179
343
|
}
|
|
180
344
|
return findFirstError(target, (value, idx)=>{
|
|
181
|
-
return findNotError(schema, (itemSchemaType)=>
|
|
345
|
+
return findNotError(schema, (itemSchemaType)=>assert(value, itemSchemaType, `${path}.${idx}`));
|
|
182
346
|
});
|
|
183
347
|
} else if (typeof schema === 'object') {
|
|
184
348
|
if (schema instanceof RegExp) {
|
|
@@ -194,30 +358,29 @@ function certain(target, schema, path, optional) {
|
|
|
194
358
|
}
|
|
195
359
|
if ($keys in schema) {
|
|
196
360
|
const targetKeys = Object.keys(target);
|
|
197
|
-
const assertError = findFirstError(targetKeys, (targetKey)=>
|
|
361
|
+
const assertError = findFirstError(targetKeys, (targetKey)=>assert(targetKey, schema[$keys], `${path}.${targetKey}`));
|
|
198
362
|
if (assertError) {
|
|
199
363
|
return assertError;
|
|
200
364
|
}
|
|
201
365
|
}
|
|
202
366
|
if ($values in schema) {
|
|
203
367
|
const targetKeys = Object.keys(target);
|
|
204
|
-
const assertError = findFirstError(targetKeys, (targetKey)=>
|
|
368
|
+
const assertError = findFirstError(targetKeys, (targetKey)=>assert(target[targetKey], schema[$values], `${path}.${targetKey}`));
|
|
205
369
|
if (assertError) {
|
|
206
370
|
return assertError;
|
|
207
371
|
}
|
|
208
372
|
}
|
|
209
|
-
return findFirstError(Object.keys(schema), (key)=>
|
|
373
|
+
return findFirstError(Object.keys(schema), (key)=>assert(target[key], schema[key], `${path}.${key}`));
|
|
210
374
|
}
|
|
211
375
|
} else if (target !== schema) {
|
|
212
376
|
return new AssertError(target, schema, path);
|
|
213
377
|
}
|
|
214
|
-
}
|
|
378
|
+
};
|
|
215
379
|
const ascertain = (schema, data, rootName = '[root]')=>{
|
|
216
|
-
const result =
|
|
380
|
+
const result = assert(data, schema, rootName);
|
|
217
381
|
if (result instanceof AssertError) {
|
|
218
382
|
throw new TypeError(result.toString());
|
|
219
383
|
}
|
|
220
384
|
};
|
|
221
|
-
const _default = ascertain;
|
|
222
385
|
|
|
223
386
|
//# sourceMappingURL=index.cjs.map
|
package/build/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["class AssertError {\n constructor(value, expected, path, subject = 'value') {\n this.value = value;\n this.expected = expected;\n this.path = path;\n this.subject = subject;\n }\n\n toString() {\n return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;\n }\n}\n\nfunction findFirstError(array, map) {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n}\n\nfunction findNotError(array, map) {\n const errors = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);\n });\n}\n\nfunction Optional(schema) {\n this.schema = schema;\n}\n\nfunction And(schema) {\n this.schema = schema;\n}\n\nfunction Or(schema) {\n this.schema = schema;\n}\n\nexport const optional = (schema) => {\n return new Optional(schema);\n};\n\nexport const and = (...schema) => {\n return new And(schema);\n};\n\nexport const or = (...schema) => {\n return new Or(schema);\n};\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\n\nexport const fromBase64 =\n typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value) => {\n const result = parseFloat(value);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value) => {\n const result = Date.parse(value);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [_, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit];\n }\n return undefined;\n },\n boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),\n array: (value, delimiter) => value?.split(delimiter) ?? undefined,\n json: (value) => {\n try {\n return JSON.parse(value);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value) => {\n try {\n return fromBase64(value);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nfunction certain(target, schema, path, optional) {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return certain(target, schema.schema, path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schema, (schema) => certain(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schema, (schema) => certain(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(targetKey, schema[$keys], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(target[targetKey], schema[$values], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n}\n\nexport const ascertain = (schema, data, rootName = '[root]') => {\n const result = certain(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n\nexport default ascertain;\n"],"names":["$keys","$values","and","as","ascertain","fromBase64","optional","or","AssertError","constructor","value","expected","path","subject","toString","JSON","stringify","findFirstError","array","map","i","length","error","findNotError","errors","push","reduce","result","join","string","Optional","schema","And","Or","Symbol","for","Buffer","atob","from","MULTIPLIERS","ms","s","m","h","d","w","undefined","number","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","_","amount","unit","parseInt","boolean","test","delimiter","split","json","e","base64","certain","target","isValue","name","Array","isArray","idx","itemSchemaType","RegExp","source","targetKeys","Object","keys","assertError","targetKey","key","data","rootName","TypeError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class AssertError extends TypeError {\n static join(errors: AssertError[], separator = ' or ') {\n return new AssertError(errors[0].value, errors.map((e) => `${e.expected}`).join(separator), errors[0].path, errors[0].subject);\n }\n constructor(\n public readonly value: unknown,\n public readonly expected: unknown,\n public readonly path: string,\n public readonly subject = 'value',\n ) {\n super(`Invalid ${subject} ${JSON.stringify(value)} for path ${path}, expected ${expected}.`);\n }\n}\n\ntype AssertErrorConstructor = new (value: unknown, expected: unknown, path: string, subject?: string) => Error;\n\ntype Keys = string | number | symbol;\ntype DataValue = any;\ntype Data = Record<Keys, unknown>;\ntype DataArray = DataValue[];\n\nexport type Schema<T> = T extends Data ? { [S in keyof T]?: Schema<T[S]> } : T extends DataArray ? [Schema<T[number]>] : DataValue;\n\nexport type SchemaData<S> =\n S extends Record<Keys, unknown>\n ? { [K in keyof S as Exclude<K, typeof $keys | typeof $values>]?: SchemaData<S[K]> } & Record<string, unknown>\n : S extends unknown[]\n ? unknown[]\n : unknown;\n\nabstract class Operation<T extends Data = DataValue> {\n constructor(public readonly schemas: Schema<T>[]) {\n if (schemas.length === 0) {\n throw new TypeError(`Operation schema ${this.constructor.name} must have at least one element`);\n }\n }\n}\n\nclass Or<T extends Data = DataValue> extends Operation<T> {}\nexport const or = <T extends Data = DataValue>(...schemas: Schema<T>[]) => new Or(schemas);\n\nclass And<T extends Data = DataValue> extends Operation<T> {}\nexport const and = <T extends Data = DataValue>(...schemas: Schema<T>[]) => new And(schemas);\n\nclass Optional<T extends Data = DataValue> extends Operation<T> {\n constructor(schema: Schema<T>) {\n super([schema]);\n }\n}\nexport const optional = <T extends Data = DataValue>(schema: Schema<T>) => new Optional(schema);\n\nclass Tuple<T extends Data = DataValue> extends Operation<T> {}\nexport const tuple = <T extends Data = DataValue>(...schemas: Schema<T>[]) => new Tuple(schemas);\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\nexport const fromBase64 = typeof Buffer === 'undefined' ? (value: string) => atob(value) : (value: string) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value: string | undefined) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value: string | undefined) => {\n const result = parseFloat(value as string);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value: string | undefined) => {\n const result = Date.parse(value as string);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value: string | undefined) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit as keyof typeof MULTIPLIERS];\n }\n return undefined;\n },\n boolean: (value: string | undefined) =>\n /^(0|1|true|false|enabled|disabled)$/i.test(value as string) ? /^(1|true|enabled)$/i.test(value as string) : undefined,\n array: (value: string | undefined, delimiter: string) => value?.split(delimiter) ?? undefined,\n json: (value: string | undefined) => {\n try {\n return JSON.parse(value as string);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value: string | undefined) => {\n try {\n return fromBase64(value as string);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nexport class Context {\n public readonly Error: AssertErrorConstructor;\n public readonly errors: AssertError[] = [];\n public readonly registry: unknown[] = [];\n private varIndex = 0;\n constructor(public readonly options: CompilerOptions = {}) {\n this.Error = options.error ?? AssertError;\n }\n\n error(errors: AssertError[]) {\n this.errors.push(...errors);\n return true;\n }\n\n register(value: unknown): number {\n if (!this.registry.includes(value)) {\n this.registry.push(value);\n }\n return this.registry.indexOf(value);\n }\n\n unique(prefix: string) {\n return `${prefix}$$${this.varIndex++}`;\n }\n}\n\nexport interface CompilerOptions {\n error?: AssertErrorConstructor;\n}\n\nconst codeGen = <T extends Data = DataValue>(schema: Schema<T>, context: Context, valuePath: string, path: string): string => {\n if (schema instanceof And) {\n const valueAlias = context.unique('v');\n const errorsAlias = context.unique('err');\n const code = schema.schemas.map((s) => `try { ${codeGen(s, context, valueAlias, path)} } catch (e) { ${errorsAlias}.push(e); }`).join('\\n');\n return `// And\n const ${errorsAlias} = [];\n const ${valueAlias} = ${valuePath};\n ${code}\n if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ' and '); }\n`;\n } else if (schema instanceof Or) {\n const valueAlias = context.unique('v');\n const errorsAlias = context.unique('err');\n const code = schema.schemas\n .map((s) => codeGen(s, context, valueAlias, path))\n .reduceRight((result, code) => `try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw ctx.Error.join(${errorsAlias}, ' or ')`);\n return `// Or\nconst ${errorsAlias} = [];\nconst ${valueAlias} = ${valuePath};\n${code}\n `;\n } else if (schema instanceof Optional) {\n const valueAlias = context.unique('v');\n return `// Optional\nconst ${valueAlias} = ${valuePath};\nif (${valueAlias} !== undefined && ${valueAlias} !== null) { ${codeGen(schema.schemas[0], context, valueAlias, path)} }\n`;\n } else if (schema instanceof Tuple) {\n const valueAlias = context.unique('v');\n const errorsAlias = context.unique('err');\n const code = schema.schemas\n .map((s, idx) => `try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`)\n .join('\\n');\n return `// Tuple\n const ${valueAlias} = ${valuePath};\n const ${errorsAlias} = [];\n if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'Array', \\`${path}\\`); }\n ${code}\n if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }\n`;\n }\n if (typeof schema === 'function') {\n const index = context.register(schema);\n const valueAlias = context.unique('v');\n const registryAlias = context.unique('r');\n return `\nconst ${valueAlias} = ${valuePath};\nconst ${registryAlias} = ctx.registry[${index}];\nif (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'a non-nullable', \\`${path}\\`); }\nif (typeof ${valueAlias} === 'object' && !(${valueAlias} instanceof ${registryAlias})) { throw new ctx.Error(${valueAlias}?.constructor?.name, \\`instance of \\${${registryAlias}.name}\\`, \\`${path}\\`, 'instance of'); }\nelse if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \\`${path}\\`, 'type'); }\n`;\n } else if (Array.isArray(schema)) {\n const valueAlias = context.unique('v');\n const code: string[] = [\n `const ${valueAlias} = ${valuePath};`,\n `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \\`${path}\\`); }`,\n ];\n if (schema.length > 0) {\n const value = context.unique('val');\n const key = context.unique('key');\n const errorsAlias = context.unique('err');\n\n const orCode = schema\n .map((s) => codeGen(s, context, value, `${path}[\\${${key}}]`))\n .reduceRight((result, code) => `try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw ctx.Error.join(${errorsAlias}, ' or ')`);\n code.push(`for(const ${key} in ${valueAlias}) {`, `const ${errorsAlias} = [];`, `const ${value} = ${valueAlias}[${key}];`, orCode, `}`);\n }\n return code.join('\\n');\n } else if (typeof schema === 'object' && schema !== null) {\n if (schema instanceof RegExp) {\n const valueAlias = context.unique('v');\n return `\nconst ${valueAlias} = ${valuePath};\nif (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valueAlias}, 'matching ${schema.toString()}', \\`${path}\\`); }\n`;\n } else {\n const valueAlias = context.unique('v');\n const code: string[] = [\n `const ${valueAlias} = ${valuePath};`,\n `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \\`${path}\\`); }`,\n `if (${valueAlias} === null) { throw new ctx.Error(${valueAlias}, 'object', \\`${path}\\`); }`,\n ];\n if ($keys in schema) {\n const keysAlias = context.unique('key');\n const errorsAlias = context.unique('err');\n const value = context.unique('v');\n code.push(`\nconst ${keysAlias} = Object.keys(${valueAlias});\nconst ${errorsAlias} = ${keysAlias}.map((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).flat().filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }\n`);\n }\n if ($values in schema) {\n const vAlias = context.unique('val');\n const valuesAlias = context.unique('vals');\n const errorsAlias = context.unique('err');\n code.push(`{\nconst ${valuesAlias} = Object.values(${valuePath});\nconst ${errorsAlias} = ${valuesAlias}.map((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).flat().filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }\n}`);\n }\n const keys = Object.keys(schema);\n code.push(...keys.map((key) => codeGen(schema[key], context, `${valueAlias}['${key}']`, `${path}.${key}`)));\n return `{${code.join('\\n')}}`;\n }\n } else {\n const valueAlias = context.unique('v');\n return `\nconst ${valueAlias} = ${valuePath};\nif (${valueAlias} !== ${schema}) { throw new ctx.Error(${valueAlias}, ${schema}, \\`${path}\\`); }\n`;\n }\n};\n\nexport const compile = <S>(schema: S, rootName: string, options: CompilerOptions = {}) => {\n const context = new Context(options);\n const code = codeGen(schema, context, 'data', rootName);\n const validator = new Function('ctx', 'data', code);\n return (data: SchemaData<S>) => validator(context, data);\n};\n\nconst findFirstError = <T>(array: T[], map: (value: T, index: number) => AssertError | false | null | void | undefined): false | AssertError => {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n};\n\nconst findNotError = <T>(array: T[], map: (value: T, index: number) => AssertError | false | null | void | undefined): false | AssertError => {\n const errors: AssertError[] = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.subject);\n });\n};\n\nconst assert = (target: unknown, schema: unknown, path: string, optional = false): AssertError | false | void => {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return assert(target, schema.schemas[0], path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schemas.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schemas, (schema) => assert(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schemas.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schemas, (schema) => assert(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => assert(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) => assert(targetKey, schema[$keys], `${path}.${targetKey}`));\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n assert(target[targetKey as keyof typeof target], schema[$values], `${path}.${targetKey}`),\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => assert(target[key as keyof typeof target], schema[key as keyof typeof target], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n};\n\nexport const ascertain = <T extends Data = DataValue>(schema: Schema<T>, data: T, rootName = '[root]') => {\n const result = assert(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n"],"names":["$keys","$values","AssertError","Context","and","as","ascertain","compile","fromBase64","optional","or","tuple","TypeError","join","errors","separator","value","map","e","expected","path","subject","constructor","JSON","stringify","Operation","schemas","length","name","Or","And","Optional","schema","Tuple","Symbol","for","Buffer","atob","from","toString","MULTIPLIERS","ms","s","m","h","d","w","string","undefined","number","result","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","amount","unit","parseInt","boolean","test","array","delimiter","split","json","base64","Error","registry","varIndex","options","error","push","register","includes","indexOf","unique","prefix","codeGen","context","valuePath","valueAlias","errorsAlias","code","reduceRight","idx","index","registryAlias","Array","isArray","key","orCode","RegExp","keysAlias","vAlias","valuesAlias","keys","Object","rootName","validator","Function","data","findFirstError","i","findNotError","reduce","assert","target","isValue","itemSchemaType","source","targetKeys","assertError","targetKey"],"mappings":"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"}
|