ascertain 0.15.0-0 → 1.0.1

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ### Ascertain what data is not suitable for your library
4
4
 
5
- 0-Deps, simple, blazing fast, for browser and node js object schema validator
5
+ 0-Deps, simple, blazing fast, for browser and Node.js object schema validator
6
6
 
7
7
  [![Coverage Status][codecov-image]][codecov-url]
8
8
  [![Build Status][github-image]][github-url]
@@ -14,9 +14,17 @@
14
14
 
15
15
  - Type-safe validation: Ensures your data conforms to predefined schemas.
16
16
  - Composite schemas: Supports logical AND, OR, and optional schemas.
17
- - Type casting: Automatically parse and cast strings to other types.
17
+ - Type casting: Automatically parses and casts strings to other types.
18
18
  - Error handling: Provides detailed error messages for invalid data.
19
19
 
20
+ ## Schema description
21
+
22
+ - Primitive Values: Any primitive value (e.g., string, number, bigint, boolean, undefined, symbol, null) is used as an expected constant to match against.
23
+ - Function Types: Functions are used as constructors for non-objects and instance types for object types.
24
+ - Array Values: Arrays are used to represent an expected array type, where every item in the array must match the specified type (acting as an "and" operator).
25
+ - Regular Expressions: Regular expressions are used to validate that a value matches a specified string pattern.
26
+ - Object Types: Non-null objects are used as templates for expected properties, where each property of the object must match the corresponding schema definition.
27
+
20
28
  ## Usage Example
21
29
 
22
30
  ### Schema compilation
@@ -133,6 +141,43 @@ const schema: Schema<typeof data> = {
133
141
  const validate = ascertain<typeof data>(schema, data, '[DATA]');
134
142
  ```
135
143
 
144
+ ### Benchmark VS zod and ajv
145
+ ```
146
+ ⭐ Script ajv-vs-zod-vs-ascertain.js
147
+ ⇶ Suite ajv vs zod vs ascertain
148
+ ➤ Perform benchmark
149
+ ✓ Measure 500000 zod static schema validation
150
+ ┌──────────┬──────────┬──────────┬──────────┬────────────┬────────┐
151
+ │ (index) │ med │ p95 │ p99 │ total │ count │
152
+ ├──────────┼──────────┼──────────┼──────────┼────────────┼────────┤
153
+ │ 0.000699 │ 0.000788 │ 0.000996 │ 0.001624 │ 462.602373 │ 500000 │
154
+ └──────────┴──────────┴──────────┴──────────┴────────────┴────────┘
155
+ ✓ Measure 500000 zod dynamic schema validation
156
+ ┌──────────┬──────────┬──────────┬──────────┬─────────────┬────────┐
157
+ │ (index) │ med │ p95 │ p99 │ total │ count │
158
+ ├──────────┼──────────┼──────────┼──────────┼─────────────┼────────┤
159
+ │ 0.006248 │ 0.006918 │ 0.007524 │ 0.016948 │ 3780.465563 │ 500000 │
160
+ └──────────┴──────────┴──────────┴──────────┴─────────────┴────────┘
161
+ ✓ Measure 500000 ascertain static schema validation
162
+ ┌──────────┬──────────┬──────────┬──────────┬───────────┬────────┐
163
+ │ (index) │ med │ p95 │ p99 │ total │ count │
164
+ ├──────────┼──────────┼──────────┼──────────┼───────────┼────────┤
165
+ │ 0.000063 │ 0.000071 │ 0.000098 │ 0.000267 │ 41.673271 │ 500000 │
166
+ └──────────┴──────────┴──────────┴──────────┴───────────┴────────┘
167
+ ✓ Measure 500000 ascertain dynamic schema validation
168
+ ┌──────────┬──────────┬──────────┬──────────┬────────────┬────────┐
169
+ │ (index) │ med │ p95 │ p99 │ total │ count │
170
+ ├──────────┼──────────┼──────────┼──────────┼────────────┼────────┤
171
+ │ 0.000367 │ 0.000415 │ 0.000525 │ 0.001055 │ 239.078129 │ 500000 │
172
+ └──────────┴──────────┴──────────┴──────────┴────────────┴────────┘
173
+ ✓ Measure 500000 ajv compiled schema validation
174
+ ┌──────────┬──────────┬──────────┬──────────┬───────────┬────────┐
175
+ │ (index) │ med │ p95 │ p99 │ total │ count │
176
+ ├──────────┼──────────┼──────────┼──────────┼───────────┼────────┤
177
+ │ 0.000063 │ 0.000072 │ 0.000124 │ 0.000307 │ 44.542936 │ 500000 │
178
+ └──────────┴──────────┴──────────┴──────────┴───────────┴────────┘
179
+ ```
180
+
136
181
  ## License
137
182
  License [The MIT License](http://opensource.org/licenses/MIT)
138
183
  Copyright (c) 2019-2024 Ivan Zakharchanka
package/build/index.cjs CHANGED
@@ -18,9 +18,6 @@ _export(exports, {
18
18
  AssertError: function() {
19
19
  return AssertError;
20
20
  },
21
- Context: function() {
22
- return Context;
23
- },
24
21
  and: function() {
25
22
  return and;
26
23
  },
@@ -51,9 +48,6 @@ class AssertError extends TypeError {
51
48
  expected;
52
49
  path;
53
50
  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
- }
57
51
  constructor(value, expected, path, subject = 'value'){
58
52
  super(`Invalid ${subject} ${JSON.stringify(value)} for path ${path}, expected ${expected}.`);
59
53
  this.value = value;
@@ -120,7 +114,7 @@ const as = {
120
114
  return undefined;
121
115
  },
122
116
  boolean: (value)=>/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined,
123
- array: (value, delimiter)=>value?.split(delimiter) ?? undefined,
117
+ array: (value, delimiter)=>value?.split?.(delimiter) ?? undefined,
124
118
  json: (value)=>{
125
119
  try {
126
120
  return JSON.parse(value);
@@ -139,20 +133,14 @@ const as = {
139
133
  class Context {
140
134
  options;
141
135
  Error;
142
- errors;
143
136
  registry;
144
137
  varIndex;
145
138
  constructor(options = {}){
146
139
  this.options = options;
147
- this.errors = [];
148
140
  this.registry = [];
149
141
  this.varIndex = 0;
150
142
  this.Error = options.error ?? AssertError;
151
143
  }
152
- error(errors) {
153
- this.errors.push(...errors);
154
- return true;
155
- }
156
144
  register(value) {
157
145
  if (!this.registry.includes(value)) {
158
146
  this.registry.push(value);
@@ -172,12 +160,12 @@ const codeGen = (schema, context, valuePath, path)=>{
172
160
  const ${errorsAlias} = [];
173
161
  const ${valueAlias} = ${valuePath};
174
162
  ${code}
175
- if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ' and '); }
163
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
176
164
  `;
177
165
  } else if (schema instanceof Or) {
178
166
  const valueAlias = context.unique('v');
179
167
  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 ')`);
168
+ const code = schema.schemas.map((s)=>codeGen(s, context, valueAlias, path)).reduceRight((result, code)=>`try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"');`);
181
169
  return `// Or
182
170
  const ${errorsAlias} = [];
183
171
  const ${valueAlias} = ${valuePath};
@@ -192,16 +180,16 @@ if (${valueAlias} !== undefined && ${valueAlias} !== null) { ${codeGen(schema.sc
192
180
  } else if (schema instanceof Tuple) {
193
181
  const valueAlias = context.unique('v');
194
182
  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') {
183
+ const code = [
184
+ '// Tuple',
185
+ `const ${valueAlias} = ${valuePath};`,
186
+ `const ${errorsAlias} = [];`,
187
+ `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \`${path}\`); }`,
188
+ ...schema.schemas.map((s, idx)=>`try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`),
189
+ `if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }`
190
+ ];
191
+ return code.join('\n');
192
+ } else if (typeof schema === 'function') {
205
193
  const index = context.register(schema);
206
194
  const valueAlias = context.unique('v');
207
195
  const registryAlias = context.unique('r');
@@ -210,20 +198,21 @@ const ${valueAlias} = ${valuePath};
210
198
  const ${registryAlias} = ctx.registry[${index}];
211
199
  if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'a non-nullable', \`${path}\`); }
212
200
  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'); }
201
+ if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \`${path}\`, 'type'); }
214
202
  `;
215
203
  } else if (Array.isArray(schema)) {
216
204
  const valueAlias = context.unique('v');
217
205
  const code = [
218
206
  `const ${valueAlias} = ${valuePath};`,
219
- `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`
207
+ `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \`${path}\`); }`
220
208
  ];
221
209
  if (schema.length > 0) {
222
210
  const value = context.unique('val');
223
211
  const key = context.unique('key');
224
212
  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, `}`);
213
+ code.push(`const ${errorsAlias} = [];`);
214
+ code.push(...schema.map((s)=>`${valueAlias}.forEach((${value},${key}) => { try { ${codeGen(s, context, value, `${path}[\${${key}}]`)} } catch(e){ ${errorsAlias}.push(e); } });`));
215
+ code.push(`if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }`);
227
216
  }
228
217
  return code.join('\n');
229
218
  } else if (typeof schema === 'object' && schema !== null) {
@@ -237,8 +226,8 @@ if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valu
237
226
  const valueAlias = context.unique('v');
238
227
  const code = [
239
228
  `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}\`); }`
229
+ `if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'object', \`${path}\`); }`,
230
+ `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`
242
231
  ];
243
232
  if ($keys in schema) {
244
233
  const keysAlias = context.unique('key');
@@ -246,8 +235,8 @@ if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valu
246
235
  const value = context.unique('v');
247
236
  code.push(`
248
237
  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}, ', '); }
238
+ const ${errorsAlias} = ${keysAlias}.flatMap((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).filter(Boolean);
239
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
251
240
  `);
252
241
  }
253
242
  if ($values in schema) {
@@ -256,130 +245,150 @@ if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
256
245
  const errorsAlias = context.unique('err');
257
246
  code.push(`{
258
247
  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}, ', '); }
248
+ const ${errorsAlias} = ${valuesAlias}.flatMap((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).filter(Boolean);
249
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
261
250
  }`);
262
251
  }
263
252
  const keys = Object.keys(schema);
264
253
  code.push(...keys.map((key)=>codeGen(schema[key], context, `${valueAlias}['${key}']`, `${path}.${key}`)));
265
254
  return `{${code.join('\n')}}`;
266
255
  }
