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.
- package/LICENSE +21 -0
- package/README.md +97 -11
- package/build/index.cjs +265 -93
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +50 -32
- package/build/index.js +257 -91
- package/build/index.js.map +1 -1
- package/package.json +25 -12
- package/src/index.js +0 -201
package/build/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["class AssertError {\n constructor(value, expected, path, subject = 'value') {\n this.value = value;\n this.expected = expected;\n this.path = path;\n this.subject = subject;\n }\n\n toString() {\n return `Invalid ${this.subject} ${JSON.stringify(this.value)} specified by path ${this.path} expected ${this.expected}`;\n }\n}\n\nfunction findFirstError(array, map) {\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (error) {\n return error;\n }\n }\n return false;\n}\n\nfunction findNotError(array, map) {\n const errors = [];\n for (let i = 0; i < array.length; i++) {\n const error = map(array[i], i);\n if (!error) {\n return false;\n } else {\n errors.push(error);\n }\n }\n return errors.reduce((result, error) => {\n return new AssertError(result.value, [result.expected, error.expected].join(' or '), result.path, result.string);\n });\n}\n\nfunction Optional(schema) {\n this.schema = schema;\n}\n\nfunction And(schema) {\n this.schema = schema;\n}\n\nfunction Or(schema) {\n this.schema = schema;\n}\n\nexport const optional = (schema) => {\n return new Optional(schema);\n};\n\nexport const and = (...schema) => {\n return new And(schema);\n};\n\nexport const or = (...schema) => {\n return new Or(schema);\n};\n\nexport const $keys = Symbol.for('@@keys');\nexport const $values = Symbol.for('@@values');\n\nexport const fromBase64 =\n typeof Buffer === 'undefined' ? (value) => atob(value) : (value) => Buffer.from(value, 'base64').toString('utf-8');\n\nconst MULTIPLIERS = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n};\n\nexport const as = {\n string: (value) => {\n return typeof value === 'string' ? value : undefined;\n },\n number: (value) => {\n const result = parseFloat(value);\n return Number.isFinite(result) ? result : undefined;\n },\n date: (value) => {\n const result = Date.parse(value);\n return Number.isFinite(result) ? new Date(result) : undefined;\n },\n time: (value) => {\n const matches = value?.match(/^(\\d+)(ms|s|m|h|d|w)?$/);\n if (matches) {\n const [_, amount, unit = 'ms'] = matches;\n return parseInt(amount, 10) * MULTIPLIERS[unit];\n }\n return undefined;\n },\n boolean: (value) => (/^(0|1|true|false|enabled|disabled)$/i.test(value) ? /^(1|true|enabled)$/i.test(value) : undefined),\n array: (value, delimiter) => value?.split(delimiter) ?? undefined,\n json: (value) => {\n try {\n return JSON.parse(value);\n } catch (e) {\n return undefined;\n }\n },\n base64: (value) => {\n try {\n return fromBase64(value);\n } catch (e) {\n return undefined;\n }\n },\n};\n\nfunction certain(target, schema, path, optional) {\n if (schema === null || typeof schema === 'undefined') {\n return new AssertError(schema, 'any value', path, 'schema value');\n }\n if (schema instanceof Optional) {\n return certain(target, schema.schema, path, true);\n }\n const isValue = target !== null && typeof target !== 'undefined';\n if (!isValue && optional) {\n return;\n }\n if (schema instanceof Or) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'OR schema');\n }\n return findNotError(schema.schema, (schema) => certain(target, schema, path));\n }\n if (schema instanceof And) {\n if (!schema.schema.length) {\n return new AssertError(target, 'values', path, 'AND schema');\n }\n return findFirstError(schema.schema, (schema) => certain(target, schema, path));\n }\n\n if (typeof schema === 'function') {\n if (!isValue) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target === 'object' && !(target instanceof schema)) {\n return new AssertError(target, schema.name, path);\n }\n if (typeof target !== 'object' && target.constructor !== schema) {\n return new AssertError(target, schema.name, path);\n }\n } else if (Array.isArray(schema)) {\n if (!Array.isArray(target)) {\n return new AssertError(target, schema.constructor.name, path);\n }\n return findFirstError(target, (value, idx) => {\n return findNotError(schema, (itemSchemaType) => certain(value, itemSchemaType, `${path}.${idx}`));\n });\n } else if (typeof schema === 'object') {\n if (schema instanceof RegExp) {\n if (!schema.test('' + target)) {\n return new AssertError(target, `matching /${schema.source}/`, path);\n }\n } else {\n if (typeof target !== 'object') {\n return new AssertError(target, schema.constructor.name, path);\n }\n if (target === null) {\n return new AssertError(target, 'an object', path);\n }\n if ($keys in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(targetKey, schema[$keys], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n if ($values in schema) {\n const targetKeys = Object.keys(target);\n const assertError = findFirstError(targetKeys, (targetKey) =>\n certain(target[targetKey], schema[$values], `${path}.${targetKey}`)\n );\n if (assertError) {\n return assertError;\n }\n }\n return findFirstError(Object.keys(schema), (key) => certain(target[key], schema[key], `${path}.${key}`));\n }\n } else if (target !== schema) {\n return new AssertError(target, schema, path);\n }\n}\n\nexport const ascertain = (schema, data, rootName = '[root]') => {\n const result = certain(data, schema, rootName);\n if (result instanceof AssertError) {\n throw new TypeError(result.toString());\n }\n};\n\nexport default ascertain;\n"],"names":["$keys","$values","and","as","ascertain","fromBase64","optional","or","AssertError","constructor","value","expected","path","subject","toString","JSON","stringify","findFirstError","array","map","i","length","error","findNotError","errors","push","reduce","result","join","string","Optional","schema","And","Or","Symbol","for","Buffer","atob","from","MULTIPLIERS","ms","s","m","h","d","w","undefined","number","parseFloat","Number","isFinite","date","Date","parse","time","matches","match","_","amount","unit","parseInt","boolean","test","delimiter","split","json","e","base64","certain","target","isValue","name","Array","isArray","idx","itemSchemaType","RegExp","source","targetKeys","Object","keys","assertError","targetKey","key","data","rootName","TypeError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export class AssertError extends TypeError {\n 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
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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<
|
|
7
|
-
|
|
8
|
-
export type Schema<T> = T extends Data
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
28
|
-
|
|
29
|
-
export
|
|
30
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
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
|
-
|
|
39
|
-
this.schema = schema;
|
|
23
|
+
class Or extends Operation {
|
|
40
24
|
}
|
|
41
|
-
|
|
42
|
-
|
|
25
|
+
export const or = (...schemas)=>new Or(schemas);
|
|
26
|
+
class And extends Operation {
|
|
43
27
|
}
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
49
|
-
}
|
|
50
|
-
export const
|
|
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 [
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
109
|
-
|
|
99
|
+
register(value) {
|
|
100
|
+
if (!this.registry.includes(value)) {
|
|
101
|
+
this.registry.push(value);
|
|
102
|
+
}
|
|
103
|
+
return this.registry.indexOf(value);
|
|
110
104
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return;
|
|
105
|
+
unique(prefix) {
|
|
106
|
+
return `${prefix}$$${this.varIndex++}`;
|
|
114
107
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
123
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
285
|
+
return [
|
|
286
|
+
new AssertError(target?.constructor?.name, `instance of ${schema.name}`, path, 'instance of')
|
|
287
|
+
];
|
|
133
288
|
}
|
|
134
|
-
if (typeof target !== 'object' && target
|
|
135
|
-
return
|
|
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
|
|
296
|
+
return [
|
|
297
|
+
new AssertError(target, 'array', path)
|
|
298
|
+
];
|
|
140
299
|
}
|
|
141
|
-
return
|
|
142
|
-
|
|
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
|
|
304
|
+
return [
|
|
305
|
+
new AssertError(target, `matching ${schema.toString()}`, path)
|
|
306
|
+
];
|
|
148
307
|
}
|
|
308
|
+
return [];
|
|
149
309
|
} else {
|
|
150
|
-
if (
|
|
151
|
-
return
|
|
310
|
+
if (target === null || target === undefined) {
|
|
311
|
+
return [
|
|
312
|
+
new AssertError(target, 'object', path)
|
|
313
|
+
];
|
|
152
314
|
}
|
|
153
|
-
if (target
|
|
154
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
178
|
-
if (result
|
|
179
|
-
throw new
|
|
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
|