ascertain 0.14.39 → 1.0.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"sourcesContent":["class AssertError {\n constructor(value, expected, path, subject = 'value') {\n this.value = value;\n this.expected = expected;\n this.path = path;\n this.subject = subject;\n }\n\n toString() {\n return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;\n }\n}\n\nfunction findFirstError(array, map) {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n}\n\nfunction findNotError(array, map) {\n const errors = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);\n });\n}\n\nfunction Optional(schema) {\n this.schema = schema;\n}\n\nfunction And(schema) {\n this.schema = schema;\n}\n\nfunction Or(schema) {\n this.schema = schema;\n}\n\nexport const optional = (schema) => {\n return new Optional(schema);\n};\n\nexport const and = (...schema) => {\n return new And(schema);\n};\n\nexport const or = (...schema) => {\n return new Or(schema);\n};\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\n\nexport const fromBase64 =\n typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value) => {\n const result = parseFloat(value);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value) => {\n const result = Date.parse(value);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [_, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit];\n }\n return undefined;\n },\n boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),\n array: (value, delimiter) => value?.split(delimiter) ?? undefined,\n json: (value) => {\n try {\n return JSON.parse(value);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value) => {\n try {\n return fromBase64(value);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nfunction certain(target, schema, path, optional) {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return certain(target, schema.schema, path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schema, (schema) => certain(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schema, (schema) => certain(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(targetKey, schema[$keys], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(target[targetKey], schema[$values], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n}\n\nexport const ascertain = (schema, data, rootName = '[root]') => {\n const result = certain(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n\nexport default ascertain;\n"],"names":["$keys","$values","and","as","ascertain","fromBase64","optional","or","AssertError","constructor","value","expected","path","subject","toString","JSON","stringify","findFirstError","array","map","i","length","error","findNotError","errors","push","reduce","result","join","string","Optional","schema","And","Or","Symbol","for","Buffer","atob","from","MULTIPLIERS","ms","s","m","h","d","w","undefined","number","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","_","amount","unit","parseInt","boolean","test","delimiter","split","json","e","base64","certain","target","isValue","name","Array","isArray","idx","itemSchemaType","RegExp","source","targetKeys","Object","keys","assertError","targetKey","key","data","rootName","TypeError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class AssertError extends TypeError {\n 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
@@ -1,35 +1,53 @@
1
- export const $keys: symbol;
2
- export const $values: symbol;
3
-
4
- type DataKeys = string | number | symbol;
1
+ export declare class AssertError extends TypeError {
2
+ readonly value: unknown;
3
+ readonly expected: unknown;
4
+ readonly path: string;
5
+ readonly subject: string;
6
+ constructor(value: unknown, expected: unknown, path: string, subject?: string);
7
+ }
8
+ type Keys = string | number | symbol;
5
9
  type DataValue = any;
6
- type Data = Record<DataKeys, unknown>;
7
-
8
- export type Schema<T> = T extends Data
9
- ? { [S in keyof T]?: Schema<T[S]> }
10
- : DataValue;
11
-
12
- export function optional<T = any>(schema: Schema<T>): Schema<any>;
13
- export function and<T = any>(...schema: Schema<T>[]): Schema<any>;
14
- export function or<T = any>(...schemas: Schema<T>[]): Schema<any>;
15
-
16
- interface As {
17
- string: (value: string | undefined) => string,
18
- number: (value: string | undefined) => number,
19
- date: (value: string | undefined) => Date,
20
- time: (value: string | undefined) => number,
21
- boolean: (value: string | undefined) => boolean,
22
- array: (value: string | undefined, delimiter: string | RegExp) => string[];
23
- json: <T>(value: string | undefined) => T;
24
- base64: (value: string | undefined) => string;
10
+ export type Data = Record<Keys, unknown>;
11
+ type DataArray = DataValue[];
12
+ export type Schema<T> = T extends Data ? {
13
+ [S in keyof T]?: Schema<T[S]>;
14
+ } : T extends DataArray ? [Schema<T[number]>] : DataValue;
15
+ export type SchemaData<S> = S extends Record<Keys, unknown> ? {
16
+ [K in keyof S as Exclude<K, typeof $keys | typeof $values>]?: SchemaData<S[K]>;
17
+ } & Record<string, unknown> : S extends unknown[] ? unknown[] : unknown;
18
+ declare abstract class Operation<T extends Data = DataValue> {
19
+ readonly schemas: Schema<T>[];
20
+ constructor(schemas: Schema<T>[]);
21
+ }
22
+ declare class Or<T extends Data = DataValue> extends Operation<T> {
23
+ }
24
+ export declare const or: <T extends Data = any>(...schemas: Schema<T>[]) => Or<T>;
25
+ declare class And<T extends Data = DataValue> extends Operation<T> {
26
+ }
27
+ export declare const and: <T extends Data = any>(...schemas: Schema<T>[]) => And<T>;
28
+ declare class Optional<T extends Data = DataValue> extends Operation<T> {
29
+ constructor(schema: Schema<T>);
30
+ }
31
+ export declare const optional: <T extends Data = any>(schema: Schema<T>) => Optional<T>;
32
+ declare class Tuple<T extends Data = DataValue> extends Operation<T> {
25
33
  }
26
-
27
- export const as: As;
28
-
29
- export interface Ascertain {
30
- (data: any): void;
34
+ export declare const tuple: <T extends Data = any>(...schemas: Schema<T>[]) => Tuple<T>;
35
+ export declare const $keys: unique symbol;
36
+ export declare const $values: unique symbol;
37
+ export declare const fromBase64: (value: string) => string;
38
+ export declare const as: {
39
+ string: (value: string | undefined) => string | undefined;
40
+ number: (value: string | undefined) => number | undefined;
41
+ date: (value: string | undefined) => Date | undefined;
42
+ time: (value: string | undefined) => number | undefined;
43
+ boolean: (value: string | undefined) => boolean | undefined;
44
+ array: (value: string | undefined, delimiter: string) => string[] | undefined;
45
+ json: (value: string | undefined) => any;
46
+ base64: (value: string | undefined) => string | undefined;
47
+ };
48
+ export interface CompilerOptions {
49
+ error?: typeof AssertError;
31
50
  }
32
-
33
- export function ascertain<T extends Data = any>(schema: Schema<T>, data: any, rootName?: string): void;
34
-
35
- export default function <T extends Data = any>(schema: Schema<T>, data: any, rootName?: string): void;
51
+ export declare const compile: <S>(schema: S, rootName: string, options?: CompilerOptions) => (data: SchemaData<S>) => void;
52
+ export declare const ascertain: <T extends Data = any>(schema: Schema<T>, data: T, rootName?: string) => void;
53
+ export {};
package/build/index.js CHANGED
@@ -1,58 +1,42 @@
1
- let AssertError = class AssertError {
1
+ export class AssertError extends TypeError {
2
+ value;
3
+ expected;
4
+ path;
5
+ subject;
2
6
  constructor(value, expected, path, subject = 'value'){
7
+ super(`Invalid ${subject} ${JSON.stringify(value)} for path ${path}, expected ${expected}.`);
3
8
  this.value = value;
4
9
  this.expected = expected;
5
10
  this.path = path;
6
11
  this.subject = subject;
7
12
  }
8
- toString() {
9
- return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;
10
- }
11
- };
12
- function findFirstError(array, map) {
13
- for(let i = 0; i < array.length; i++){
14
- const error = map(array[i], i);
15
- if (error) {
16
- return error;
17
- }
18
- }
19
- return false;
20
13
  }
21
- function findNotError(array, map) {
22
- const errors = [];
23
- for(let i = 0; i < array.length; i++){
24
- const error = map(array[i], i);
25
- if (!error) {
26
- return false;
27
- } else {
28
- errors.push(error);
14
+ class Operation {
15
+ schemas;
16
+ constructor(schemas){
17
+ this.schemas = schemas;
18
+ if (schemas.length === 0) {
19
+ throw new TypeError(`Operation schema ${this.constructor.name} must have at least one element`);
29
20
  }
30
21
  }
31
- return errors.reduce((result, error)=>{
32
- return new AssertError(result.value, [
33
- result.expected,
34
- error.expected
35
- ].join(' or '), result.path, result.string);
36
- });
37
22
  }
38
- function Optional(schema) {
39
- this.schema = schema;
23
+ class Or extends Operation {
40
24
  }
41
- function And(schema) {
42
- this.schema = schema;
25
+ export const or = (...schemas)=>new Or(schemas);
26
+ class And extends Operation {
43
27
  }
44
- function Or(schema) {
45
- this.schema = schema;
28
+ export const and = (...schemas)=>new And(schemas);
29
+ class Optional extends Operation {
30
+ constructor(schema){
31
+ super([
32
+ schema
33
+ ]);
34
+ }
46
35
  }
47
- export const optional = (schema)=>{
48
- return new Optional(schema);
49
- };
50
- export const and = (...schema)=>{
51
- return new And(schema);
52
- };
53
- export const or = (...schema)=>{
54
- return new Or(schema);
55
- };
36
+ export const optional = (schema)=>new Optional(schema);
37
+ class Tuple extends Operation {
38
+ }
39
+ export const tuple = (...schemas)=>new Tuple(schemas);
56
40
  export const $keys = Symbol.for('@@keys');
57
41
  export const $values = Symbol.for('@@values');
58
42
  export const fromBase64 = typeof Buffer === 'undefined' ? (value)=>atob(value) : (value)=>Buffer.from(value, 'base64').toString('utf-8');
@@ -79,13 +63,13 @@ export const as = {
79
63
  time: (value)=>{
80
64
  const matches = value?.match(/^(\d+)(ms|s|m|h|d|w)?$/);
81
65
  if (matches) {
82
- const [_, amount, unit = 'ms'] = matches;
66
+ const [, amount, unit = 'ms'] = matches;
83
67
  return parseInt(amount, 10) * MULTIPLIERS[unit];
84
68
  }
85
69
  return undefined;
86
70
  },
87
71
  boolean: (value)=>/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined,
88
- array: (value, delimiter)=>value?.split(delimiter) ?? undefined,
72
+ array: (value, delimiter)=>value?.split?.(delimiter) ?? undefined,
89
73
  json: (value)=>{
90
74
  try {
91
75
  return JSON.parse(value);
@@ -101,84 +85,266 @@ export const as = {
101
85
  }
102
86
  }
103
87
  };
104
- function certain(target, schema, path, optional) {
105
- if (schema === null || typeof schema === 'undefined') {
106
- return new AssertError(schema, 'any value', path, 'schema value');
88
+ class Context {
89
+ options;
90
+ Error;
91
+ registry;
92
+ varIndex;
93
+ constructor(options = {}){
94
+ this.options = options;
95
+ this.registry = [];
96
+ this.varIndex = 0;
97
+ this.Error = options.error ?? AssertError;
107
98
  }
108
- if (schema instanceof Optional) {
109
- return certain(target, schema.schema, path, true);
99
+ register(value) {
100
+ if (!this.registry.includes(value)) {
101
+ this.registry.push(value);
102
+ }
103
+ return this.registry.indexOf(value);
110
104
  }
111
- const isValue = target !== null && typeof target !== 'undefined';
112
- if (!isValue && optional) {
113
- return;
105
+ unique(prefix) {
106
+ return `${prefix}$$${this.varIndex++}`;
114
107
  }
115
- if (schema instanceof Or) {
116
- if (!schema.schema.length) {
117
- return new AssertError(target, 'values', path, 'OR schema');
108
+ }
109
+ const codeGen = (schema, context, valuePath, path)=>{
110
+ if (schema instanceof And) {
111
+ const valueAlias = context.unique('v');
112
+ const errorsAlias = context.unique('err');
113
+ const code = schema.schemas.map((s)=>`try { ${codeGen(s, context, valueAlias, path)} } catch (e) { ${errorsAlias}.push(e); }`).join('\n');
114
+ return `// And
115
+ const ${errorsAlias} = [];
116
+ const ${valueAlias} = ${valuePath};
117
+ ${code}
118
+ if (${errorsAlias}.length !== 0) { throw new AggregateError(${errorsAlias}, 'Invalid value for path "${path}"'); }
119
+ `;
120
+ } else if (schema instanceof Or) {
121
+ const valueAlias = context.unique('v');
122
+ const errorsAlias = context.unique('err');
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}"');`);
124
+ return `// Or
125
+ const ${errorsAlias} = [];
126
+ const ${valueAlias} = ${valuePath};
127
+ ${code}
128
+ `;
129
+ } else if (schema instanceof Optional) {
130
+ const valueAlias = context.unique('v');
131
+ return `// Optional
132
+ const ${valueAlias} = ${valuePath};
133
+ if (${valueAlias} !== undefined && ${valueAlias} !== null) { ${codeGen(schema.schemas[0], context, valueAlias, path)} }
134
+ `;
135
+ } else if (schema instanceof Tuple) {
136
+ const valueAlias = context.unique('v');
137
+ const errorsAlias = context.unique('err');
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') {
148
+ const index = context.register(schema);
149
+ const valueAlias = context.unique('v');
150
+ const registryAlias = context.unique('r');
151
+ return `
152
+ const ${valueAlias} = ${valuePath};
153
+ const ${registryAlias} = ctx.registry[${index}];
154
+ if (${valueAlias} === null || ${valueAlias} === undefined) { throw new ctx.Error(${valueAlias}, 'a non-nullable', \`${path}\`); }
155
+ if (typeof ${valueAlias} === 'object' && !(${valueAlias} instanceof ${registryAlias})) { throw new ctx.Error(${valueAlias}?.constructor?.name, \`instance of \${${registryAlias}.name}\`, \`${path}\`, 'instance of'); }
156
+ if (typeof ${valueAlias} !== 'object' && ${valueAlias}?.constructor !== ${registryAlias}) { throw new ctx.Error(${valueAlias}?.constructor?.name, ${registryAlias}.name, \`${path}\`, 'type'); }
157
+ `;
158
+ } else if (Array.isArray(schema)) {
159
+ const valueAlias = context.unique('v');
160
+ const code = [
161
+ `const ${valueAlias} = ${valuePath};`,
162
+ `if (!Array.isArray(${valueAlias})) { throw new ctx.Error(${valueAlias}, 'array', \`${path}\`); }`
163
+ ];
164
+ if (schema.length > 0) {
165
+ const value = context.unique('val');
166
+ const key = context.unique('key');
167
+ const errorsAlias = context.unique('err');
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}"'); }`);
171
+ }
172
+ return code.join('\n');
173
+ } else if (typeof schema === 'object' && schema !== null) {
174
+ if (schema instanceof RegExp) {
175
+ const valueAlias = context.unique('v');
176
+ return `
177
+ const ${valueAlias} = ${valuePath};
178
+ if (!${schema.toString()}.test('' + ${valueAlias})) { throw new ctx.Error(${valueAlias}, 'matching ${schema.toString()}', \`${path}\`); }
179
+ `;
180
+ } else {
181
+ const valueAlias = context.unique('v');
182
+ const code = [
183
+ `const ${valueAlias} = ${valuePath};`,
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}\`); }`
186
+ ];
187
+ if ($keys in schema) {
188
+ const keysAlias = context.unique('key');
189
+ const errorsAlias = context.unique('err');
190
+ const value = context.unique('v');
191
+ code.push(`
192
+ const ${keysAlias} = Object.keys(${valueAlias});
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}"'); }
195
+ `);
196
+ }
197
+ if ($values in schema) {
198
+ const vAlias = context.unique('val');
199
+ const valuesAlias = context.unique('vals');
200
+ const errorsAlias = context.unique('err');
201
+ code.push(`{
202
+ const ${valuesAlias} = Object.values(${valuePath});
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}"'); }
205
+ }`);
206
+ }
207
+ const keys = Object.keys(schema);
208
+ code.push(...keys.map((key)=>codeGen(schema[key], context, `${valueAlias}['${key}']`, `${path}.${key}`)));
209
+ return `{${code.join('\n')}}`;
118
210
  }
119
- return findNotError(schema.schema, (schema)=>certain(target, schema, path));
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
+ `;
227
+ } else {
228
+ const valueAlias = context.unique('v');
229
+ const typeAlias = context.unique('t');
230
+ const value = context.unique('val');
231
+ return `
232
+ const ${valueAlias} = ${valuePath};
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}'); }
237
+ `;
120
238
  }
239
+ };
240
+ const flatAggregateError = (error)=>{
241
+ return error.errors.flatMap((e)=>e instanceof AggregateError ? flatAggregateError(e) : e);
242
+ };
243
+ export const compile = (schema, rootName, options = {})=>{
244
+ const context = new Context(options);
245
+ const code = codeGen(schema, context, 'data', rootName);
246
+ const validator = new Function('ctx', 'data', code);
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');
255
+ }
256
+ };
257
+ };
258
+ const assert = (target, schema, path)=>{
121
259
  if (schema instanceof And) {
122
- if (!schema.schema.length) {
123
- return new AssertError(target, 'values', path, 'AND schema');
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;
124
266
  }
125
- return findFirstError(schema.schema, (schema)=>certain(target, schema, path));
126
- }
127
- if (typeof schema === 'function') {
128
- if (!isValue) {
129
- return new AssertError(target, schema.name, path);
267
+ } else if (schema instanceof Optional) {
268
+ if (target !== undefined && target !== null) {
269
+ return assert(target, schema.schemas[0], path);
270
+ }
271
+ } else if (schema instanceof Tuple) {
272
+ if (!Array.isArray(target)) {
273
+ return [
274
+ new AssertError(target, 'array', path)
275
+ ];
276
+ }
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
+ ];
130
283
  }
131
284
  if (typeof target === 'object' && !(target instanceof schema)) {
132
- return new AssertError(target, schema.name, path);
285
+ return [
286
+ new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')
287
+ ];
133
288
  }
134
- if (typeof target !== 'object' && target.constructor !== schema) {
135
- 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
+ ];
136
293
  }
137
294
  } else if (Array.isArray(schema)) {
138
295
  if (!Array.isArray(target)) {
139
- return new AssertError(target, schema.constructor.name, path);
296
+ return [
297
+ new AssertError(target, 'array', path)
298
+ ];
140
299
  }
141
- return findFirstError(target, (value, idx)=>{
142
- return findNotError(schema, (itemSchemaType)=>certain(value, itemSchemaType, `${path}.${idx}`));
143
- });
144
- } 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) {
145
302
  if (schema instanceof RegExp) {
146
303
  if (!schema.test('' + target)) {
147
- return new AssertError(target, `matching /${schema.source}/`, path);
304
+ return [
305
+ new AssertError(target, `matching ${schema.toString()}`, path)
306
+ ];
148
307
  }
308
+ return [];
149
309
  } else {
150
- if (typeof target !== 'object') {
151
- return new AssertError(target, schema.constructor.name, path);
310
+ if (target === null || target === undefined) {
311
+ return [
312
+ new AssertError(target, 'object', path)
313
+ ];
152
314
  }
153
- if (target === null) {
154
- return new AssertError(target, 'an object', path);
315
+ if (typeof target !== 'object') {
316
+ return [
317
+ new AssertError(target, schema.constructor.name, path)
318
+ ];
155
319
  }
156
320
  if ($keys in schema) {
157
321
  const targetKeys = Object.keys(target);
158
- const assertError = findFirstError(targetKeys, (targetKey)=>certain(targetKey, schema[$keys], `${path}.${targetKey}`));
159
- if (assertError) {
160
- return assertError;
161
- }
322
+ return targetKeys.flatMap((key)=>assert(key, schema[$keys], path)).filter((error)=>!!error);
162
323
  }
163
324
  if ($values in schema) {
164
325
  const targetKeys = Object.keys(target);
165
- const assertError = findFirstError(targetKeys, (targetKey)=>certain(target[targetKey], schema[$values], `${path}.${targetKey}`));
166
- if (assertError) {
167
- return assertError;
168
- }
326
+ return targetKeys.flatMap((key)=>assert(target[key], schema[$values], path)).filter((error)=>!!error);
169
327
  }
170
- return findFirstError(Object.keys(schema), (key)=>certain(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
+ ];
171
335
  }
172
336
  } else if (target !== schema) {
173
- return new AssertError(target, schema, path);
337
+ return [
338
+ new AssertError(target, schema, path)
339
+ ];
174
340
  }
175
- }
341
+ return [];
342
+ };
176
343
  export const ascertain = (schema, data, rootName = '[root]')=>{
177
- const result = certain(data, schema, rootName);
178
- if (result instanceof AssertError) {
179
- 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');
180
347
  }
181
348
  };
182
- export default ascertain;
183
349
 
184
350
  //# sourceMappingURL=index.js.map