@cleverbrush/schema 0.0.17 → 1.0.0-beta.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 +213 -163
- package/package.json +3 -3
- package/src/builders/ArraySchemaBuilder.test.ts +270 -0
- package/src/builders/ArraySchemaBuilder.ts +381 -0
- package/src/builders/BooleanSchemaBuilder.test.ts +196 -0
- package/src/builders/BooleanSchemaBuilder.ts +155 -0
- package/src/builders/FunctionSchemaBuilder.test.ts +134 -0
- package/src/builders/FunctionSchemaBuilder.ts +109 -0
- package/src/builders/NumberSchemaBuilder.test.ts +493 -0
- package/src/builders/NumberSchemaBuilder.ts +789 -0
- package/src/builders/ObjectSchemaBuilder.test.ts +657 -0
- package/src/builders/ObjectSchemaBuilder.ts +794 -0
- package/src/builders/SchemaBuilder.test.ts +73 -0
- package/src/builders/SchemaBuilder.ts +135 -0
- package/src/builders/StringSchemaBuilder.test.ts +318 -0
- package/src/builders/StringSchemaBuilder.ts +392 -0
- package/src/builders/UnionSchemaBuilder.test.ts +162 -0
- package/src/builders/UnionSchemaBuilder.ts +154 -0
- package/src/defaultSchemas.ts +44 -0
- package/src/index.ts +58 -190
- package/src/schema.ts +827 -0
- package/src/schemaRegistry.builders.test.ts +1393 -0
- package/src/schemaRegistry.test.ts +118 -0
- package/src/schemaRegistry.ts +461 -0
- package/src/validators/validateArray.ts +4 -7
- package/src/validators/validateBoolean.ts +2 -11
- package/src/validators/validateFunction.ts +25 -0
- package/src/validators/validateNumber.ts +2 -7
- package/src/validators/validateObject.ts +32 -21
- package/src/validators/validateString.ts +2 -7
- package/src/validators/validateUnion.ts +36 -0
- package/dist/index.d.ts +0 -94
- package/dist/index.js +0 -9
- package/dist/schemaValidator.d.ts +0 -16
- package/dist/schemaValidator.js +0 -234
- package/dist/validators/validateArray.d.ts +0 -2
- package/dist/validators/validateArray.js +0 -60
- package/dist/validators/validateBoolean.d.ts +0 -2
- package/dist/validators/validateBoolean.js +0 -33
- package/dist/validators/validateNumber.d.ts +0 -2
- package/dist/validators/validateNumber.js +0 -69
- package/dist/validators/validateObject.d.ts +0 -2
- package/dist/validators/validateObject.js +0 -73
- package/dist/validators/validateString.d.ts +0 -2
- package/dist/validators/validateString.js +0 -50
- package/src/schemaValidator.test.ts +0 -1656
- package/src/schemaValidator.ts +0 -367
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
ObjectSchemaDefinition,
|
|
4
|
-
ISchemaValidator,
|
|
5
|
-
Schema
|
|
6
|
-
} from '../index';
|
|
1
|
+
import { ObjectSchema, Schema, ValidationResult } from '../schema.js';
|
|
2
|
+
import SchemaRegistry from '../schemaRegistry.js';
|
|
7
3
|
|
|
8
4
|
export const validateObject = async (
|
|
9
5
|
obj: any,
|
|
10
|
-
schema:
|
|
11
|
-
validator:
|
|
6
|
+
schema: ObjectSchema<any>,
|
|
7
|
+
validator: SchemaRegistry<any>
|
|
12
8
|
): Promise<ValidationResult> => {
|
|
13
9
|
if (
|
|
14
10
|
typeof obj === 'undefined' &&
|
|
@@ -33,11 +29,14 @@ export const validateObject = async (
|
|
|
33
29
|
Object.keys(schema.preprocessors).map(async (key: string) => {
|
|
34
30
|
if (key === '*') return;
|
|
35
31
|
if (typeof schema.preprocessors[key] === 'function') {
|
|
36
|
-
|
|
37
|
-
(schema.preprocessors[key] as (
|
|
38
|
-
obj[key]
|
|
39
|
-
)
|
|
32
|
+
const res = await Promise.resolve(
|
|
33
|
+
(schema.preprocessors[key] as any)(obj[key])
|
|
40
34
|
);
|
|
35
|
+
if (typeof res !== 'undefined') {
|
|
36
|
+
obj[key] = res;
|
|
37
|
+
} else {
|
|
38
|
+
delete obj[key];
|
|
39
|
+
}
|
|
41
40
|
} else {
|
|
42
41
|
const preprocessor = validator.preprocessors.get(
|
|
43
42
|
schema.preprocessors[key] as string
|
|
@@ -47,16 +46,19 @@ export const validateObject = async (
|
|
|
47
46
|
`preprocessor '${schema.preprocessors[key]}' is unknown`
|
|
48
47
|
);
|
|
49
48
|
}
|
|
50
|
-
|
|
49
|
+
const res = await Promise.resolve(preprocessor(obj[key]));
|
|
50
|
+
if (typeof res !== 'undefined') {
|
|
51
|
+
obj[key] = res;
|
|
52
|
+
} else {
|
|
53
|
+
delete obj[key];
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
})
|
|
53
57
|
);
|
|
54
58
|
if ('*' in schema.preprocessors) {
|
|
55
59
|
const objectPreprocessor = schema.preprocessors['*'];
|
|
56
60
|
if (typeof objectPreprocessor === 'function') {
|
|
57
|
-
await Promise.resolve(
|
|
58
|
-
(objectPreprocessor as (unknown) => unknown)(obj)
|
|
59
|
-
);
|
|
61
|
+
await Promise.resolve((objectPreprocessor as any)(obj));
|
|
60
62
|
} else {
|
|
61
63
|
const preprocessor = validator.preprocessors.get(
|
|
62
64
|
objectPreprocessor as string
|
|
@@ -72,10 +74,10 @@ export const validateObject = async (
|
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
if (typeof schema.properties === 'object' && schema.properties) {
|
|
75
|
-
const errors =
|
|
76
|
-
await Promise.all(
|
|
77
|
+
const errors = [
|
|
78
|
+
...(await Promise.all(
|
|
77
79
|
Object.entries(schema.properties).map(
|
|
78
|
-
async ([name, schema]: [string, Schema
|
|
80
|
+
async ([name, schema]: [string, Schema]) => {
|
|
79
81
|
const result = await validator.validate(
|
|
80
82
|
schema,
|
|
81
83
|
obj[name]
|
|
@@ -89,11 +91,20 @@ export const validateObject = async (
|
|
|
89
91
|
};
|
|
90
92
|
}
|
|
91
93
|
)
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
+
)),
|
|
95
|
+
...(schema.noUnknownProperties === false
|
|
96
|
+
? []
|
|
97
|
+
: Object.keys(obj)
|
|
98
|
+
.filter((k) => !(k in schema.properties))
|
|
99
|
+
.map((k) => ({
|
|
100
|
+
valid: false,
|
|
101
|
+
errors: [`-> ${k} - unknown field`]
|
|
102
|
+
})))
|
|
103
|
+
]
|
|
94
104
|
.filter((r) => !r.valid)
|
|
95
105
|
.map((r) => r.errors)
|
|
96
106
|
.flat(Infinity) as string[];
|
|
107
|
+
|
|
97
108
|
if (errors.length) {
|
|
98
109
|
return {
|
|
99
110
|
valid: false,
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ValidationResult,
|
|
3
|
-
StringSchemaDefinition,
|
|
4
|
-
ISchemaValidator
|
|
5
|
-
} from '../index';
|
|
1
|
+
import { StringSchema, ValidationResult } from '../schema.js';
|
|
6
2
|
|
|
7
3
|
export const validateString = async (
|
|
8
4
|
obj: any,
|
|
9
|
-
schema:
|
|
10
|
-
validator: ISchemaValidator<any>
|
|
5
|
+
schema: StringSchema
|
|
11
6
|
): Promise<ValidationResult> => {
|
|
12
7
|
if (
|
|
13
8
|
typeof obj === 'undefined' &&
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { UnionSchema, ValidationResult } from '../schema.js';
|
|
2
|
+
import SchemaRegistry from '../schemaRegistry.js';
|
|
3
|
+
|
|
4
|
+
export const validateUnion = async (
|
|
5
|
+
obj: any,
|
|
6
|
+
schema: UnionSchema<any>,
|
|
7
|
+
validator: SchemaRegistry<any>
|
|
8
|
+
): Promise<ValidationResult> => {
|
|
9
|
+
if (typeof obj === 'undefined' && schema.isRequired === false) {
|
|
10
|
+
return {
|
|
11
|
+
valid: true
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (obj === null && schema.isNullable) {
|
|
16
|
+
return {
|
|
17
|
+
valid: true
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (Array.isArray(schema.variants) && schema.variants.length > 0) {
|
|
22
|
+
for (let i = 0; i < schema.variants.length; i++) {
|
|
23
|
+
const variant = schema.variants[i];
|
|
24
|
+
const result = await validator.validate(variant, obj);
|
|
25
|
+
if (result.valid) {
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
valid: false,
|
|
31
|
+
errors: ['object does not satisfy any scheme']
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
throw new Error('variants should be non empty array');
|
|
36
|
+
};
|
package/dist/index.d.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Merge } from '@cleverbrush/deep';
|
|
2
|
-
import SchemaValidator from './schemaValidator';
|
|
3
|
-
export declare type DefaultSchemaType = 'object' | 'boolean' | 'function' | 'number' | 'string' | 'array' | 'alias';
|
|
4
|
-
export declare type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
|
|
5
|
-
export declare type DefaultPropertyDefinition = {
|
|
6
|
-
isRequired: boolean;
|
|
7
|
-
isNullable: boolean;
|
|
8
|
-
};
|
|
9
|
-
export declare type ValidationResultRaw = {
|
|
10
|
-
valid: boolean;
|
|
11
|
-
errors?: Array<string>;
|
|
12
|
-
};
|
|
13
|
-
export declare type ValidationResult = ValidationResultRaw | Promise<ValidationResultRaw>;
|
|
14
|
-
export declare type Validator<TObj> = (value: TObj) => ValidationResult;
|
|
15
|
-
export declare type SchemaDefintion<TObj> = {
|
|
16
|
-
type: DefaultSchemaType;
|
|
17
|
-
isRequired?: boolean;
|
|
18
|
-
isNullable?: boolean;
|
|
19
|
-
validators?: Array<Validator<TObj>>;
|
|
20
|
-
};
|
|
21
|
-
export declare type ObjectSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
|
|
22
|
-
type: 'object';
|
|
23
|
-
extends?: string;
|
|
24
|
-
properties?: Partial<{
|
|
25
|
-
[S in keyof T]: Schema<PropType<T, S>>;
|
|
26
|
-
}>;
|
|
27
|
-
preprocessors?: Partial<{
|
|
28
|
-
[S in keyof T | '*']: S extends keyof T ? ((value: unknown) => undefined | PropType<T, S> | Promise<PropType<T, S>>) | string : (value: T) => void | Promise<void>;
|
|
29
|
-
}>;
|
|
30
|
-
};
|
|
31
|
-
export declare type AliasSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
|
|
32
|
-
type: 'alias';
|
|
33
|
-
schemaName: string;
|
|
34
|
-
};
|
|
35
|
-
export declare type ObjectSchemaDefinitionParam<T> = Omit<ObjectSchemaDefinition<T>, 'type'>;
|
|
36
|
-
export declare type ParamsValidators<TFunc extends (...args: any) => any> = {
|
|
37
|
-
[S in keyof Parameters<TFunc>]: SingleSchema<Parameters<TFunc>[S]>;
|
|
38
|
-
};
|
|
39
|
-
export declare type FunctionSchemaDefinition<T extends (...args: any) => any> = Omit<SchemaDefintion<T>, 'type'> & {
|
|
40
|
-
type: 'function';
|
|
41
|
-
params?: ParamsValidators<T>;
|
|
42
|
-
};
|
|
43
|
-
export declare type BooleanSchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
|
|
44
|
-
type: 'boolean';
|
|
45
|
-
equals?: boolean;
|
|
46
|
-
};
|
|
47
|
-
export declare type NumberSchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
|
|
48
|
-
type: 'number';
|
|
49
|
-
min?: number;
|
|
50
|
-
max?: number;
|
|
51
|
-
equals?: number;
|
|
52
|
-
isInteger?: boolean;
|
|
53
|
-
ensureNotNaN?: boolean;
|
|
54
|
-
ensureIsFinite?: boolean;
|
|
55
|
-
};
|
|
56
|
-
export declare type StringSchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
|
|
57
|
-
type: 'string';
|
|
58
|
-
equals?: string;
|
|
59
|
-
minLength?: number;
|
|
60
|
-
maxLength?: number;
|
|
61
|
-
};
|
|
62
|
-
export declare type ArraySchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
|
|
63
|
-
type: 'array';
|
|
64
|
-
preprocessor?: ((value: unknown) => unknown | Promise<unknown>) | string;
|
|
65
|
-
ofType?: Schema<any>;
|
|
66
|
-
minLength?: number;
|
|
67
|
-
maxLength?: number;
|
|
68
|
-
};
|
|
69
|
-
export declare type CompositeSchema<TObj> = TObj extends (...args: any) => any ? FunctionSchemaDefinition<TObj> : TObj extends number ? NumberSchemaDefinition<TObj> : TObj extends string ? StringSchemaDefinition<TObj> | 'string' : BooleanSchemaDefinition<TObj> | NumberSchemaDefinition<TObj> | StringSchemaDefinition<TObj> | ArraySchemaDefinition<TObj> | ObjectSchemaDefinition<TObj> | AliasSchemaDefinition<TObj>;
|
|
70
|
-
export declare type SingleSchema<TObj = Record<string, never>> = number | string | DefaultSchemaType | CompositeSchema<TObj>;
|
|
71
|
-
export declare type Schema<TObj> = SingleSchema<TObj> | Array<SingleSchema<TObj>>;
|
|
72
|
-
export declare type Cons<H, T extends unknown[] = []> = T['length'] extends 0 ? [H] : ((h: H, ...t: T) => void) extends (...r: infer R) => void ? R : never;
|
|
73
|
-
export interface ISchemaActions<S> {
|
|
74
|
-
validate(value: any): Promise<ValidationResult>;
|
|
75
|
-
schema: S;
|
|
76
|
-
}
|
|
77
|
-
export interface ISchemasProvider<T extends unknown[]> {
|
|
78
|
-
schemas: Merge<T>;
|
|
79
|
-
}
|
|
80
|
-
export interface ISchemaValidator<T extends Record<string, never> = Record<string, never>, SchemaTypesStructures extends unknown[] = []> {
|
|
81
|
-
get preprocessors(): Map<string, (value: unknown) => unknown | Promise<unknown>>;
|
|
82
|
-
addPreprocessor(name: string, preprocessor: (value: unknown) => unknown | Promise<unknown>): SchemaValidator<T, SchemaTypesStructures>;
|
|
83
|
-
addSchemaType<K, L extends ObjectSchemaDefinitionParam<M> | Array<Schema<any>>, M = any>(name: keyof K, schema: L): SchemaValidator<T & {
|
|
84
|
-
[key in keyof K]: typeof schema;
|
|
85
|
-
}, Cons<Unfold<keyof K, ISchemaActions<L>>, SchemaTypesStructures>>;
|
|
86
|
-
validate(schema: keyof T | DefaultSchemaType | Schema<any>, obj: any): Promise<ValidationResult>;
|
|
87
|
-
}
|
|
88
|
-
export declare type Unfold<T, K> = T extends string ? T extends `${infer F}.${infer L}` ? {
|
|
89
|
-
[k in F]: Unfold<L, K>;
|
|
90
|
-
} : {
|
|
91
|
-
[k in T]: K;
|
|
92
|
-
} : never;
|
|
93
|
-
export { SchemaValidator };
|
|
94
|
-
export default SchemaValidator;
|
package/dist/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SchemaValidator = void 0;
|
|
7
|
-
const schemaValidator_1 = __importDefault(require("./schemaValidator"));
|
|
8
|
-
exports.SchemaValidator = schemaValidator_1.default;
|
|
9
|
-
exports.default = schemaValidator_1.default;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Merge } from '@cleverbrush/deep';
|
|
2
|
-
import { ISchemasProvider, Schema, ISchemaActions, ObjectSchemaDefinitionParam, ValidationResult, ISchemaValidator, DefaultSchemaType, Cons, Unfold } from './index';
|
|
3
|
-
export default class SchemaValidator<T extends Record<string, never> = Record<string, never>, SchemaTypesStructures extends unknown[] = []> implements ISchemasProvider<SchemaTypesStructures>, ISchemaValidator<T, SchemaTypesStructures> {
|
|
4
|
-
private _schemasMap;
|
|
5
|
-
private _schemasCache;
|
|
6
|
-
private _preprocessorsMap;
|
|
7
|
-
get preprocessors(): Map<string, (value: unknown) => unknown>;
|
|
8
|
-
addPreprocessor(name: string, preprocessor: (value: unknown) => unknown | Promise<unknown>): SchemaValidator<T, SchemaTypesStructures>;
|
|
9
|
-
addSchemaType<K, L extends ObjectSchemaDefinitionParam<M> | Array<Schema<any>>, M = any>(name: keyof K, schema: L): SchemaValidator<T & {
|
|
10
|
-
[key in keyof K]: L;
|
|
11
|
-
}, Cons<Unfold<keyof K, ISchemaActions<L>>, SchemaTypesStructures>>;
|
|
12
|
-
get schemas(): Merge<SchemaTypesStructures>;
|
|
13
|
-
private validateDefaultType;
|
|
14
|
-
private checkValidators;
|
|
15
|
-
validate<K>(schema: keyof T | DefaultSchemaType | Schema<K>, obj: any): Promise<ValidationResult>;
|
|
16
|
-
}
|
package/dist/schemaValidator.js
DELETED
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const deep_1 = require("@cleverbrush/deep");
|
|
4
|
-
const validateNumber_1 = require("./validators/validateNumber");
|
|
5
|
-
const validateBoolean_1 = require("./validators/validateBoolean");
|
|
6
|
-
const validateString_1 = require("./validators/validateString");
|
|
7
|
-
const validateArray_1 = require("./validators/validateArray");
|
|
8
|
-
const validateObject_1 = require("./validators/validateObject");
|
|
9
|
-
const defaultSchemaNames = ['string', 'boolean', 'number', 'date', 'array'];
|
|
10
|
-
const defaultSchemas = {
|
|
11
|
-
number: {
|
|
12
|
-
type: 'number',
|
|
13
|
-
isRequired: true,
|
|
14
|
-
isNullable: false,
|
|
15
|
-
ensureNotNaN: true,
|
|
16
|
-
ensureIsFinite: true
|
|
17
|
-
},
|
|
18
|
-
boolean: {
|
|
19
|
-
type: 'boolean',
|
|
20
|
-
isRequired: true,
|
|
21
|
-
isNullable: false
|
|
22
|
-
},
|
|
23
|
-
string: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
isNullable: false,
|
|
26
|
-
isRequired: true
|
|
27
|
-
},
|
|
28
|
-
array: {
|
|
29
|
-
type: 'array'
|
|
30
|
-
},
|
|
31
|
-
object: {
|
|
32
|
-
type: 'object',
|
|
33
|
-
isNullable: false,
|
|
34
|
-
isRequired: true
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
const defaultSchemasValidationStrategies = {
|
|
38
|
-
number: (obj, schema, validator) => (0, validateNumber_1.validateNumber)(obj, schema, validator),
|
|
39
|
-
boolean: (obj, schema, validator) => (0, validateBoolean_1.validateBoolean)(obj, schema, validator),
|
|
40
|
-
string: (obj, schema, validator) => (0, validateString_1.validateString)(obj, schema, validator),
|
|
41
|
-
array: (obj, schema, validator) => (0, validateArray_1.validateArray)(obj, schema, validator)
|
|
42
|
-
};
|
|
43
|
-
const isDefaultType = (name) => defaultSchemaNames.indexOf(name) !== -1;
|
|
44
|
-
class SchemaValidator {
|
|
45
|
-
_schemasMap = new Map();
|
|
46
|
-
_schemasCache = null;
|
|
47
|
-
_preprocessorsMap = new Map();
|
|
48
|
-
get preprocessors() {
|
|
49
|
-
return this._preprocessorsMap;
|
|
50
|
-
}
|
|
51
|
-
addPreprocessor(name, preprocessor) {
|
|
52
|
-
if (this._preprocessorsMap.has(name))
|
|
53
|
-
throw new Error(`Preprocessor '${name}' is already registered`);
|
|
54
|
-
this._preprocessorsMap.set(name, preprocessor);
|
|
55
|
-
return this;
|
|
56
|
-
}
|
|
57
|
-
addSchemaType(name, schema) {
|
|
58
|
-
if (typeof name !== 'string' || !name)
|
|
59
|
-
throw new Error('Name is required');
|
|
60
|
-
if (isDefaultType(name.toString()))
|
|
61
|
-
throw new Error(`You can't add a schema named "${name}" because it's a name of a default schema, please consider another name to be used`);
|
|
62
|
-
if (this._schemasMap.has(name.toString())) {
|
|
63
|
-
throw new Error(`Schema "${name}" already exists`);
|
|
64
|
-
}
|
|
65
|
-
if (Array.isArray(schema)) {
|
|
66
|
-
this._schemasMap.set(name.toString(), schema);
|
|
67
|
-
this._schemasCache = null;
|
|
68
|
-
return this;
|
|
69
|
-
}
|
|
70
|
-
if (typeof schema !== 'object')
|
|
71
|
-
throw new Error('Array or Object is required');
|
|
72
|
-
this._schemasMap.set(name.toString(), {
|
|
73
|
-
...schema,
|
|
74
|
-
type: 'object'
|
|
75
|
-
});
|
|
76
|
-
this._schemasCache = null;
|
|
77
|
-
return this;
|
|
78
|
-
}
|
|
79
|
-
get schemas() {
|
|
80
|
-
if (this._schemasCache)
|
|
81
|
-
return this._schemasCache;
|
|
82
|
-
const res = {};
|
|
83
|
-
for (const key of this._schemasMap.keys()) {
|
|
84
|
-
const parts = key.split('.');
|
|
85
|
-
let curr = res;
|
|
86
|
-
for (let i = 0; i < parts.length; i++) {
|
|
87
|
-
if (i === parts.length - 1) {
|
|
88
|
-
curr[parts[i]] = {
|
|
89
|
-
validate: (value) => this.validate(this._schemasMap.get(key), value),
|
|
90
|
-
schema: this._schemasMap.get(key)
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
if (typeof curr[parts[i]] === 'undefined') {
|
|
95
|
-
curr[parts[i]] = {};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
curr = curr[parts[i]];
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
this._schemasCache = res;
|
|
102
|
-
return this._schemasCache;
|
|
103
|
-
}
|
|
104
|
-
async validateDefaultType(name, value, mergeSchema) {
|
|
105
|
-
const strategy = defaultSchemasValidationStrategies[name];
|
|
106
|
-
let finalSchema = defaultSchemas[name];
|
|
107
|
-
if (strategy) {
|
|
108
|
-
if (typeof mergeSchema === 'object') {
|
|
109
|
-
finalSchema = (0, deep_1.deepExtend)(finalSchema, mergeSchema);
|
|
110
|
-
}
|
|
111
|
-
if (typeof mergeSchema === 'number') {
|
|
112
|
-
finalSchema = {
|
|
113
|
-
...finalSchema,
|
|
114
|
-
equals: mergeSchema
|
|
115
|
-
};
|
|
116
|
-
mergeSchema;
|
|
117
|
-
}
|
|
118
|
-
let preliminaryResult = await strategy(value, finalSchema, this);
|
|
119
|
-
if (!preliminaryResult.valid)
|
|
120
|
-
return preliminaryResult;
|
|
121
|
-
preliminaryResult = await this.checkValidators(finalSchema, value);
|
|
122
|
-
return preliminaryResult;
|
|
123
|
-
}
|
|
124
|
-
throw new Error('not implemented');
|
|
125
|
-
}
|
|
126
|
-
async checkValidators(schema, value) {
|
|
127
|
-
if (!schema.isRequired && typeof value === 'undefined') {
|
|
128
|
-
return {
|
|
129
|
-
valid: true
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
if (Array.isArray(schema.validators)) {
|
|
133
|
-
const validatorsResults = await Promise.allSettled(schema.validators.map((v) => Promise.resolve(v(value))));
|
|
134
|
-
const rejections = validatorsResults
|
|
135
|
-
.filter((f) => f.status === 'rejected')
|
|
136
|
-
.map((f) => f.reason);
|
|
137
|
-
const errors = validatorsResults
|
|
138
|
-
.filter((f) => f.status === 'fulfilled' &&
|
|
139
|
-
typeof f.value !== 'boolean' &&
|
|
140
|
-
f.value.valid === false)
|
|
141
|
-
.map((f) => f.value)
|
|
142
|
-
.map((f) => f.errors);
|
|
143
|
-
if (rejections.length === 0 && errors.length === 0) {
|
|
144
|
-
return {
|
|
145
|
-
valid: true
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
valid: false,
|
|
150
|
-
errors: [...rejections, ...errors]
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
valid: true
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
async validate(schema, obj) {
|
|
158
|
-
if (!schema)
|
|
159
|
-
throw new Error('schemaName is required');
|
|
160
|
-
if (typeof schema === 'string') {
|
|
161
|
-
if (isDefaultType(schema)) {
|
|
162
|
-
return await this.validateDefaultType(schema, obj);
|
|
163
|
-
}
|
|
164
|
-
else if (typeof this._schemasMap.get(schema) !== 'undefined') {
|
|
165
|
-
if (Array.isArray(this._schemasMap.get(schema))) {
|
|
166
|
-
return this.validate(this._schemasMap.get(schema), obj);
|
|
167
|
-
}
|
|
168
|
-
const objSchema = (0, deep_1.deepExtend)(defaultSchemas.object, this._schemasMap.get(schema));
|
|
169
|
-
const res = await (0, validateObject_1.validateObject)(obj, objSchema, this);
|
|
170
|
-
if (!res.valid)
|
|
171
|
-
return res;
|
|
172
|
-
return await this.checkValidators(objSchema, obj);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
return await this.validateDefaultType('string', obj, {
|
|
176
|
-
type: 'string',
|
|
177
|
-
equals: schema
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (Array.isArray(schema)) {
|
|
182
|
-
for (let i = 0; i < schema.length; i++) {
|
|
183
|
-
const res = await this.validate(schema[i], obj);
|
|
184
|
-
if (res.valid) {
|
|
185
|
-
return res;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return {
|
|
189
|
-
valid: false,
|
|
190
|
-
errors: ['object does not match any schema']
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
if (typeof schema === 'number') {
|
|
194
|
-
return await this.validateDefaultType('number', obj, schema);
|
|
195
|
-
}
|
|
196
|
-
if (typeof schema === 'object') {
|
|
197
|
-
if (typeof schema.type !== 'string')
|
|
198
|
-
throw new Error('Schema has no type');
|
|
199
|
-
if (isDefaultType(schema.type)) {
|
|
200
|
-
return await this.validateDefaultType(schema.type, obj, schema);
|
|
201
|
-
}
|
|
202
|
-
else if (schema.type === 'alias') {
|
|
203
|
-
const alias = this._schemasMap.get(schema.schemaName);
|
|
204
|
-
if (typeof alias === 'undefined') {
|
|
205
|
-
throw new Error(`Unknown schema alias - ${schema.schemaName}`);
|
|
206
|
-
}
|
|
207
|
-
if (Array.isArray(alias)) {
|
|
208
|
-
if ((!schema.isRequired && typeof obj === 'undefined') ||
|
|
209
|
-
(schema.isNullable && obj === null)) {
|
|
210
|
-
return {
|
|
211
|
-
valid: true
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
return await this.validate(alias, obj);
|
|
215
|
-
}
|
|
216
|
-
if (typeof alias !== 'object')
|
|
217
|
-
throw new Error('it is only possible to use a full schema schema definition as alias');
|
|
218
|
-
const schemaToMerge = { ...schema };
|
|
219
|
-
delete schemaToMerge.type;
|
|
220
|
-
delete schemaToMerge.schemaName;
|
|
221
|
-
const finalSchema = (0, deep_1.deepExtend)(alias, schemaToMerge);
|
|
222
|
-
return await this.validate(finalSchema, obj);
|
|
223
|
-
}
|
|
224
|
-
else if (schema.type === 'object') {
|
|
225
|
-
const preliminaryResult = await (0, validateObject_1.validateObject)(obj, schema, this);
|
|
226
|
-
if (!preliminaryResult.valid)
|
|
227
|
-
return preliminaryResult;
|
|
228
|
-
return await this.checkValidators(schema, obj);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
throw new Error("Coldn't understand the Schema provided");
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
exports.default = SchemaValidator;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateArray = void 0;
|
|
4
|
-
const validateArray = async (obj, schema, validator) => {
|
|
5
|
-
if (typeof obj === 'undefined' &&
|
|
6
|
-
typeof schema === 'object' &&
|
|
7
|
-
schema.isRequired === false) {
|
|
8
|
-
return {
|
|
9
|
-
valid: true
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
if (!Array.isArray(obj))
|
|
13
|
-
return {
|
|
14
|
-
valid: false,
|
|
15
|
-
errors: ['expected type array']
|
|
16
|
-
};
|
|
17
|
-
if (schema.preprocessor) {
|
|
18
|
-
const preprocessor = typeof schema.preprocessor === 'function'
|
|
19
|
-
? schema.preprocessor
|
|
20
|
-
: validator.preprocessors.get(schema.preprocessor);
|
|
21
|
-
if (typeof preprocessor !== 'function') {
|
|
22
|
-
throw new Error(`unknown preprocessor '${schema.preprocessor}'`);
|
|
23
|
-
}
|
|
24
|
-
for (let i = 0; i < obj.length; i++) {
|
|
25
|
-
obj[i] = await Promise.resolve(preprocessor(obj[i]));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (typeof schema.minLength === 'number' && obj.length < schema.minLength) {
|
|
29
|
-
return {
|
|
30
|
-
valid: false,
|
|
31
|
-
errors: [`expected to be at least ${schema.minLength} chars long`]
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
if (typeof schema.maxLength === 'number' && obj.length > schema.maxLength) {
|
|
35
|
-
return {
|
|
36
|
-
valid: false,
|
|
37
|
-
errors: [`expected to be at most ${schema.maxLength} chars long`]
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (typeof schema.ofType !== 'undefined') {
|
|
41
|
-
const results = await Promise.all(obj.map((i) => validator.validate(schema.ofType, i)));
|
|
42
|
-
const errors = results
|
|
43
|
-
.filter((r) => !r.valid)
|
|
44
|
-
.map((r) => r.errors)
|
|
45
|
-
.flat(Infinity);
|
|
46
|
-
if (errors.length) {
|
|
47
|
-
return {
|
|
48
|
-
valid: false,
|
|
49
|
-
errors
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
return {
|
|
53
|
-
valid: true
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
valid: true
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
exports.validateArray = validateArray;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateBoolean = void 0;
|
|
4
|
-
const validateBoolean = async (obj, schema, validator) => {
|
|
5
|
-
if (typeof obj === 'undefined' &&
|
|
6
|
-
typeof schema === 'object' &&
|
|
7
|
-
schema.isRequired === false) {
|
|
8
|
-
return {
|
|
9
|
-
valid: true
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
if (typeof obj !== 'boolean')
|
|
13
|
-
return {
|
|
14
|
-
valid: false,
|
|
15
|
-
errors: [`expected type boolean, but saw ${typeof obj}`]
|
|
16
|
-
};
|
|
17
|
-
if (typeof schema === 'boolean') {
|
|
18
|
-
return { valid: true };
|
|
19
|
-
}
|
|
20
|
-
const bool = obj;
|
|
21
|
-
if (typeof schema.equals === 'boolean') {
|
|
22
|
-
return schema.equals === bool
|
|
23
|
-
? { valid: true }
|
|
24
|
-
: {
|
|
25
|
-
valid: false,
|
|
26
|
-
errors: [`must be equal to ${schema.equals}`]
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
return {
|
|
30
|
-
valid: true
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
exports.validateBoolean = validateBoolean;
|