256
+ } else if (typeof schema === 'symbol') {
257
+ const index = context.register(schema);
258
+ const valueAlias = context.unique('v');
259
+ const registryAlias = context.unique('r');
260
+ return `
261
+ const ${valueAlias} = ${valuePath};
262
+ const ${registryAlias} = ctx.registry[${index}];
263
+ if (typeof ${valueAlias} !== 'symbol') { throw new ctx.Error(typeof ${valueAlias}, 'symbol', '${path}', 'type of'); }
264
+ if (${valueAlias} !== ${registryAlias}) { throw new ctx.Error(${valueAlias}.toString(), ${registryAlias}.toString(), '${path}', 'symbol'); }
265
+ `;
266
+ } else if (schema === null || schema === undefined) {
267
+ const valueAlias = context.unique('v');
268
+ return `
269
+ const ${valueAlias} = ${valuePath};
270
+ if (${valueAlias} !== null && ${valueAlias} !== undefined ) { throw new ctx.Error(${valueAlias}, 'nullable', '${path}'); }
271
+ `;
267
272
  } else {
268
273
  const valueAlias = context.unique('v');
274
+ const typeAlias = context.unique('t');
275
+ const value = context.unique('val');
269
276
  return `
270
277
  const ${valueAlias} = ${valuePath};
271
- if (${valueAlias} !== ${schema}) { throw new ctx.Error(${valueAlias}, ${schema}, \`${path}\`); }
278
+ const ${typeAlias} = '${typeof schema}';
279
+ const ${value} = ${JSON.stringify(schema)};
280
+ if (typeof ${valueAlias} !== ${typeAlias}) { throw new ctx.Error(typeof ${valueAlias}, ${typeAlias}, '${path}', 'type of'); }
281
+ if (${valueAlias} !== ${value}) { throw new ctx.Error(${valueAlias}, ${value}, '${path}'); }
272
282
  `;
273
283
  }
274
284
  };
