@cleverbrush/schema 0.0.3

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 ADDED
@@ -0,0 +1,279 @@
1
+ # Object Schema Validator
2
+
3
+ This package contains utilities to validate the JavaScript object's schema. There is only one class exported - `SchemaValidator`
4
+
5
+ ## Schema Types
6
+
7
+ There are several schema types available:
8
+
9
+ - object
10
+ - string
11
+ - number
12
+ - array
13
+ - function (_TBD_)
14
+
15
+ Schemas could be either described by shortcusts (string value from the list above) or by more detailed specification.
16
+
17
+ ## Schema Definitions
18
+
19
+ ### Common for all types
20
+
21
+ Any schema defined by object can contain the following fields:
22
+
23
+ - `type` - schema type (see the list above)
24
+ - `isRequired` - defines if `undefined` value is considered valid
25
+ - `isNullable` - defines if `null` value is considered valid
26
+ - `validators` - optional array of custom validation functions (see [Examples](#examples))
27
+
28
+ ### Number
29
+
30
+ `number` schema can be defined as follows:
31
+
32
+ import { SchemaValidator } from '@cleverbrush/schema';
33
+ const validator = new SchemaValidator();
34
+
35
+ // validates for integer number between 1 and 100
36
+ let result = await validator.validate(
37
+ {
38
+ type: "number",
39
+ isInteger: true,
40
+ min: 1,
41
+ max: 100,
42
+ },
43
+ 10
44
+ );
45
+
46
+ All fields available (apart of common fields for all schemas) are:
47
+
48
+ - `isInteger` - ensures that number is integer
49
+ - `ensureIsFinite` - ensures that nubmer is finite
50
+ - `ensureNotNaN` - ensures that number is not NaN
51
+ - `equals` - checks if a value is equal to provided number
52
+ - `min` - checks if a value is bigger or equal than a provided lower bound
53
+ - `max` - checks if a value is lower or equal than a provided upper bound
54
+
55
+ Also it can be defined either by shortcut:
56
+
57
+ import { SchemaValidator } from '@cleverbrush/schema';
58
+ const validator = new SchemaValidator();
59
+ let result = await validator.validate('number', 10);
60
+ // { valid: true }
61
+ result = await validator.validate('number', 'some string');
62
+ // { valid: false, errors: [ 'expected type number, but saw string' ] }
63
+
64
+ which is equal to:
65
+
66
+ import { SchemaValidator } from '@cleverbrush/schema';
67
+ const validator = new SchemaValidator();
68
+ let result = await validator.validate({
69
+ type: 'number',
70
+ isRequired: true,
71
+ isNullable: false,
72
+ ensureNotNaN: true,
73
+ ensureIsFinite: true
74
+ }, 0 / 0);
75
+ // { valid: false }
76
+
77
+ ### String
78
+
79
+ `string` schema can be defined as follows:
80
+
81
+ import { SchemaValidator } from '@cleverbrush/schema';
82
+ const validator = new SchemaValidator();
83
+
84
+ // validates for non empty string no longer than 100 chars
85
+ let result = await validator.validate(
86
+ {
87
+ type: "string",
88
+ minLength: 1,
89
+ maxLength: 100
90
+ },
91
+ "some value here"
92
+ );
93
+ // { valid: true }
94
+
95
+ All fields available (apart of common fields for all schemas) are:
96
+
97
+ - `equals` - checks if value is equal to provided string
98
+ - `minLength` - checks if value is at least `minLength` characters long
99
+ - `maxLength` - checks if value is at most `maxLength` characters long
100
+
101
+ Also it can be defined either by shortcut:
102
+
103
+ import { SchemaValidator } from '@cleverbrush/schema';
104
+ const validator = new SchemaValidator();
105
+ let result = await validator.validate('string', 'something');
106
+ // { valid: true }
107
+ result = await validator.validate('string', 10);
108
+ // { valid: false, errors: [ 'expected type string, but saw number' ] }
109
+
110
+ which is equal to:
111
+
112
+ import { SchemaValidator } from '@cleverbrush/schema';
113
+ const validator = new SchemaValidator();
114
+ let result = await validator.validate({
115
+ type: 'string',
116
+ isNullable: false,
117
+ isRequired: true
118
+ }, 1230);
119
+ // { valid: false }
120
+
121
+ ### Array
122
+
123
+ `array` schema can be defined as follows:
124
+
125
+ import { SchemaValidator } from '@cleverbrush/schema';
126
+ const validator = new SchemaValidator();
127
+
128
+ // validates for non empty string no longer than 100 chars
129
+ let result = await validator.validate(
130
+ {
131
+ type: "array",
132
+ minLength: 5,
133
+ maxLength: 10,
134
+ ofType: {
135
+ type: "number",
136
+ min: 1,
137
+ max: 10
138
+ }
139
+ },
140
+ [5, 6, 7, 8, 9]
141
+ );
142
+ // { valid: true }
143
+
144
+ All fields available (apart of common fields for all schemas) are:
145
+
146
+ - `ofType` - here you can pass the `schema` and all array elements will be checked to match this schema
147
+ - `minLength` - checks if array is at least `minLength` elements long
148
+ - `maxLength` - checks if array is at most `maxLength` elements long
149
+
150
+ Also it can be defined either by shortcut:
151
+
152
+ import { SchemaValidator } from '@cleverbrush/schema';
153
+ const validator = new SchemaValidator();
154
+ let result = await validator.validate('array', []);
155
+ // { valid: true }
156
+ result = await validator.validate('array', 10);
157
+ // { valid: false, errors: [ 'expected array' ] }
158
+
159
+ which is equal to:
160
+
161
+ import { SchemaValidator } from '@cleverbrush/schema';
162
+ const validator = new SchemaValidator();
163
+ let result = await validator.validate({
164
+ type: 'array'
165
+ }, 1230);
166
+ // { valid: false, errors: [ 'expected array' ] }
167
+
168
+ ### Object
169
+
170
+ `object` type allows to define a complex object schema. For example:
171
+
172
+ await validator.validate(
173
+ {
174
+ type: "object",
175
+ properties: {
176
+ id: "number",
177
+ name: {
178
+ type: "string",
179
+ minLength: 1,
180
+ maxLength: 100,
181
+ },
182
+ address: {
183
+ type: "object",
184
+ properties: {
185
+ city: "string",
186
+ street: {
187
+ type: "string",
188
+ isRequired: false,
189
+ },
190
+ },
191
+ },
192
+ },
193
+ },
194
+ {
195
+ id: 10,
196
+ name: "Andrew",
197
+ address: {
198
+ city: "Madrid",
199
+ },
200
+ }
201
+ );
202
+ // {valid: true}
203
+
204
+ All fields available are:
205
+
206
+ - `properties` - the list of properties, every property has corresponding schema definition (see example above).
207
+
208
+ ## Alternative schema
209
+
210
+ Everywhere you pass a `schema` object to the library, you may pass an array of `schema` objects which will validate the object to match at least one schema from this list.
211
+ For example, if you want to check that array is consisting either from number or from `{ name: string, value: number }` objects, you can do the following:
212
+
213
+ await validator.validate(
214
+ {
215
+ type: "array",
216
+ ofType: [
217
+ "number",
218
+ {
219
+ type: "object",
220
+ properties: {
221
+ name: "string",
222
+ value: "number",
223
+ },
224
+ },
225
+ ],
226
+ },
227
+ [
228
+ 10,
229
+ { name: "something", value: 1 },
230
+ 100,
231
+ { name: "another string", value: 1 },
232
+ ]
233
+ );
234
+ // {valid: true}
235
+
236
+ ## Named schemas
237
+
238
+ There is a possibility to register a schema, give it a name and then reuse it:
239
+
240
+ const validator = new SchemaValidator().addSchemaType("Address", {
241
+ properties: {
242
+ id: {
243
+ type: "number",
244
+ min: 1,
245
+ },
246
+ street: "string",
247
+ zip: "number",
248
+ },
249
+ });
250
+
251
+ await validator.validate(
252
+ {
253
+ type: "object",
254
+ properties: {
255
+ name: "string",
256
+ address1: "Address",
257
+ address2: "Address",
258
+ },
259
+ },
260
+ {
261
+ name: "Andrew",
262
+ address1: {
263
+ id: 1,
264
+ street: "some street",
265
+ zip: 12345,
266
+ },
267
+ address2: {
268
+ id: 2,
269
+ street: "some street 2",
270
+ zip: 3456,
271
+ },
272
+ }
273
+ );
274
+
275
+ // { valid: true }
276
+
277
+ ## Examples {#examples}
278
+
279
+ For Examples see unit tests in the schemaValidator.tests.ts
@@ -0,0 +1,75 @@
1
+ import SchemaValidator from './schemaValidator';
2
+ export declare type DefaultSchemaType = 'object' | 'function' | 'number' | 'string' | 'array';
3
+ export declare type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
4
+ export declare type DefaultPropertyDefinition = {
5
+ isRequired: boolean;
6
+ isNullable: boolean;
7
+ };
8
+ export declare type ValidationResultRaw = {
9
+ valid: boolean;
10
+ errors?: Array<string>;
11
+ };
12
+ export declare type ValidationResult = ValidationResultRaw | Promise<ValidationResultRaw>;
13
+ export declare type Validator<TObj> = (value: TObj) => ValidationResult;
14
+ export declare type SchemaDefintion<TObj> = {
15
+ type: DefaultSchemaType;
16
+ isRequired?: boolean;
17
+ isNullable?: boolean;
18
+ validators?: Array<Validator<TObj>>;
19
+ };
20
+ export declare type ObjectSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
21
+ type: 'object';
22
+ extends?: string;
23
+ properties?: Partial<{
24
+ [S in keyof T]: Schema<PropType<T, S>>;
25
+ }>;
26
+ };
27
+ export declare type ObjectSchemaDefinitionParam<T> = Omit<ObjectSchemaDefinition<T>, 'type'>;
28
+ export declare type ParamsValidators<TFunc extends (...args: any) => any> = {
29
+ [S in keyof Parameters<TFunc>]: SingleSchema<Parameters<TFunc>[S]>;
30
+ };
31
+ export declare type FunctionSchemaDefinition<T extends (...args: any) => any> = Omit<SchemaDefintion<T>, 'type'> & {
32
+ type: 'function';
33
+ params?: ParamsValidators<T>;
34
+ };
35
+ export declare type NumberSchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
36
+ type: 'number';
37
+ min?: number;
38
+ max?: number;
39
+ equals?: number;
40
+ isInteger?: boolean;
41
+ ensureNotNaN?: boolean;
42
+ ensureIsFinite?: boolean;
43
+ };
44
+ export declare type StringSchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
45
+ type: 'string';
46
+ equals?: string;
47
+ minLength?: number;
48
+ maxLength?: number;
49
+ };
50
+ export declare type ArraySchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 'type'> & {
51
+ type: 'array';
52
+ ofType?: Schema<any>;
53
+ minLength?: number;
54
+ maxLength?: number;
55
+ };
56
+ export declare type CompositeSchema<TObj> = TObj extends (...args: any) => any ? FunctionSchemaDefinition<TObj> : TObj extends number ? NumberSchemaDefinition<TObj> : TObj extends string ? StringSchemaDefinition<TObj> | 'string' : NumberSchemaDefinition<TObj> | StringSchemaDefinition<TObj> | ArraySchemaDefinition<TObj> | ObjectSchemaDefinition<TObj>;
57
+ export declare type SingleSchema<TObj = Record<string, never>> = number | string | DefaultSchemaType | CompositeSchema<TObj>;
58
+ export declare type Schema<TObj> = SingleSchema<TObj> | Array<SingleSchema<TObj>>;
59
+ export interface ISchemaActions<K, T extends keyof K> {
60
+ validate(value: any): Promise<ValidationResult>;
61
+ schema: PropType<K, T>;
62
+ }
63
+ export interface ISchemasProvider<T = Record<string, never>> {
64
+ schemas: {
65
+ [K in keyof T]: ISchemaActions<T, K>;
66
+ };
67
+ }
68
+ export interface ISchemaValidator<T = Record<string, never>> {
69
+ addSchemaType<K, L extends ObjectSchemaDefinitionParam<M>, M = any>(name: keyof K, schema: L): SchemaValidator<T & {
70
+ [key in keyof K]: L;
71
+ }>;
72
+ validate(schema: keyof T | DefaultSchemaType | Schema<any>, obj: any): Promise<ValidationResult>;
73
+ }
74
+ export { SchemaValidator };
75
+ export default SchemaValidator;
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
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;
@@ -0,0 +1,14 @@
1
+ import { ISchemasProvider, Schema, ISchemaActions, ObjectSchemaDefinitionParam, ValidationResult, ISchemaValidator, DefaultSchemaType } from './index';
2
+ export default class SchemaValidator<T = Record<string, never>> implements ISchemasProvider<T>, ISchemaValidator<T> {
3
+ private _schemasMap;
4
+ private _schemasCache;
5
+ addSchemaType<K, L extends ObjectSchemaDefinitionParam<M>, M = any>(name: keyof K, schema: L): SchemaValidator<T & {
6
+ [key in keyof K]: L;
7
+ }>;
8
+ get schemas(): {
9
+ [K in keyof T]: ISchemaActions<T, K>;
10
+ };
11
+ private validateDefaultType;
12
+ private checkValidators;
13
+ validate(schema: keyof T | DefaultSchemaType | Schema<any>, obj: any): Promise<ValidationResult>;
14
+ }
@@ -0,0 +1,170 @@
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 validateString_1 = require("./validators/validateString");
6
+ const validateArray_1 = require("./validators/validateArray");
7
+ const validateObject_1 = require("./validators/validateObject");
8
+ const defaultSchemaNames = ['string', 'number', 'date', 'array'];
9
+ const defaultSchemas = {
10
+ number: {
11
+ type: 'number',
12
+ isRequired: true,
13
+ isNullable: false,
14
+ ensureNotNaN: true,
15
+ ensureIsFinite: true
16
+ },
17
+ string: {
18
+ type: 'string',
19
+ isNullable: false,
20
+ isRequired: true
21
+ },
22
+ array: {
23
+ type: 'array'
24
+ },
25
+ object: {
26
+ type: 'object',
27
+ isNullable: false,
28
+ isRequired: true
29
+ }
30
+ };
31
+ const defaultSchemasValidationStrategies = {
32
+ number: (obj, schema, validator) => (0, validateNumber_1.validateNumber)(obj, schema, validator),
33
+ string: (obj, schema, validator) => (0, validateString_1.validateString)(obj, schema, validator),
34
+ array: (obj, schema, validator) => (0, validateArray_1.validateArray)(obj, schema, validator)
35
+ };
36
+ const isDefaultType = (name) => defaultSchemaNames.indexOf(name) !== -1;
37
+ class SchemaValidator {
38
+ _schemasMap = new Map();
39
+ _schemasCache = null;
40
+ addSchemaType(name, schema) {
41
+ if (typeof name !== 'string' || !name)
42
+ throw new Error('Name is required');
43
+ if (typeof schema !== 'object')
44
+ throw new Error('Object is required');
45
+ if (isDefaultType(name.toString()))
46
+ 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`);
47
+ if (this._schemasMap.has(name.toString())) {
48
+ throw new Error(`Schema "${name}" already exists`);
49
+ }
50
+ this._schemasMap.set(name.toString(), {
51
+ ...schema,
52
+ type: 'object'
53
+ });
54
+ this._schemasCache = null;
55
+ return this;
56
+ }
57
+ get schemas() {
58
+ if (this._schemasCache)
59
+ return this._schemasCache;
60
+ const res = {};
61
+ for (const key of this._schemasMap.keys()) {
62
+ res[key] = {
63
+ validate: (value) => this.validate(this._schemasMap.get(key), value),
64
+ schema: this._schemasMap.get(key)
65
+ };
66
+ }
67
+ this._schemasCache = res;
68
+ return this._schemasCache;
69
+ }
70
+ async validateDefaultType(name, value, mergeSchema) {
71
+ const strategy = defaultSchemasValidationStrategies[name];
72
+ let finalSchema = defaultSchemas[name];
73
+ if (strategy) {
74
+ if (typeof mergeSchema === 'object') {
75
+ finalSchema = (0, deep_1.deepExtend)(finalSchema, mergeSchema);
76
+ }
77
+ if (typeof mergeSchema === 'number') {
78
+ finalSchema = {
79
+ ...finalSchema,
80
+ equals: mergeSchema
81
+ };
82
+ mergeSchema;
83
+ }
84
+ let preliminaryResult = await strategy(value, finalSchema, this);
85
+ if (!preliminaryResult.valid)
86
+ return preliminaryResult;
87
+ preliminaryResult = await this.checkValidators(finalSchema, value);
88
+ return preliminaryResult;
89
+ }
90
+ throw new Error('not implemented');
91
+ }
92
+ async checkValidators(schema, value) {
93
+ if (Array.isArray(schema.validators)) {
94
+ const validatorsResults = await Promise.allSettled(schema.validators.map((v) => Promise.resolve(v(value))));
95
+ const rejections = validatorsResults
96
+ .filter((f) => f.status === 'rejected')
97
+ .map((f) => f.reason);
98
+ const errors = validatorsResults
99
+ .filter((f) => f.status === 'fulfilled' &&
100
+ typeof f.value !== 'boolean' &&
101
+ f.value.valid === false)
102
+ .map((f) => f.value)
103
+ .map((f) => f.errors);
104
+ if (rejections.length === 0 && errors.length === 0) {
105
+ return {
106
+ valid: true
107
+ };
108
+ }
109
+ return {
110
+ valid: false,
111
+ errors: [...rejections, ...errors]
112
+ };
113
+ }
114
+ return {
115
+ valid: true
116
+ };
117
+ }
118
+ async validate(schema, obj) {
119
+ if (!schema)
120
+ throw new Error('schemaName is required');
121
+ if (typeof schema === 'string') {
122
+ if (isDefaultType(schema)) {
123
+ return await this.validateDefaultType(schema, obj);
124
+ }
125
+ else if (typeof this.schemas[schema] !== 'undefined') {
126
+ const objSchema = (0, deep_1.deepExtend)(defaultSchemas.object, this.schemas[schema].schema);
127
+ const res = await (0, validateObject_1.validateObject)(obj, objSchema, this);
128
+ if (!res.valid)
129
+ return res;
130
+ return await this.checkValidators(objSchema, obj);
131
+ }
132
+ else {
133
+ return await this.validateDefaultType('string', obj, {
134
+ type: 'string',
135
+ equals: schema
136
+ });
137
+ }
138
+ }
139
+ if (Array.isArray(schema)) {
140
+ for (let i = 0; i < schema.length; i++) {
141
+ const res = await this.validate(schema[i], obj);
142
+ if (res.valid) {
143
+ return res;
144
+ }
145
+ }
146
+ return {
147
+ valid: false,
148
+ errors: ['object does not match any schema']
149
+ };
150
+ }
151
+ if (typeof schema === 'number') {
152
+ return await this.validateDefaultType('number', obj, schema);
153
+ }
154
+ if (typeof schema === 'object') {
155
+ if (typeof schema.type !== 'string')
156
+ throw new Error('Schema has no type');
157
+ if (isDefaultType(schema.type)) {
158
+ return await this.validateDefaultType(schema.type, obj, schema);
159
+ }
160
+ else if (schema.type === 'object') {
161
+ const preliminaryResult = await (0, validateObject_1.validateObject)(obj, schema, this);
162
+ if (!preliminaryResult.valid)
163
+ return preliminaryResult;
164
+ return await this.checkValidators(schema, obj);
165
+ }
166
+ }
167
+ throw new Error("Coldn't understand the Schema provided");
168
+ }
169
+ }
170
+ exports.default = SchemaValidator;
@@ -0,0 +1,2 @@
1
+ import { ValidationResult, ArraySchemaDefinition, ISchemaValidator } from '../index';
2
+ export declare const validateArray: (obj: any, schema: ArraySchemaDefinition<any>, validator: ISchemaValidator<any>) => Promise<ValidationResult>;
@@ -0,0 +1,49 @@
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 (typeof schema.minLength === 'number' && obj.length < schema.minLength) {
18
+ return {
19
+ valid: false,
20
+ errors: [`expected to be at least ${schema.minLength} chars long`]
21
+ };
22
+ }
23
+ if (typeof schema.maxLength === 'number' && obj.length > schema.maxLength) {
24
+ return {
25
+ valid: false,
26
+ errors: [`expected to be at most ${schema.maxLength} chars long`]
27
+ };
28
+ }
29
+ if (typeof schema.ofType !== 'undefined') {
30
+ const results = await Promise.all(obj.map((i) => validator.validate(schema.ofType, i)));
31
+ const errors = results
32
+ .filter((r) => !r.valid)
33
+ .map((r) => r.errors)
34
+ .flat(Infinity);
35
+ if (errors.length) {
36
+ return {
37
+ valid: false,
38
+ errors
39
+ };
40
+ }
41
+ return {
42
+ valid: true
43
+ };
44
+ }
45
+ return {
46
+ valid: true
47
+ };
48
+ };
49
+ exports.validateArray = validateArray;
@@ -0,0 +1,2 @@
1
+ import { ValidationResult, NumberSchemaDefinition, ISchemaValidator } from '../index';
2
+ export declare const validateNumber: (obj: any, schema: NumberSchemaDefinition<any>, validator: ISchemaValidator<any>) => Promise<ValidationResult>;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateNumber = void 0;
4
+ const validateNumber = 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 !== 'number')
13
+ return {
14
+ valid: false,
15
+ errors: [`expected type number, but saw ${typeof obj}`]
16
+ };
17
+ if (typeof schema === 'number') {
18
+ return obj === schema
19
+ ? { valid: true }
20
+ : {
21
+ valid: false,
22
+ errors: [`should be equal to ${schema}`]
23
+ };
24
+ }
25
+ const num = obj;
26
+ if (schema.ensureNotNaN && Number.isNaN(num)) {
27
+ return {
28
+ valid: false,
29
+ errors: ['is not expected to be NaN']
30
+ };
31
+ }
32
+ if (schema.ensureIsFinite &&
33
+ !Number.isFinite(num) &&
34
+ schema.ensureNotNaN &&
35
+ !Number.isNaN(num)) {
36
+ return {
37
+ valid: false,
38
+ errors: ['is expected to be a finite number']
39
+ };
40
+ }
41
+ if (typeof schema.equals !== 'undefined' && num !== schema.equals) {
42
+ return {
43
+ valid: false,
44
+ errors: [`expected to be equal to ${schema.equals}`]
45
+ };
46
+ }
47
+ if (typeof schema.min !== 'undefined') {
48
+ if (typeof schema.min !== 'number')
49
+ throw new Error('min constraint should be a number');
50
+ if (num < schema.min)
51
+ return {
52
+ valid: false,
53
+ errors: [`expected to be at least ${schema.min}`]
54
+ };
55
+ }
56
+ if (typeof schema.max !== 'undefined') {
57
+ if (typeof schema.max !== 'number')
58
+ throw new Error('max constraint should be a number');
59
+ if (num > schema.max)
60
+ return {
61
+ valid: false,
62
+ errors: [`expected to be no more than ${schema.max}`]
63
+ };
64
+ }
65
+ return {
66
+ valid: true
67
+ };
68
+ };
69
+ exports.validateNumber = validateNumber;
@@ -0,0 +1,2 @@
1
+ import { ValidationResult, ObjectSchemaDefinition, ISchemaValidator } from '../index';
2
+ export declare const validateObject: (obj: any, schema: ObjectSchemaDefinition<any>, validator: ISchemaValidator<any>) => Promise<ValidationResult>;