285
+ const flatAggregateError = (error)=>{
286
+ return error.errors.flatMap((e)=>e instanceof AggregateError ? flatAggregateError(e) : e);
287
+ };
275
288
  const compile = (schema, rootName, options = {})=>{
276
289
  const context = new Context(options);
277
290
  const code = codeGen(schema, context, 'data', rootName);
278
291
  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;
292
+ return (data)=>{
293
+ try {
294
+ validator(context, data);
295
+ } catch (e) {
296
+ const errors = e instanceof AggregateError ? flatAggregateError(e) : [
297
+ e
298
+ ];
299
+ throw new AggregateError(errors, 'Validation failure');
286
300
  }
287
- }
288
- return false;
301
+ };
289
302
  };
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);
303
+ const assert = (target, schema, path)=>{
304
+ if (schema instanceof And) {
305
+ return schema.schemas.flatMap((schema)=>assert(target, schema, path)).filter((error)=>!!error);
306
+ } else if (schema instanceof Or) {
307
+ const errors = schema.schemas.flatMap((schema)=>assert(target, schema, path));
308
+ const filteredErrors = errors.filter((error)=>!!error);
309
+ if (filteredErrors.length === schema.schemas.length) {
310
+ return filteredErrors;
298
311
  }
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)=>{
308
- if (schema === null || typeof schema === 'undefined') {
309
- return new AssertError(schema, 'any value', path, 'schema value');
310
- }
311
- if (schema instanceof Optional) {
312
- return assert(target, schema.schemas[0], path, true);
313
- }
314
- const isValue = target !== null && typeof target !== 'undefined';
315
- if (!isValue && optional) {
316
- return;
317
- }
318
- if (schema instanceof Or) {
319
- if (!schema.schemas.length) {
320
- return new AssertError(target, 'values', path, 'OR schema');
312
+ } else if (schema instanceof Optional) {
313
+ if (target !== undefined && target !== null) {
314
+ return assert(target, schema.schemas[0], path);
321
315
  }
322
- return findNotError(schema.schemas, (schema)=>assert(target, schema, path));
323
- }
324
- if (schema instanceof And) {
325
- if (!schema.schemas.length) {
326
- return new AssertError(target, 'values', path, 'AND schema');
316
+ } else if (schema instanceof Tuple) {
317
+ if (!Array.isArray(target)) {
318
+ return [
319
+ new AssertError(target, 'array', path)
320
+ ];
327
321
  }
328
- return findFirstError(schema.schemas, (schema)=>assert(target, schema, path));
329
- }
330
- if (typeof schema === 'function') {
331
- if (!isValue) {
332
- return new AssertError(target, schema.name, path);
322
+ return schema.schemas.flatMap((s, idx)=>assert(target[idx], s, `${path}[${idx}]`)).filter((error)=>!!error);
323
+ } else if (typeof schema === 'function') {
324
+ if (target === null || target === undefined) {
325
+ return [
326
+ new AssertError(target, 'a non-nullable', path)
327
+ ];
333
328
  }
334
329
  if (typeof target === 'object' && !(target instanceof schema)) {
335
- return new AssertError(target, schema.name, path);
330
+ return [
331
+ new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')
332
+ ];
336
333
  }
337
- if (typeof target !== 'object' && target.constructor !== schema) {
338
- return new AssertError(target, schema.name, path);
334
+ if (typeof target !== 'object' && target?.constructor !== schema) {
335
+ return [
336
+ new AssertError(target?.constructor?.name, schema.name, path, 'type')
337
+ ];
339
338
  }
340
339
  } else if (Array.isArray(schema)) {
341
340
  if (!Array.isArray(target)) {
342
- return new AssertError(target, schema.constructor.name, path);
341
+ return [
342
+ new AssertError(target, 'array', path)
343
+ ];
343
344
  }
344
- return findFirstError(target, (value, idx)=>{
345
- return findNotError(schema, (itemSchemaType)=>assert(value, itemSchemaType, `${path}.${idx}`));
346
- });
347
- } else if (typeof schema === 'object') {
345
+ return schema.flatMap((s)=>target.flatMap((value, idx)=>assert(value, s, `${path}[${idx}]`))).filter((error)=>!!error);
346
+ } else if (typeof schema === 'object' && schema !== null) {
348
347
  if (schema instanceof RegExp) {
349
348
  if (!schema.test('' + target)) {
350
- return new AssertError(target, `matching /${schema.source}/`, path);
349
+ return [
350
+ new AssertError(target, `matching ${schema.toString()}`, path)
351
+ ];
351
352
  }
353
+ return [];
352
354
  } else {
353
- if (typeof target !== 'object') {
354
- return new AssertError(target, schema.constructor.name, path);
355
+ if (target === null || target === undefined) {
356
+ return [
357
+ new AssertError(target, 'object', path)
358
+ ];
355
359
  }
356
- if (target === null) {
357
- return new AssertError(target, 'an object', path);
360
+ if (typeof target !== 'object') {
361
+ return [
362
+ new AssertError(target, schema.constructor.name, path)
363
+ ];
358
364
  }
359
365
  if ($keys in schema) {
360
366
  const targetKeys = Object.keys(target);
361
- const assertError = findFirstError(targetKeys, (targetKey)=>assert(targetKey, schema[$keys], `${path}.${targetKey}`));
362
- if (assertError) {
363
- return assertError;
364
- }
367
+ return targetKeys.flatMap((key)=>assert(key, schema[$keys], path)).filter((error)=>!!error);
365
368
  }
366
369
  if ($values in schema) {
367
370
  const targetKeys = Object.keys(target);
368
- const assertError = findFirstError(targetKeys, (targetKey)=>assert(target[targetKey], schema[$values], `${path}.${targetKey}`));
369
- if (assertError) {
370
- return assertError;
371
- }
371
+ return targetKeys.flatMap((key)=>assert(target[key], schema[$values], path)).filter((error)=>!!error);
372
372
  }
373
- return findFirstError(Object.keys(schema), (key)=>assert(target[key], schema[key], `${path}.${key}`));
373
+ return Object.keys(schema).flatMap((key)=>assert(target[key], schema[key], path)).filter((error)=>!!error);
374
+ }
375
+ } else if (schema === null || schema === undefined) {
376
+ if (target !== null && target !== undefined) {
377
+ return [
378
+ new AssertError(target, 'nullable', path)
379
+ ];
374
380
  }
375
381
  } else if (target !== schema) {
376
- return new AssertError(target, schema, path);
382
+ return [
383
+ new AssertError(target, schema, path)
384
+ ];
377
385
  }
386
+ return [];
378
387
  };
379
388
  const ascertain = (schema, data, rootName = '[root]')=>{
380
- const result = assert(data, schema, rootName);
381
- if (result instanceof AssertError) {
382
- throw new TypeError(result.toString());
389
+ const result = assert(data, schema, rootName).filter((error)=>!!error);
390
+ if (result.length > 0) {
391
+ throw new AggregateError(result, 'Validation failure');
383
392
  }
384
393
  };
385
394
 
@@ -1 +1 @@
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":";;;;;;;;;;;IAsDaA,KAAK;eAALA;;IACAC,OAAO;eAAPA;;IAvDAC,WAAW;eAAXA;;IA0GAC,OAAO;eAAPA;;IAhEAC,GAAG;eAAHA;;IAyBAC,EAAE;eAAFA;;IAsSAC,SAAS;eAATA;;IA5GAC,OAAO;eAAPA;;IArMAC,UAAU;eAAVA;;IAPAC,QAAQ;eAARA;;IAVAC,EAAE;eAAFA;;IAaAC,KAAK;eAALA;;;AApDN,MAAMT,oBAAoBU;;;;;IAC/B,OAAOC,KAAKC,MAAqB,EAAEC,YAAY,MAAM,EAAE;QACrD,OAAO,IAAIb,YAAYY,MAAM,CAAC,EAAE,CAACE,KAAK,EAAEF,OAAOG,GAAG,CAAC,CAACC,IAAM,CAAC,EAAEA,EAAEC,QAAQ,CAAC,CAAC,EAAEN,IAAI,CAACE,YAAYD,MAAM,CAAC,EAAE,CAACM,IAAI,EAAEN,MAAM,CAAC,EAAE,CAACO,OAAO;IAC/H;IACAC,YACE,AAAgBN,KAAc,EAC9B,AAAgBG,QAAiB,EACjC,AAAgBC,IAAY,EAC5B,AAAgBC,UAAU,OAAO,CACjC;QACA,KAAK,CAAC,CAAC,QAAQ,EAAEA,QAAQ,CAAC,EAAEE,KAAKC,SAAS,CAACR,OAAO,UAAU,EAAEI,KAAK,WAAW,EAAED,SAAS,CAAC,CAAC;aAL3EH,QAAAA;aACAG,WAAAA;aACAC,OAAAA;aACAC,UAAAA;IAGlB;AACF;AAkBA,MAAeI;;IACbH,YAAY,AAAgBI,OAAoB,CAAE;aAAtBA,UAAAA;QAC1B,IAAIA,QAAQC,MAAM,KAAK,GAAG;YACxB,MAAM,IAAIf,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAACU,WAAW,CAACM,IAAI,CAAC,+BAA+B,CAAC;QAChG;IACF;AACF;AAEA,MAAMC,WAAuCJ;AAAc;AACpD,MAAMf,KAAK,CAA6B,GAAGgB,UAAyB,IAAIG,GAAGH;AAElF,MAAMI,YAAwCL;AAAc;AACrD,MAAMrB,MAAM,CAA6B,GAAGsB,UAAyB,IAAII,IAAIJ;AAEpF,MAAMK,iBAA6CN;IACjDH,YAAYU,MAAiB,CAAE;QAC7B,KAAK,CAAC;YAACA;SAAO;IAChB;AACF;AACO,MAAMvB,WAAW,CAA6BuB,SAAsB,IAAID,SAASC;AAExF,MAAMC,cAA0CR;AAAc;AACvD,MAAMd,QAAQ,CAA6B,GAAGe,UAAyB,IAAIO,MAAMP;AAEjF,MAAM1B,QAAQkC,OAAOC,GAAG,CAAC;AACzB,MAAMlC,UAAUiC,OAAOC,GAAG,CAAC;AAC3B,MAAM3B,aAAa,OAAO4B,WAAW,cAAc,CAACpB,QAAkBqB,KAAKrB,SAAS,CAACA,QAAkBoB,OAAOE,IAAI,CAACtB,OAAO,UAAUuB,QAAQ,CAAC;AAEpJ,MAAMC,cAAc;IAClBC,IAAI;IACJC,GAAG;IACHC,GAAG;IACHC,GAAG;IACHC,GAAG;IACHC,GAAG;AACL;AAEO,MAAMzC,KAAK;IAChB0C,QAAQ,CAAC/B;QACP,OAAO,OAAOA,UAAU,WAAWA,QAAQgC;IAC7C;IACAC,QAAQ,CAACjC;QACP,MAAMkC,SAASC,WAAWnC;QAC1B,OAAOoC,OAAOC,QAAQ,CAACH,UAAUA,SAASF;IAC5C;IACAM,MAAM,CAACtC;QACL,MAAMkC,SAASK,KAAKC,KAAK,CAACxC;QAC1B,OAAOoC,OAAOC,QAAQ,CAACH,UAAU,IAAIK,KAAKL,UAAUF;IACtD;IACAS,MAAM,CAACzC;QACL,MAAM0C,UAAU1C,OAAO2C,MAAM;QAC7B,IAAID,SAAS;YACX,MAAM,GAAGE,QAAQC,OAAO,IAAI,CAAC,GAAGH;YAChC,OAAOI,SAASF,QAAQ,MAAMpB,WAAW,CAACqB,KAAiC;QAC7E;QACA,OAAOb;IACT;IACAe,SAAS,CAAC/C,QACR,uCAAuCgD,IAAI,CAAChD,SAAmB,sBAAsBgD,IAAI,CAAChD,SAAmBgC;IAC/GiB,OAAO,CAACjD,OAA2BkD,YAAsBlD,OAAOmD,MAAMD,cAAclB;IACpFoB,MAAM,CAACpD;QACL,IAAI;YACF,OAAOO,KAAKiC,KAAK,CAACxC;QACpB,EAAE,OAAOE,GAAG;YACV,OAAO8B;QACT;IACF;IACAqB,QAAQ,CAACrD;QACP,IAAI;YACF,OAAOR,WAAWQ;QACpB,EAAE,OAAOE,GAAG;YACV,OAAO8B;QACT;IACF;AACF;AAEO,MAAM7C;;IACKmE,MAA8B;IAC9BxD,OAA2B;IAC3ByD,SAAyB;IACjCC,SAAa;IACrBlD,YAAY,AAAgBmD,UAA2B,CAAC,CAAC,CAAE;aAA/BA,UAAAA;aAHZ3D,SAAwB,EAAE;aAC1ByD,WAAsB,EAAE;aAChCC,WAAW;QAEjB,IAAI,CAACF,KAAK,GAAGG,QAAQC,KAAK,IAAIxE;IAChC;IAEAwE,MAAM5D,MAAqB,EAAE;QAC3B,IAAI,CAACA,MAAM,CAAC6D,IAAI,IAAI7D;QACpB,OAAO;IACT;IAEA8D,SAAS5D,KAAc,EAAU;QAC/B,IAAI,CAAC,IAAI,CAACuD,QAAQ,CAACM,QAAQ,CAAC7D,QAAQ;YAClC,IAAI,CAACuD,QAAQ,CAACI,IAAI,CAAC3D;QACrB;QACA,OAAO,IAAI,CAACuD,QAAQ,CAACO,OAAO,CAAC9D;IAC/B;IAEA+D,OAAOC,MAAc,EAAE;QACrB,OAAO,CAAC,EAAEA,OAAO,EAAE,EAAE,IAAI,CAACR,QAAQ,GAAG,CAAC;IACxC;AACF;AAMA,MAAMS,UAAU,CAA6BjD,QAAmBkD,SAAkBC,WAAmB/D;IACnG,IAAIY,kBAAkBF,KAAK;QACzB,MAAMsD,aAAaF,QAAQH,MAAM,CAAC;QAClC,MAAMM,cAAcH,QAAQH,MAAM,CAAC;QACnC,MAAMO,OAAOtD,OAAON,OAAO,CAACT,GAAG,CAAC,CAACyB,IAAM,CAAC,MAAM,EAAEuC,QAAQvC,GAAGwC,SAASE,YAAYhE,MAAM,eAAe,EAAEiE,YAAY,WAAW,CAAC,EAAExE,IAAI,CAAC;QACtI,OAAO,CAAC;QACJ,EAAEwE,YAAY;QACd,EAAED,WAAW,GAAG,EAAED,UAAU;EAClC,EAAEG,KAAK;MACH,EAAED,YAAY,sCAAsC,EAAEA,YAAY;AACxE,CAAC;IACC,OAAO,IAAIrD,kBAAkBH,IAAI;QAC/B,MAAMuD,aAAaF,QAAQH,MAAM,CAAC;QAClC,MAAMM,cAAcH,QAAQH,MAAM,CAAC;QACnC,MAAMO,OAAOtD,OAAON,OAAO,CACxBT,GAAG,CAAC,CAACyB,IAAMuC,QAAQvC,GAAGwC,SAASE,YAAYhE,OAC3CmE,WAAW,CAAC,CAACrC,QAAQoC,OAAS,CAAC,KAAK,EAAEA,KAAK,aAAa,EAAED,YAAY,SAAS,EAAEnC,OAAO,CAAC,CAAC,EAAE,CAAC,qBAAqB,EAAEmC,YAAY,SAAS,CAAC;QAC7I,OAAO,CAAC;MACN,EAAEA,YAAY;MACd,EAAED,WAAW,GAAG,EAAED,UAAU;AAClC,EAAEG,KAAK;IACH,CAAC;IACH,OAAO,IAAItD,kBAAkBD,UAAU;QACrC,MAAMqD,aAAaF,QAAQH,MAAM,CAAC;QAClC,OAAO,CAAC;MACN,EAAEK,WAAW,GAAG,EAAED,UAAU;IAC9B,EAAEC,WAAW,kBAAkB,EAAEA,WAAW,aAAa,EAAEH,QAAQjD,OAAON,OAAO,CAAC,EAAE,EAAEwD,SAASE,YAAYhE,MAAM;AACrH,CAAC;IACC,OAAO,IAAIY,kBAAkBC,OAAO;QAClC,MAAMmD,aAAaF,QAAQH,MAAM,CAAC;QAClC,MAAMM,cAAcH,QAAQH,MAAM,CAAC;QACnC,MAAMO,OAAOtD,OAAON,OAAO,CACxBT,GAAG,CAAC,CAACyB,GAAG8C,MAAQ,CAAC,MAAM,EAAEP,QAAQvC,GAAGwC,SAAS,CAAC,EAAEE,WAAW,CAAC,EAAEI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAEpE,KAAK,CAAC,EAAEoE,IAAI,CAAC,CAAC,EAAE,eAAe,EAAEH,YAAY,WAAW,CAAC,EAClIxE,IAAI,CAAC;QACR,OAAO,CAAC;QACJ,EAAEuE,WAAW,GAAG,EAAED,UAAU;QAC5B,EAAEE,YAAY;qBACD,EAAED,WAAW,yBAAyB,EAAEA,WAAW,aAAa,EAAEhE,KAAK;EAC1F,EAAEkE,KAAK;MACH,EAAED,YAAY,sCAAsC,EAAEA,YAAY;AACxE,CAAC;IACC;IACA,IAAI,OAAOrD,WAAW,YAAY;QAChC,MAAMyD,QAAQP,QAAQN,QAAQ,CAAC5C;QAC/B,MAAMoD,aAAaF,QAAQH,MAAM,CAAC;QAClC,MAAMW,gBAAgBR,QAAQH,MAAM,CAAC;QACrC,OAAO,CAAC;MACN,EAAEK,WAAW,GAAG,EAAED,UAAU;MAC5B,EAAEO,cAAc,gBAAgB,EAAED,MAAM;IAC1C,EAAEL,WAAW,aAAa,EAAEA,WAAW,sCAAsC,EAAEA,WAAW,sBAAsB,EAAEhE,KAAK;WAChH,EAAEgE,WAAW,mBAAmB,EAAEA,WAAW,YAAY,EAAEM,cAAc,yBAAyB,EAAEN,WAAW,sCAAsC,EAAEM,cAAc,YAAY,EAAEtE,KAAK;gBACnL,EAAEgE,WAAW,iBAAiB,EAAEA,WAAW,kBAAkB,EAAEM,cAAc,wBAAwB,EAAEN,WAAW,qBAAqB,EAAEM,cAAc,SAAS,EAAEtE,KAAK;AACvL,CAAC;IACC,OAAO,IAAIuE,MAAMC,OAAO,CAAC5D,SAAS;QAChC,MAAMoD,aAAaF,QAAQH,MAAM,CAAC;QAClC,MAAMO,OAAiB;YACrB,CAAC,MAAM,EAAEF,WAAW,GAAG,EAAED,UAAU,CAAC,CAAC;YACrC,CAAC,mBAAmB,EAAEC,WAAW,yBAAyB,EAAEA,WAAW,GAAG,EAAEpD,OAAOV,WAAW,CAACM,IAAI,CAAC,KAAK,EAAER,KAAK,MAAM,CAAC;SACxH;QACD,IAAIY,OAAOL,MAAM,GAAG,GAAG;YACrB,MAAMX,QAAQkE,QAAQH,MAAM,CAAC;YAC7B,MAAMc,MAAMX,QAAQH,MAAM,CAAC;YAC3B,MAAMM,cAAcH,QAAQH,MAAM,CAAC;YAEnC,MAAMe,SAAS9D,OACZf,GAAG,CAAC,CAACyB,IAAMuC,QAAQvC,GAAGwC,SAASlE,OAAO,CAAC,EAAEI,KAAK,IAAI,EAAEyE,IAAI,EAAE,CAAC,GAC3DN,WAAW,CAAC,CAACrC,QAAQoC,OAAS,CAAC,KAAK,EAAEA,KAAK,aAAa,EAAED,YAAY,SAAS,EAAEnC,OAAO,CAAC,CAAC,EAAE,CAAC,qBAAqB,EAAEmC,YAAY,SAAS,CAAC;YAC7IC,KAAKX,IAAI,CAAC,CAAC,UAAU,EAAEkB,IAAI,IAAI,EAAET,WAAW,GAAG,CAAC,EAAE,CAAC,MAAM,EAAEC,YAAY,MAAM,CAAC,EAAE,CAAC,MAAM,EAAErE,MAAM,GAAG,EAAEoE,WAAW,CAAC,EAAES,IAAI,EAAE,CAAC,EAAEC,QAAQ,CAAC,CAAC,CAAC;QACxI;QACA,OAAOR,KAAKzE,IAAI,CAAC;IACnB,OAAO,IAAI,OAAOmB,WAAW,YAAYA,WAAW,MAAM;QACxD,IAAIA,kBAAkB+D,QAAQ;YAC5B,MAAMX,aAAaF,QAAQH,MAAM,CAAC;YAClC,OAAO,CAAC;MACR,EAAEK,WAAW,GAAG,EAAED,UAAU;KAC7B,EAAEnD,OAAOO,QAAQ,GAAG,WAAW,EAAE6C,WAAW,yBAAyB,EAAEA,WAAW,YAAY,EAAEpD,OAAOO,QAAQ,GAAG,KAAK,EAAEnB,KAAK;AACnI,CAAC;QACG,OAAO;YACL,MAAMgE,aAAaF,QAAQH,MAAM,CAAC;YAClC,MAAMO,OAAiB;gBACrB,CAAC,MAAM,EAAEF,WAAW,GAAG,EAAED,UAAU,CAAC,CAAC;gBACrC,CAAC,WAAW,EAAEC,WAAW,qCAAqC,EAAEA,WAAW,GAAG,EAAEpD,OAAOV,WAAW,CAACM,IAAI,CAAC,KAAK,EAAER,KAAK,MAAM,CAAC;gBAC3H,CAAC,IAAI,EAAEgE,WAAW,iCAAiC,EAAEA,WAAW,cAAc,EAAEhE,KAAK,MAAM,CAAC;aAC7F;YACD,IAAIpB,SAASgC,QAAQ;gBACnB,MAAMgE,YAAYd,QAAQH,MAAM,CAAC;gBACjC,MAAMM,cAAcH,QAAQH,MAAM,CAAC;gBACnC,MAAM/D,QAAQkE,QAAQH,MAAM,CAAC;gBAC7BO,KAAKX,IAAI,CAAC,CAAC;MACb,EAAEqB,UAAU,eAAe,EAAEZ,WAAW;MACxC,EAAEC,YAAY,GAAG,EAAEW,UAAU,MAAM,EAAEhF,MAAM,OAAO,EAAEiE,QAAQjD,MAAM,CAAChC,MAAM,EAAEkF,SAASlE,OAAOI,MAAM;IACnG,EAAEiE,YAAY,sCAAsC,EAAEA,YAAY;AACtE,CAAC;YACK;YACA,IAAIpF,WAAW+B,QAAQ;gBACrB,MAAMiE,SAASf,QAAQH,MAAM,CAAC;gBAC9B,MAAMmB,cAAchB,QAAQH,MAAM,CAAC;gBACnC,MAAMM,cAAcH,QAAQH,MAAM,CAAC;gBACnCO,KAAKX,IAAI,CAAC,CAAC;MACb,EAAEuB,YAAY,iBAAiB,EAAEf,UAAU;MAC3C,EAAEE,YAAY,GAAG,EAAEa,YAAY,MAAM,EAAED,OAAO,OAAO,EAAEhB,QAAQjD,MAAM,CAAC/B,QAAQ,EAAEiF,SAASe,QAAQ7E,MAAM;IACzG,EAAEiE,YAAY,sCAAsC,EAAEA,YAAY;CACrE,CAAC;YACI;YACA,MAAMc,OAAOC,OAAOD,IAAI,CAACnE;YACzBsD,KAAKX,IAAI,IAAIwB,KAAKlF,GAAG,CAAC,CAAC4E,MAAQZ,QAAQjD,MAAM,CAAC6D,IAAI,EAAEX,SAAS,CAAC,EAAEE,WAAW,EAAE,EAAES,IAAI,EAAE,CAAC,EAAE,CAAC,EAAEzE,KAAK,CAAC,EAAEyE,IAAI,CAAC;YACxG,OAAO,CAAC,CAAC,EAAEP,KAAKzE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B;IACF,OAAO;QACL,MAAMuE,aAAaF,QAAQH,MAAM,CAAC;QAClC,OAAO,CAAC;MACN,EAAEK,WAAW,GAAG,EAAED,UAAU;IAC9B,EAAEC,WAAW,KAAK,EAAEpD,OAAO,wBAAwB,EAAEoD,WAAW,EAAE,EAAEpD,OAAO,IAAI,EAAEZ,KAAK;AAC1F,CAAC;IACC;AACF;AAEO,MAAMb,UAAU,CAAIyB,QAAWqE,UAAkB5B,UAA2B,CAAC,CAAC;IACnF,MAAMS,UAAU,IAAI/E,QAAQsE;IAC5B,MAAMa,OAAOL,QAAQjD,QAAQkD,SAAS,QAAQmB;IAC9C,MAAMC,YAAY,IAAIC,SAAS,OAAO,QAAQjB;IAC9C,OAAO,CAACkB,OAAwBF,UAAUpB,SAASsB;AACrD;AAEA,MAAMC,iBAAiB,CAAIxC,OAAYhD;IACrC,IAAK,IAAIyF,IAAI,GAAGA,IAAIzC,MAAMtC,MAAM,EAAE+E,IAAK;QACrC,MAAMhC,QAAQzD,IAAIgD,KAAK,CAACyC,EAAE,EAAEA;QAC5B,IAAIhC,OAAO;YACT,OAAOA;QACT;IACF;IACA,OAAO;AACT;AAEA,MAAMiC,eAAe,CAAI1C,OAAYhD;IACnC,MAAMH,SAAwB,EAAE;IAChC,IAAK,IAAI4F,IAAI,GAAGA,IAAIzC,MAAMtC,MAAM,EAAE+E,IAAK;QACrC,MAAMhC,QAAQzD,IAAIgD,KAAK,CAACyC,EAAE,EAAEA;QAC5B,IAAI,CAAChC,OAAO;YACV,OAAO;QACT,OAAO;YACL5D,OAAO6D,IAAI,CAACD;QACd;IACF;IACA,OAAO5D,OAAO8F,MAAM,CAAC,CAAC1D,QAAQwB;QAC5B,OAAO,IAAIxE,YAAYgD,OAAOlC,KAAK,EAAE;YAACkC,OAAO/B,QAAQ;YAAEuD,MAAMvD,QAAQ;SAAC,CAACN,IAAI,CAAC,SAASqC,OAAO9B,IAAI,EAAE8B,OAAO7B,OAAO;IAClH;AACF;AAEA,MAAMwF,SAAS,CAACC,QAAiB9E,QAAiBZ,MAAcX,WAAW,KAAK;IAC9E,IAAIuB,WAAW,QAAQ,OAAOA,WAAW,aAAa;QACpD,OAAO,IAAI9B,YAAY8B,QAAQ,aAAaZ,MAAM;IACpD;IACA,IAAIY,kBAAkBD,UAAU;QAC9B,OAAO8E,OAAOC,QAAQ9E,OAAON,OAAO,CAAC,EAAE,EAAEN,MAAM;IACjD;IACA,MAAM2F,UAAUD,WAAW,QAAQ,OAAOA,WAAW;IACrD,IAAI,CAACC,WAAWtG,UAAU;QACxB;IACF;IACA,IAAIuB,kBAAkBH,IAAI;QACxB,IAAI,CAACG,OAAON,OAAO,CAACC,MAAM,EAAE;YAC1B,OAAO,IAAIzB,YAAY4G,QAAQ,UAAU1F,MAAM;QACjD;QACA,OAAOuF,aAAa3E,OAAON,OAAO,EAAE,CAACM,SAAW6E,OAAOC,QAAQ9E,QAAQZ;IACzE;IACA,IAAIY,kBAAkBF,KAAK;QACzB,IAAI,CAACE,OAAON,OAAO,CAACC,MAAM,EAAE;YAC1B,OAAO,IAAIzB,YAAY4G,QAAQ,UAAU1F,MAAM;QACjD;QACA,OAAOqF,eAAezE,OAAON,OAAO,EAAE,CAACM,SAAW6E,OAAOC,QAAQ9E,QAAQZ;IAC3E;IAEA,IAAI,OAAOY,WAAW,YAAY;QAChC,IAAI,CAAC+E,SAAS;YACZ,OAAO,IAAI7G,YAAY4G,QAAQ9E,OAAOJ,IAAI,EAAER;QAC9C;QACA,IAAI,OAAO0F,WAAW,YAAY,CAAEA,CAAAA,kBAAkB9E,MAAK,GAAI;YAC7D,OAAO,IAAI9B,YAAY4G,QAAQ9E,OAAOJ,IAAI,EAAER;QAC9C;QACA,IAAI,OAAO0F,WAAW,YAAYA,OAAOxF,WAAW,KAAKU,QAAQ;YAC/D,OAAO,IAAI9B,YAAY4G,QAAQ9E,OAAOJ,IAAI,EAAER;QAC9C;IACF,OAAO,IAAIuE,MAAMC,OAAO,CAAC5D,SAAS;QAChC,IAAI,CAAC2D,MAAMC,OAAO,CAACkB,SAAS;YAC1B,OAAO,IAAI5G,YAAY4G,QAAQ9E,OAAOV,WAAW,CAACM,IAAI,EAAER;QAC1D;QACA,OAAOqF,eAAeK,QAAQ,CAAC9F,OAAOwE;YACpC,OAAOmB,aAAa3E,QAAQ,CAACgF,iBAAmBH,OAAO7F,OAAOgG,gBAAgB,CAAC,EAAE5F,KAAK,CAAC,EAAEoE,IAAI,CAAC;QAChG;IACF,OAAO,IAAI,OAAOxD,WAAW,UAAU;QACrC,IAAIA,kBAAkB+D,QAAQ;YAC5B,IAAI,CAAC/D,OAAOgC,IAAI,CAAC,KAAK8C,SAAS;gBAC7B,OAAO,IAAI5G,YAAY4G,QAAQ,CAAC,UAAU,EAAE9E,OAAOiF,MAAM,CAAC,CAAC,CAAC,EAAE7F;YAChE;QACF,OAAO;YACL,IAAI,OAAO0F,WAAW,UAAU;gBAC9B,OAAO,IAAI5G,YAAY4G,QAAQ9E,OAAOV,WAAW,CAACM,IAAI,EAAER;YAC1D;YACA,IAAI0F,WAAW,MAAM;gBACnB,OAAO,IAAI5G,YAAY4G,QAAQ,aAAa1F;YAC9C;YACA,IAAIpB,SAASgC,QAAQ;gBACnB,MAAMkF,aAAad,OAAOD,IAAI,CAACW;gBAC/B,MAAMK,cAAcV,eAAeS,YAAY,CAACE,YAAcP,OAAOO,WAAWpF,MAAM,CAAChC,MAAM,EAAE,CAAC,EAAEoB,KAAK,CAAC,EAAEgG,UAAU,CAAC;gBACrH,IAAID,aAAa;oBACf,OAAOA;gBACT;YACF;YACA,IAAIlH,WAAW+B,QAAQ;gBACrB,MAAMkF,aAAad,OAAOD,IAAI,CAACW;gBAC/B,MAAMK,cAAcV,eAAeS,YAAY,CAACE,YAC9CP,OAAOC,MAAM,CAACM,UAAiC,EAAEpF,MAAM,CAAC/B,QAAQ,EAAE,CAAC,EAAEmB,KAAK,CAAC,EAAEgG,UAAU,CAAC;gBAE1F,IAAID,aAAa;oBACf,OAAOA;gBACT;YACF;YACA,OAAOV,eAAeL,OAAOD,IAAI,CAACnE,SAAS,CAAC6D,MAAQgB,OAAOC,MAAM,CAACjB,IAA2B,EAAE7D,MAAM,CAAC6D,IAA2B,EAAE,CAAC,EAAEzE,KAAK,CAAC,EAAEyE,IAAI,CAAC;QACrJ;IACF,OAAO,IAAIiB,WAAW9E,QAAQ;QAC5B,OAAO,IAAI9B,YAAY4G,QAAQ9E,QAAQZ;IACzC;AACF;AAEO,MAAMd,YAAY,CAA6B0B,QAAmBwE,MAASH,WAAW,QAAQ;IACnG,MAAMnD,SAAS2D,OAAOL,MAAMxE,QAAQqE;IACpC,IAAInD,kBAAkBhD,aAAa;QACjC,MAAM,IAAIU,UAAUsC,OAAOX,QAAQ;IACrC;AACF"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class AssertError extends TypeError {\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 Keys = string | number | symbol;\ntype DataValue = any;\nexport type 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\nclass Context {\n public readonly Error: typeof AssertError;\n public readonly registry: unknown[] = [];\n private varIndex = 0;\n\n constructor(public readonly options: CompilerOptions = {}) {\n this.Error = options.error ?? AssertError;\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?: typeof AssertError;\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 new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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(\n (result, code) => `try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`,\n `throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"');`,\n );\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: string[] = [\n '// Tuple',\n `const ${valueAlias} = ${valuePath};`,\n `const ${errorsAlias} = [];`,\n `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \\`${path}\\`); }`,\n ...schema.schemas.map((s, idx) => `try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`),\n `if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }`,\n ];\n\n return code.join('\\n');\n } else 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'); }\nif (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}, 'array', \\`${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 code.push(`const ${errorsAlias} = [];`);\n code.push(\n ...schema.map(\n (s) =>\n `${valueAlias}.forEach((${value},${key}) => { try { ${codeGen(s, context, value, `${path}[\\${${key}}]`)} } catch(e){ ${errorsAlias}.push(e); } });`,\n ),\n );\n\n code.push(`if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }`);\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 (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'object', \\`${path}\\`); }`,\n `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \\`${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}.flatMap((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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}.flatMap((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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 if (typeof schema === 'symbol') {\n const index = context.register(schema);\n const valueAlias = context.unique('v');\n const registryAlias = context.unique('r');\n\n return `\nconst ${valueAlias} = ${valuePath};\nconst ${registryAlias} = ctx.registry[${index}];\nif (typeof ${valueAlias} !== 'symbol') { throw new ctx.Error(typeof ${valueAlias}, 'symbol', '${path}', 'type of'); }\nif (${valueAlias} !== ${registryAlias}) { throw new ctx.Error(${valueAlias}.toString(), ${registryAlias}.toString(), '${path}', 'symbol'); }\n `;\n } else if (schema === null || schema === undefined) {\n const valueAlias = context.unique('v');\n return `\nconst ${valueAlias} = ${valuePath};\nif (${valueAlias} !== null && ${valueAlias} !== undefined ) { throw new ctx.Error(${valueAlias}, 'nullable', '${path}'); }\n `;\n } else {\n const valueAlias = context.unique('v');\n const typeAlias = context.unique('t');\n const value = context.unique('val');\n return `\nconst ${valueAlias} = ${valuePath};\nconst ${typeAlias} = '${typeof schema}';\nconst ${value} = ${JSON.stringify(schema)};\nif (typeof ${valueAlias} !== ${typeAlias}) { throw new ctx.Error(typeof ${valueAlias}, ${typeAlias}, '${path}', 'type of'); }\nif (${valueAlias} !== ${value}) { throw new ctx.Error(${valueAlias}, ${value}, '${path}'); }\n`;\n }\n};\n\nconst flatAggregateError = (error: AggregateError): AssertError[] => {\n return error.errors.flatMap((e) => (e instanceof AggregateError ? flatAggregateError(e) : e));\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>) => {\n try {\n validator(context, data);\n } catch (e) {\n const errors = e instanceof AggregateError ? flatAggregateError(e) : [e];\n throw new AggregateError(errors, 'Validation failure');\n }\n };\n};\n\nconst assert = (target: unknown, schema: unknown, path: string): AssertError[] => {\n if (schema instanceof And) {\n return schema.schemas.flatMap((schema) => assert(target, schema, path)).filter((error) => !!error);\n } else if (schema instanceof Or) {\n const errors = schema.schemas.flatMap((schema) => assert(target, schema, path));\n const filteredErrors = errors.filter((error) => !!error);\n if (filteredErrors.length === schema.schemas.length) {\n return filteredErrors;\n }\n } else if (schema instanceof Optional) {\n if (target !== undefined && target !== null) {\n return assert(target, schema.schemas[0], path);\n }\n } else if (schema instanceof Tuple) {\n if (!Array.isArray(target)) {\n return [new AssertError(target, 'array', path)];\n }\n return schema.schemas.flatMap((s, idx) => assert(target[idx], s, `${path}[${idx}]`)).filter((error) => !!error);\n } else if (typeof schema === 'function') {\n if (target === null || target === undefined) {\n return [new AssertError(target, 'a non-nullable', path)];\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return [new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')];\n }\n if (typeof target !== 'object' && target?.constructor !== schema) {\n return [new AssertError(target?.constructor?.name, schema.name, path, 'type')];\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return [new AssertError(target, 'array', path)];\n }\n return schema.flatMap((s) => target.flatMap((value, idx) => assert(value, s, `${path}[${idx}]`))).filter((error) => !!error);\n } else if (typeof schema === 'object' && schema !== null) {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return [new AssertError(target, `matching ${schema.toString()}`, path)];\n }\n return [];\n } else {\n if (target === null || target === undefined) {\n return [new AssertError(target, 'object', path)];\n }\n if (typeof target !== 'object') {\n return [new AssertError(target, schema.constructor.name, path)];\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n return targetKeys.flatMap((key) => assert(key, schema[$keys], path)).filter((error) => !!error);\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n return targetKeys.flatMap((key) => assert(target[key as keyof typeof target], schema[$values], path)).filter((error) => !!error);\n }\n return Object.keys(schema)\n .flatMap((key) => assert(target[key as keyof typeof target], schema[key as keyof typeof target], path))\n .filter((error) => !!error);\n }\n } else if (schema === null || schema === undefined) {\n if (target !== null && target !== undefined) {\n return [new AssertError(target, 'nullable', path)];\n }\n } else if (target !== schema) {\n return [new AssertError(target, schema, path)];\n }\n return [];\n};\n\nexport const ascertain = <T extends Data = DataValue>(schema: Schema<T>, data: T, rootName = '[root]') => {\n const result = assert(data, schema, rootName).filter((error) => !!error);\n if (result.length > 0) {\n throw new AggregateError(result, 'Validation failure');\n }\n};\n"],"names":["$keys","$values","AssertError","and","as","ascertain","compile","fromBase64","optional","or","tuple","TypeError","constructor","value","expected","path","subject","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","e","base64","Context","Error","registry","varIndex","options","error","register","includes","push","indexOf","unique","prefix","codeGen","context","valuePath","valueAlias","errorsAlias","code","map","join","reduceRight","idx","index","registryAlias","Array","isArray","key","RegExp","keysAlias","vAlias","valuesAlias","keys","Object","typeAlias","flatAggregateError","errors","flatMap","AggregateError","rootName","validator","Function","data","assert","target","filter","filteredErrors","targetKeys"],"mappings":"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"}
package/build/index.d.ts CHANGED
@@ -3,13 +3,11 @@ export declare class AssertError extends TypeError {
3
3
  readonly expected: unknown;
4
4
  readonly path: string;
5
5
  readonly subject: string;
6
- static join(errors: AssertError[], separator?: string): AssertError;
7
6
  constructor(value: unknown, expected: unknown, path: string, subject?: string);
8
7
  }
9
- type AssertErrorConstructor = new (value: unknown, expected: unknown, path: string, subject?: string) => Error;
10
8
  type Keys = string | number | symbol;
11
9
  type DataValue = any;
12
- type Data = Record<Keys, unknown>;
10
+ export type Data = Record<Keys, unknown>;
13
11
  type DataArray = DataValue[];
14
12
  export type Schema<T> = T extends Data ? {
15
13
  [S in keyof T]?: Schema<T[S]>;
@@ -47,20 +45,9 @@ export declare const as: {
47
45
  json: (value: string | undefined) => any;
48
46
  base64: (value: string | undefined) => string | undefined;
49
47
  };
50
- export declare class Context {
51
- readonly options: CompilerOptions;
52
- readonly Error: AssertErrorConstructor;
53
- readonly errors: AssertError[];
54
- readonly registry: unknown[];
55
- private varIndex;
56
- constructor(options?: CompilerOptions);
57
- error(errors: AssertError[]): boolean;
58
- register(value: unknown): number;
59
- unique(prefix: string): string;
60
- }
61
48
  export interface CompilerOptions {
62
- error?: AssertErrorConstructor;
49
+ error?: typeof AssertError;
63
50
  }
64
- export declare const compile: <S>(schema: S, rootName: string, options?: CompilerOptions) => (data: SchemaData<S>) => any;
51
+ export declare const compile: <S>(schema: S, rootName: string, options?: CompilerOptions) => (data: SchemaData<S>) => void;
65
52
  export declare const ascertain: <T extends Data = any>(schema: Schema<T>, data: T, rootName?: string) => void;
66
53
  export {};
package/build/index.js CHANGED
@@ -3,9 +3,6 @@ export class AssertError extends TypeError {
3
3
  expected;
4
4
  path;
5
5
  subject;
6
- static join(errors, separator = ' or ') {
7
- return new AssertError(errors[0].value, errors.map((e)=>`${e.expected}`).join(separator), errors[0].path, errors[0].subject);
8
- }
9
6
  constructor(value, expected, path, subject = 'value'){
10
7
  super(`Invalid ${subject} ${JSON.stringify(value)} for path ${path}, expected ${expected}.`);
11
8
  this.value = value;
@@ -72,7 +69,7 @@ export const as = {
72
69
  return undefined;
73
70
  },
74
71
  boolean: (value)=>/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined,
75
- array: (value, delimiter)=>value?.split(delimiter) ?? undefined,
72
+ array: (value, delimiter)=>value?.split?.(delimiter) ?? undefined,
76
73
  json: (value)=>{
77
74
  try {
78
75
  return JSON.parse(value);
@@ -88,23 +85,17 @@ export const as = {
88
85
  }
89
86
  }
90
87
  };
91
- export class Context {
88
+ class Context {
92
89
  options;
93
90
  Error;
94
- errors;
95
91
  registry;
96
92
  varIndex;
97
93
  constructor(options = {}){
98
94
  this.options = options;
99
- this.errors = [];
100
95
  this.registry = [];
101
96
  this.varIndex = 0;
102
97
  this.Error = options.error ?? AssertError;
103
98
  }
104
- error(errors) {
105
- this.errors.push(...errors);
106
- return true;
107
- }
108
99
  register(value) {
109
100
  if (!this.registry.includes(value)) {
110
101
  this.registry.push(value);
@@ -124,12 +115,12 @@ const codeGen = (schema, context, valuePath, path)=>{
124
115
  const ${errorsAlias} = [];
125
116
  const ${valueAlias} = ${valuePath};
126
117
  ${code}
127
- if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ' and '); }
118
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
128
119
  `;
129
120
  } else if (schema instanceof Or) {
130
121
  const valueAlias = context.unique('v');
131
122
  const errorsAlias = context.unique('err');
132
- 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 ')`);
123
+ const code = schema.schemas.map((s)=>codeGen(s, context, valueAlias, path)).reduceRight((result, code)=>`try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`, `throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"');`);
133
124
  return `// Or
134
125
  const ${errorsAlias} = [];
135
126
  const ${valueAlias} = ${valuePath};
@@ -144,16 +135,16 @@ if (${valueAlias} !== undefined && ${valueAlias} !== null) { ${codeGen(schema.sc
144
135
  } else if (schema instanceof Tuple) {
145
136
  const valueAlias = context.unique('v');
146
137
  const errorsAlias = context.unique('err');
147
- const code = schema.schemas.map((s, idx)=>`try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`).join('\n');
148
- return `// Tuple
149
- const ${valueAlias} = ${valuePath};
150
- const ${errorsAlias} = [];
151
- if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'Array', \`${path}\`); }
152
- ${code}
153
- if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
154
- `;
155
- }
156
- if (typeof schema === 'function') {
138
+ const code = [
139
+ '// Tuple',
140
+ `const ${valueAlias} = ${valuePath};`,
141
+ `const ${errorsAlias} = [];`,
142
+ `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \`${path}\`); }`,
143
+ ...schema.schemas.map((s, idx)=>`try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`),
144
+ `if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }`
145
+ ];
146
+ return code.join('\n');
147
+ } else if (typeof schema === 'function') {
157
148
  const index = context.register(schema);
158
149
  const valueAlias = context.unique('v');
159
150
  const registryAlias = context.unique('r');
@@ -162,20 +153,21 @@ const ${valueAlias} = ${valuePath};
162
153
  const ${registryAlias} = ctx.registry[${index}];
163
154
  if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'a non-nullable', \`${path}\`); }
164
155
  if (typeof ${valueAlias} === 'object' && !(${valueAlias} instanceof ${registryAlias})) { throw new ctx.Error(${valueAlias}?.constructor?.name, \`instance of \${${registryAlias}.name}\`, \`${path}\`, 'instance of'); }
165
- else if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \`${path}\`, 'type'); }
156
+ if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \`${path}\`, 'type'); }
166
157
  `;
167
158
  } else if (Array.isArray(schema)) {
168
159
  const valueAlias = context.unique('v');
169
160
  const code = [
170
161
  `const ${valueAlias} = ${valuePath};`,
171
- `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`
162
+ `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \`${path}\`); }`
172
163
  ];
173
164
  if (schema.length > 0) {
174
165
  const value = context.unique('val');
175
166
  const key = context.unique('key');
176
167
  const errorsAlias = context.unique('err');
177
- 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 ')`);
178
- code.push(`for(const ${key} in ${valueAlias}) {`, `const ${errorsAlias} = [];`, `const ${value} = ${valueAlias}[${key}];`, orCode, `}`);
168
+ code.push(`const ${errorsAlias} = [];`);
169
+ code.push(...schema.map((s)=>`${valueAlias}.forEach((${value},${key}) => { try { ${codeGen(s, context, value, `${path}[\${${key}}]`)} } catch(e){ ${errorsAlias}.push(e); } });`));
170
+ code.push(`if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }`);
179
171
  }
180
172
  return code.join('\n');
181
173
  } else if (typeof schema === 'object' && schema !== null) {
@@ -189,8 +181,8 @@ if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valu
189
181
  const valueAlias = context.unique('v');
190
182
  const code = [
191
183
  `const ${valueAlias} = ${valuePath};`,
192
- `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`,
193
- `if (${valueAlias} === null) { throw new ctx.Error(${valueAlias}, 'object', \`${path}\`); }`
184
+ `if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'object', \`${path}\`); }`,
185
+ `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \`${path}\`); }`
194
186
  ];
195
187
  if ($keys in schema) {
196
188
  const keysAlias = context.unique('key');
@@ -198,8 +190,8 @@ if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valu
198
190
  const value = context.unique('v');
199
191
  code.push(`
200
192
  const ${keysAlias} = Object.keys(${valueAlias});
201
- const ${errorsAlias} = ${keysAlias}.map((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).flat().filter(Boolean);
202
- if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
193
+ const ${errorsAlias} = ${keysAlias}.flatMap((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).filter(Boolean);
194
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
203
195
  `);
204
196
  }
205
197
  if ($values in schema) {
@@ -208,130 +200,150 @@ if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
208
200
  const errorsAlias = context.unique('err');
209
201
  code.push(`{
210
202
  const ${valuesAlias} = Object.values(${valuePath});
211
- const ${errorsAlias} = ${valuesAlias}.map((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).flat().filter(Boolean);
212
- if (${errorsAlias}.length !== 0) { throw ctx.Error.join(${errorsAlias}, ', '); }
203
+ const ${errorsAlias} = ${valuesAlias}.flatMap((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).filter(Boolean);
204
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
213
205
  }`);
214
206
  }
215
207
  const keys = Object.keys(schema);
216
208
  code.push(...keys.map((key)=>codeGen(schema[key], context, `${valueAlias}['${key}']`, `${path}.${key}`)));
217
209
  return `{${code.join('\n')}}`;
218
210
  }
211
+ } else if (typeof schema === 'symbol') {
212
+ const index = context.register(schema);
213
+ const valueAlias = context.unique('v');
214
+ const registryAlias = context.unique('r');
215
+ return `
216
+ const ${valueAlias} = ${valuePath};
217
+ const ${registryAlias} = ctx.registry[${index}];
218
+ if (typeof ${valueAlias} !== 'symbol') { throw new ctx.Error(typeof ${valueAlias}, 'symbol', '${path}', 'type of'); }
219
+ if (${valueAlias} !== ${registryAlias}) { throw new ctx.Error(${valueAlias}.toString(), ${registryAlias}.toString(), '${path}', 'symbol'); }
220
+ `;
221
+ } else if (schema === null || schema === undefined) {
222
+ const valueAlias = context.unique('v');
223
+ return `
224
+ const ${valueAlias} = ${valuePath};
225
+ if (${valueAlias} !== null && ${valueAlias} !== undefined ) { throw new ctx.Error(${valueAlias}, 'nullable', '${path}'); }
226
+ `;
219
227
  } else {
220
228
  const valueAlias = context.unique('v');
229
+ const typeAlias = context.unique('t');
230
+ const value = context.unique('val');
221
231
  return `
222
232
  const ${valueAlias} = ${valuePath};
223
- if (${valueAlias} !== ${schema}) { throw new ctx.Error(${valueAlias}, ${schema}, \`${path}\`); }
233
+ const ${typeAlias} = '${typeof schema}';
234
+ const ${value} = ${JSON.stringify(schema)};
235
+ if (typeof ${valueAlias} !== ${typeAlias}) { throw new ctx.Error(typeof ${valueAlias}, ${typeAlias}, '${path}', 'type of'); }
236
+ if (${valueAlias} !== ${value}) { throw new ctx.Error(${valueAlias}, ${value}, '${path}'); }
224
237
  `;
225
238
  }
226
239
  };
240
+ const flatAggregateError = (error)=>{
241
+ return error.errors.flatMap((e)=>e instanceof AggregateError ? flatAggregateError(e) : e);
242
+ };
227
243
  export const compile = (schema, rootName, options = {})=>{
228
244
  const context = new Context(options);
229
245
  const code = codeGen(schema, context, 'data', rootName);
230
246
  const validator = new Function('ctx', 'data', code);
231
- return (data)=>validator(context, data);
232
- };
233
- const findFirstError = (array, map)=>{
234
- for(let i = 0; i < array.length; i++){
235
- const error = map(array[i], i);
236
- if (error) {
237
- return error;
247
+ return (data)=>{
248
+ try {
249
+ validator(context, data);
250
+ } catch (e) {
251
+ const errors = e instanceof AggregateError ? flatAggregateError(e) : [
252
+ e
253
+ ];
254
+ throw new AggregateError(errors, 'Validation failure');
238
255
  }
239
- }
240
- return false;
256
+ };
241
257
  };
242
- const findNotError = (array, map)=>{
243
- const errors = [];
244
- for(let i = 0; i < array.length; i++){
245
- const error = map(array[i], i);
246
- if (!error) {
247
- return false;
248
- } else {
249
- errors.push(error);
258
+ const assert = (target, schema, path)=>{
259
+ if (schema instanceof And) {
260
+ return schema.schemas.flatMap((schema)=>assert(target, schema, path)).filter((error)=>!!error);
261
+ } else if (schema instanceof Or) {
262
+ const errors = schema.schemas.flatMap((schema)=>assert(target, schema, path));
263
+ const filteredErrors = errors.filter((error)=>!!error);
264
+ if (filteredErrors.length === schema.schemas.length) {
265
+ return filteredErrors;
250
266
  }
251
- }
252
- return errors.reduce((result, error)=>{
253
- return new AssertError(result.value, [
254
- result.expected,
255
- error.expected
256
- ].join(' or '), result.path, result.subject);
257
- });
258
- };
259
- const assert = (target, schema, path, optional = false)=>{
260
- if (schema === null || typeof schema === 'undefined') {
261
- return new AssertError(schema, 'any value', path, 'schema value');
262
- }
263
- if (schema instanceof Optional) {
264
- return assert(target, schema.schemas[0], path, true);
265
- }
266
- const isValue = target !== null && typeof target !== 'undefined';
267
- if (!isValue && optional) {
268
- return;
269
- }
270
- if (schema instanceof Or) {
271
- if (!schema.schemas.length) {
272
- return new AssertError(target, 'values', path, 'OR schema');
267
+ } else if (schema instanceof Optional) {
268
+ if (target !== undefined && target !== null) {
269
+ return assert(target, schema.schemas[0], path);
273
270
  }
274
- return findNotError(schema.schemas, (schema)=>assert(target, schema, path));
275
- }
276
- if (schema instanceof And) {
277
- if (!schema.schemas.length) {
278
- return new AssertError(target, 'values', path, 'AND schema');
271
+ } else if (schema instanceof Tuple) {
272
+ if (!Array.isArray(target)) {
273
+ return [
274
+ new AssertError(target, 'array', path)
275
+ ];
279
276
  }
280
- return findFirstError(schema.schemas, (schema)=>assert(target, schema, path));
281
- }
282
- if (typeof schema === 'function') {
283
- if (!isValue) {
284
- return new AssertError(target, schema.name, path);
277
+ return schema.schemas.flatMap((s, idx)=>assert(target[idx], s, `${path}[${idx}]`)).filter((error)=>!!error);
278
+ } else if (typeof schema === 'function') {
279
+ if (target === null || target === undefined) {
280
+ return [
281
+ new AssertError(target, 'a non-nullable', path)
282
+ ];
285
283
  }
286
284
  if (typeof target === 'object' && !(target instanceof schema)) {
287
- return new AssertError(target, schema.name, path);
285
+ return [
286
+ new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')
287
+ ];
288
288
  }
289
- if (typeof target !== 'object' && target.constructor !== schema) {
290
- return new AssertError(target, schema.name, path);
289
+ if (typeof target !== 'object' && target?.constructor !== schema) {
290
+ return [
291
+ new AssertError(target?.constructor?.name, schema.name, path, 'type')
292
+ ];
291
293
  }
292
294
  } else if (Array.isArray(schema)) {
293
295
  if (!Array.isArray(target)) {
294
- return new AssertError(target, schema.constructor.name, path);
296
+ return [
297
+ new AssertError(target, 'array', path)
298
+ ];
295
299
  }
296
- return findFirstError(target, (value, idx)=>{
297
- return findNotError(schema, (itemSchemaType)=>assert(value, itemSchemaType, `${path}.${idx}`));
298
- });
299
- } else if (typeof schema === 'object') {
300
+ return schema.flatMap((s)=>target.flatMap((value, idx)=>assert(value, s, `${path}[${idx}]`))).filter((error)=>!!error);
301
+ } else if (typeof schema === 'object' && schema !== null) {
300
302
  if (schema instanceof RegExp) {
301
303
  if (!schema.test('' + target)) {
302
- return new AssertError(target, `matching /${schema.source}/`, path);
304
+ return [
305
+ new AssertError(target, `matching ${schema.toString()}`, path)
306
+ ];
303
307
  }
308
+ return [];
304
309
  } else {
305
- if (typeof target !== 'object') {
306
- return new AssertError(target, schema.constructor.name, path);
310
+ if (target === null || target === undefined) {
311
+ return [
312
+ new AssertError(target, 'object', path)
313
+ ];
307
314
  }
308
- if (target === null) {
309
- return new AssertError(target, 'an object', path);
315
+ if (typeof target !== 'object') {
316
+ return [
317
+ new AssertError(target, schema.constructor.name, path)
318
+ ];
310
319
  }
311
320
  if ($keys in schema) {
312
321
  const targetKeys = Object.keys(target);
313
- const assertError = findFirstError(targetKeys, (targetKey)=>assert(targetKey, schema[$keys], `${path}.${targetKey}`));
314
- if (assertError) {
315
- return assertError;
316
- }
322
+ return targetKeys.flatMap((key)=>assert(key, schema[$keys], path)).filter((error)=>!!error);
317
323
  }
318
324
  if ($values in schema) {
319
325
  const targetKeys = Object.keys(target);
320
- const assertError = findFirstError(targetKeys, (targetKey)=>assert(target[targetKey], schema[$values], `${path}.${targetKey}`));
321
- if (assertError) {
322
- return assertError;
323
- }
326
+ return targetKeys.flatMap((key)=>assert(target[key], schema[$values], path)).filter((error)=>!!error);
324
327
  }
325
- return findFirstError(Object.keys(schema), (key)=>assert(target[key], schema[key], `${path}.${key}`));
328
+ return Object.keys(schema).flatMap((key)=>assert(target[key], schema[key], path)).filter((error)=>!!error);
329
+ }
330
+ } else if (schema === null || schema === undefined) {
331
+ if (target !== null && target !== undefined) {
332
+ return [
333
+ new AssertError(target, 'nullable', path)
334
+ ];
326
335
  }
327
336
  } else if (target !== schema) {
328
- return new AssertError(target, schema, path);
337
+ return [
338
+ new AssertError(target, schema, path)
339
+ ];
329
340
  }
341
+ return [];
330
342
  };
331
343
  export const ascertain = (schema, data, rootName = '[root]')=>{
332
- const result = assert(data, schema, rootName);
333
- if (result instanceof AssertError) {
334
- throw new TypeError(result.toString());
344
+ const result = assert(data, schema, rootName).filter((error)=>!!error);
345
+ if (result.length > 0) {
346
+ throw new AggregateError(result, 'Validation failure');
335
347
  }
336
348
  };
337
349
 
@@ -1 +1 @@
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":["AssertError","TypeError","join","errors","separator","value","map","e","expected","path","subject","constructor","JSON","stringify","Operation","schemas","length","name","Or","or","And","and","Optional","schema","optional","Tuple","tuple","$keys","Symbol","for","$values","fromBase64","Buffer","atob","from","toString","MULTIPLIERS","ms","s","m","h","d","w","as","string","undefined","number","result","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","amount","unit","parseInt","boolean","test","array","delimiter","split","json","base64","Context","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","compile","rootName","validator","Function","data","findFirstError","i","findNotError","reduce","assert","target","isValue","itemSchemaType","source","targetKeys","assertError","targetKey","ascertain"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class AssertError extends TypeError {\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 Keys = string | number | symbol;\ntype DataValue = any;\nexport type 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\nclass Context {\n public readonly Error: typeof AssertError;\n public readonly registry: unknown[] = [];\n private varIndex = 0;\n\n constructor(public readonly options: CompilerOptions = {}) {\n this.Error = options.error ?? AssertError;\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?: typeof AssertError;\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 new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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(\n (result, code) => `try {${code}} catch (e) {${errorsAlias}.push(e);${result}}`,\n `throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"');`,\n );\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: string[] = [\n '// Tuple',\n `const ${valueAlias} = ${valuePath};`,\n `const ${errorsAlias} = [];`,\n `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \\`${path}\\`); }`,\n ...schema.schemas.map((s, idx) => `try { ${codeGen(s, context, `${valueAlias}[${idx}]`, `${path}[${idx}]`)} } catch (e) { ${errorsAlias}.push(e); }`),\n `if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }`,\n ];\n\n return code.join('\\n');\n } else 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'); }\nif (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}, 'array', \\`${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 code.push(`const ${errorsAlias} = [];`);\n code.push(\n ...schema.map(\n (s) =>\n `${valueAlias}.forEach((${value},${key}) => { try { ${codeGen(s, context, value, `${path}[\\${${key}}]`)} } catch(e){ ${errorsAlias}.push(e); } });`,\n ),\n );\n\n code.push(`if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }`);\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 (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'object', \\`${path}\\`); }`,\n `if (typeof ${valueAlias} !== 'object') { throw new ctx.Error(${valueAlias}, '${schema.constructor.name}', \\`${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}.flatMap((${value}) => { ${codeGen(schema[$keys], context, value, path)} }).filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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}.flatMap((${vAlias}) => { ${codeGen(schema[$values], context, vAlias, path)} }).filter(Boolean);\nif (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path \"${path}\"'); }\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 if (typeof schema === 'symbol') {\n const index = context.register(schema);\n const valueAlias = context.unique('v');\n const registryAlias = context.unique('r');\n\n return `\nconst ${valueAlias} = ${valuePath};\nconst ${registryAlias} = ctx.registry[${index}];\nif (typeof ${valueAlias} !== 'symbol') { throw new ctx.Error(typeof ${valueAlias}, 'symbol', '${path}', 'type of'); }\nif (${valueAlias} !== ${registryAlias}) { throw new ctx.Error(${valueAlias}.toString(), ${registryAlias}.toString(), '${path}', 'symbol'); }\n `;\n } else if (schema === null || schema === undefined) {\n const valueAlias = context.unique('v');\n return `\nconst ${valueAlias} = ${valuePath};\nif (${valueAlias} !== null && ${valueAlias} !== undefined ) { throw new ctx.Error(${valueAlias}, 'nullable', '${path}'); }\n `;\n } else {\n const valueAlias = context.unique('v');\n const typeAlias = context.unique('t');\n const value = context.unique('val');\n return `\nconst ${valueAlias} = ${valuePath};\nconst ${typeAlias} = '${typeof schema}';\nconst ${value} = ${JSON.stringify(schema)};\nif (typeof ${valueAlias} !== ${typeAlias}) { throw new ctx.Error(typeof ${valueAlias}, ${typeAlias}, '${path}', 'type of'); }\nif (${valueAlias} !== ${value}) { throw new ctx.Error(${valueAlias}, ${value}, '${path}'); }\n`;\n }\n};\n\nconst flatAggregateError = (error: AggregateError): AssertError[] => {\n return error.errors.flatMap((e) => (e instanceof AggregateError ? flatAggregateError(e) : e));\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>) => {\n try {\n validator(context, data);\n } catch (e) {\n const errors = e instanceof AggregateError ? flatAggregateError(e) : [e];\n throw new AggregateError(errors, 'Validation failure');\n }\n };\n};\n\nconst assert = (target: unknown, schema: unknown, path: string): AssertError[] => {\n if (schema instanceof And) {\n return schema.schemas.flatMap((schema) => assert(target, schema, path)).filter((error) => !!error);\n } else if (schema instanceof Or) {\n const errors = schema.schemas.flatMap((schema) => assert(target, schema, path));\n const filteredErrors = errors.filter((error) => !!error);\n if (filteredErrors.length === schema.schemas.length) {\n return filteredErrors;\n }\n } else if (schema instanceof Optional) {\n if (target !== undefined && target !== null) {\n return assert(target, schema.schemas[0], path);\n }\n } else if (schema instanceof Tuple) {\n if (!Array.isArray(target)) {\n return [new AssertError(target, 'array', path)];\n }\n return schema.schemas.flatMap((s, idx) => assert(target[idx], s, `${path}[${idx}]`)).filter((error) => !!error);\n } else if (typeof schema === 'function') {\n if (target === null || target === undefined) {\n return [new AssertError(target, 'a non-nullable', path)];\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return [new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')];\n }\n if (typeof target !== 'object' && target?.constructor !== schema) {\n return [new AssertError(target?.constructor?.name, schema.name, path, 'type')];\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return [new AssertError(target, 'array', path)];\n }\n return schema.flatMap((s) => target.flatMap((value, idx) => assert(value, s, `${path}[${idx}]`))).filter((error) => !!error);\n } else if (typeof schema === 'object' && schema !== null) {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return [new AssertError(target, `matching ${schema.toString()}`, path)];\n }\n return [];\n } else {\n if (target === null || target === undefined) {\n return [new AssertError(target, 'object', path)];\n }\n if (typeof target !== 'object') {\n return [new AssertError(target, schema.constructor.name, path)];\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n return targetKeys.flatMap((key) => assert(key, schema[$keys], path)).filter((error) => !!error);\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n return targetKeys.flatMap((key) => assert(target[key as keyof typeof target], schema[$values], path)).filter((error) => !!error);\n }\n return Object.keys(schema)\n .flatMap((key) => assert(target[key as keyof typeof target], schema[key as keyof typeof target], path))\n .filter((error) => !!error);\n }\n } else if (schema === null || schema === undefined) {\n if (target !== null && target !== undefined) {\n return [new AssertError(target, 'nullable', path)];\n }\n } else if (target !== schema) {\n return [new AssertError(target, schema, path)];\n }\n return [];\n};\n\nexport const ascertain = <T extends Data = DataValue>(schema: Schema<T>, data: T, rootName = '[root]') => {\n const result = assert(data, schema, rootName).filter((error) => !!error);\n if (result.length > 0) {\n throw new AggregateError(result, 'Validation failure');\n }\n};\n"],"names":["AssertError","TypeError","constructor","value","expected","path","subject","JSON","stringify","Operation","schemas","length","name","Or","or","And","and","Optional","schema","optional","Tuple","tuple","$keys","Symbol","for","$values","fromBase64","Buffer","atob","from","toString","MULTIPLIERS","ms","s","m","h","d","w","as","string","undefined","number","result","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","amount","unit","parseInt","boolean","test","array","delimiter","split","json","e","base64","Context","Error","registry","varIndex","options","error","register","includes","push","indexOf","unique","prefix","codeGen","context","valuePath","valueAlias","errorsAlias","code","map","join","reduceRight","idx","index","registryAlias","Array","isArray","key","RegExp","keysAlias","vAlias","valuesAlias","keys","Object","typeAlias","flatAggregateError","errors","flatMap","AggregateError","compile","rootName","validator","Function","data","assert","target","filter","filteredErrors","targetKeys","ascertain"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ascertain",
3
- "version": "0.15.0-0",
3
+ "version": "1.0.1",
4
4
  "description": "0-Deps, simple, fast, for browser and node js object schema validator",
5
5
  "type": "module",
6
6
  "types": "build/index.d.ts",
@@ -14,6 +14,13 @@
14
14
  "build",
15
15
  "src/index.js"
16
16
  ],
17
+ "scripts": {
18
+ "build": "rm -rf build && NODE_ENV=production inop src/ build -i __tests__ && tsc --declaration --emitDeclarationOnly",
19
+ "lint": "eslint src",
20
+ "test": "NODE_ENV=test jest --bail",
21
+ "test:cov": "CI=1 NODE_ENV=test jest",
22
+ "prepare": "husky"
23
+ },
17
24
  "repository": {
18
25
  "type": "git",
19
26
  "url": "git+https://github.com/3axap4eHko/ascertain.git"
@@ -38,26 +45,25 @@
38
45
  },
39
46
  "homepage": "https://github.com/3axap4eHko/ascertain#readme",
40
47
  "devDependencies": {
48
+ "@eslint/eslintrc": "^3.1.0",
49
+ "@eslint/js": "^9.6.0",
41
50
  "@swc/jest": "^0.2.36",
42
51
  "@types/jest": "^29.5.12",
43
- "@typescript-eslint/eslint-plugin": "^7.13.1",
44
- "@typescript-eslint/parser": "^7.13.1",
45
- "eslint": "^8.56.0",
52
+ "@types/node": "^20.14.9",
53
+ "@typescript-eslint/eslint-plugin": "^7.15.0",
54
+ "@typescript-eslint/parser": "^7.15.0",
55
+ "eslint": "^9.6.0",
46
56
  "eslint-config-airbnb-base": "^15.0.0",
47
57
  "eslint-config-prettier": "^9.1.0",
48
58
  "eslint-plugin-import": "^2.29.1",
49
59
  "eslint-plugin-prettier": "^5.1.3",
50
60
  "husky": "^9.0.11",
51
- "inop": "^0.7.0",
61
+ "inop": "^0.7.3",
52
62
  "jest": "^29.7.0",
53
63
  "overtake": "^0.1.1",
54
64
  "prettier": "^3.3.2",
55
65
  "ts-node": "^10.9.2",
56
- "typescript": "^5.5.2"
66
+ "typescript": "^5.5.3"
57
67
  },
58
- "scripts": {
59
- "build": "rm -rf build && NODE_ENV=production inop src/ build -i __tests__ && tsc --declaration --emitDeclarationOnly",
60
- "test": "NODE_ENV=test jest",
61
- "test:cov": "CI=1 NODE_ENV=test jest"
62
- }
63
- }
68
+ "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a"
69
+ }