@cleverbrush/schema 0.0.17 → 1.0.0-beta.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.
Files changed (75) hide show
  1. package/README.md +213 -163
  2. package/dist/builders/AliasSchemaBuilder.d.ts +14 -0
  3. package/dist/builders/AliasSchemaBuilder.js +91 -0
  4. package/dist/builders/ArraySchemaBuilder.d.ts +15 -0
  5. package/dist/builders/ArraySchemaBuilder.js +141 -0
  6. package/dist/builders/BooleanSchemaBuilder.d.ts +31 -0
  7. package/dist/builders/BooleanSchemaBuilder.js +90 -0
  8. package/dist/builders/FunctionSchemaBuilder.d.ts +25 -0
  9. package/dist/builders/FunctionSchemaBuilder.js +66 -0
  10. package/dist/builders/NumberSchemaBuilder.d.ts +61 -0
  11. package/dist/builders/NumberSchemaBuilder.js +206 -0
  12. package/dist/builders/ObjectSchemaBuilder.d.ts +83 -0
  13. package/dist/builders/ObjectSchemaBuilder.js +344 -0
  14. package/dist/builders/SchemaBuilder.d.ts +36 -0
  15. package/dist/builders/SchemaBuilder.js +88 -0
  16. package/dist/builders/StringSchemaBuilder.d.ts +14 -0
  17. package/dist/builders/StringSchemaBuilder.js +140 -0
  18. package/dist/builders/UnionSchemaBuilder.d.ts +10 -0
  19. package/dist/builders/UnionSchemaBuilder.js +100 -0
  20. package/dist/defaultSchemas.d.ts +4 -0
  21. package/dist/defaultSchemas.js +45 -0
  22. package/dist/index.d.ts +38 -90
  23. package/dist/index.js +30 -4
  24. package/dist/schema.d.ts +242 -0
  25. package/dist/schema.js +2 -0
  26. package/dist/schemaRegistry.d.ts +54 -0
  27. package/dist/schemaRegistry.js +301 -0
  28. package/dist/validators/validateArray.d.ts +3 -2
  29. package/dist/validators/validateBoolean.d.ts +2 -2
  30. package/dist/validators/validateBoolean.js +1 -4
  31. package/dist/validators/validateFunction.d.ts +2 -0
  32. package/dist/validators/validateFunction.js +21 -0
  33. package/dist/validators/validateNumber.d.ts +2 -2
  34. package/dist/validators/validateNumber.js +1 -1
  35. package/dist/validators/validateObject.d.ts +3 -2
  36. package/dist/validators/validateObject.js +33 -11
  37. package/dist/validators/validateString.d.ts +2 -2
  38. package/dist/validators/validateString.js +1 -1
  39. package/dist/validators/validateUnion.d.ts +3 -0
  40. package/dist/validators/validateUnion.js +30 -0
  41. package/package.json +3 -3
  42. package/src/builders/AliasSchemaBuilder.test.ts +124 -0
  43. package/src/builders/AliasSchemaBuilder.ts +250 -0
  44. package/src/builders/ArraySchemaBuilder.test.ts +270 -0
  45. package/src/builders/ArraySchemaBuilder.ts +381 -0
  46. package/src/builders/BooleanSchemaBuilder.test.ts +196 -0
  47. package/src/builders/BooleanSchemaBuilder.ts +155 -0
  48. package/src/builders/FunctionSchemaBuilder.test.ts +134 -0
  49. package/src/builders/FunctionSchemaBuilder.ts +109 -0
  50. package/src/builders/NumberSchemaBuilder.test.ts +493 -0
  51. package/src/builders/NumberSchemaBuilder.ts +789 -0
  52. package/src/builders/ObjectSchemaBuilder.test.ts +657 -0
  53. package/src/builders/ObjectSchemaBuilder.ts +794 -0
  54. package/src/builders/SchemaBuilder.test.ts +73 -0
  55. package/src/builders/SchemaBuilder.ts +135 -0
  56. package/src/builders/StringSchemaBuilder.test.ts +318 -0
  57. package/src/builders/StringSchemaBuilder.ts +392 -0
  58. package/src/builders/UnionSchemaBuilder.test.ts +162 -0
  59. package/src/builders/UnionSchemaBuilder.ts +159 -0
  60. package/src/defaultSchemas.ts +44 -0
  61. package/src/index.ts +70 -190
  62. package/src/schema.ts +922 -0
  63. package/src/schemaRegistry.builders.test.ts +1438 -0
  64. package/src/{schemaValidator.test.ts → schemaRegistry.test.ts} +561 -185
  65. package/src/schemaRegistry.ts +532 -0
  66. package/src/validators/validateArray.ts +4 -7
  67. package/src/validators/validateBoolean.ts +2 -11
  68. package/src/validators/validateFunction.ts +25 -0
  69. package/src/validators/validateNumber.ts +2 -7
  70. package/src/validators/validateObject.ts +32 -21
  71. package/src/validators/validateString.ts +2 -7
  72. package/src/validators/validateUnion.ts +36 -0
  73. package/dist/schemaValidator.d.ts +0 -16
  74. package/dist/schemaValidator.js +0 -234
  75. package/src/schemaValidator.ts +0 -367
@@ -0,0 +1,532 @@
1
+ import { ISchemaRegistry as ISchemaRegistry, Unfold } from './index.js';
2
+ import { validateNumber } from './validators/validateNumber.js';
3
+ import { validateBoolean } from './validators/validateBoolean.js';
4
+ import { validateString } from './validators/validateString.js';
5
+ import { validateArray } from './validators/validateArray.js';
6
+ import { validateObject } from './validators/validateObject.js';
7
+ import { validateUnion } from './validators/validateUnion.js';
8
+ import { validateFunction } from './validators/validateFunction.js';
9
+ import {
10
+ ArraySchema,
11
+ BooleanSchema,
12
+ DefaultSchemaType,
13
+ NumberSchema,
14
+ ObjectSchema,
15
+ Schema,
16
+ ReduceSchemaBuilder,
17
+ SchemaSpecification,
18
+ StringSchema,
19
+ ValidationResult,
20
+ ValidationResultRaw,
21
+ InferType,
22
+ ExpandSchemaBuilder,
23
+ FunctionSchema
24
+ } from './schema.js';
25
+
26
+ import { number } from './builders/NumberSchemaBuilder.js';
27
+ import { union } from './builders/UnionSchemaBuilder.js';
28
+ import { object } from './builders/ObjectSchemaBuilder.js';
29
+ import { string } from './builders/StringSchemaBuilder.js';
30
+ import { boolean } from './builders/BooleanSchemaBuilder.js';
31
+ import { array } from './builders/ArraySchemaBuilder.js';
32
+ import {
33
+ alias,
34
+ externalAlias,
35
+ IAliasSchemaBuilder
36
+ } from './builders/AliasSchemaBuilder.js';
37
+ import { func } from './builders/FunctionSchemaBuilder.js';
38
+ import { defaultSchemas } from './defaultSchemas.js';
39
+ import { ISchemaBuilder, SchemaBuilder } from './builders/SchemaBuilder.js';
40
+
41
+ const defaultSchemaNames = ['string', 'boolean', 'number', 'array', 'function'];
42
+
43
+ const defaultSchemasValidationStrategies = {
44
+ number: (obj: any, schema: NumberSchema): Promise<ValidationResult> =>
45
+ validateNumber(obj, schema),
46
+ boolean: (obj: any, schema: BooleanSchema): Promise<ValidationResult> =>
47
+ validateBoolean(obj, schema),
48
+ string: (obj: any, schema: StringSchema): Promise<ValidationResult> =>
49
+ validateString(obj, schema),
50
+ array: (
51
+ obj: any,
52
+ schema: ArraySchema<any>,
53
+ validator: SchemaRegistry<any>
54
+ ): Promise<ValidationResult> => validateArray(obj, schema, validator),
55
+ function: (obj: any, schema: FunctionSchema): Promise<ValidationResult> =>
56
+ validateFunction(obj, schema)
57
+ };
58
+
59
+ const isDefaultType = (name: string): boolean =>
60
+ defaultSchemaNames.indexOf(name) !== -1;
61
+
62
+ export default class SchemaRegistry<T extends Record<string, Schema> = {}>
63
+ implements ISchemaRegistry<T>
64
+ {
65
+ private _schemasMap = new Map<string, Schema>();
66
+ private _schemasCache: Unfold<T> = null;
67
+ private _preprocessorsMap = new Map<
68
+ string,
69
+ (value: unknown) => unknown | Promise<unknown> | undefined
70
+ >();
71
+
72
+ public get preprocessors(): Map<string, (value: unknown) => unknown> {
73
+ return this._preprocessorsMap;
74
+ }
75
+
76
+ public addPreprocessor(
77
+ name: string,
78
+ preprocessor: (value: unknown) => unknown | Promise<unknown>
79
+ ): SchemaRegistry<T> {
80
+ if (this._preprocessorsMap.has(name))
81
+ throw new Error(`Preprocessor '${name}' is already registered`);
82
+ if (typeof preprocessor !== 'function') {
83
+ throw new Error('preprocessor must be a function');
84
+ }
85
+ this._preprocessorsMap.set(name, preprocessor);
86
+ return this;
87
+ }
88
+
89
+ public addSchemaFrom<
90
+ TOldName extends keyof T,
91
+ TName extends string,
92
+ TParam extends
93
+ | Record<string, any>
94
+ | ((params: {
95
+ schema: ExpandSchemaBuilder<T[TOldName]>;
96
+ boolean: typeof boolean;
97
+ func: typeof func;
98
+ array: typeof array;
99
+ string: typeof string;
100
+ number: typeof number;
101
+ union: typeof union;
102
+ object: typeof object;
103
+ alias: <
104
+ TSchemaName extends keyof T,
105
+ TCompiledType = InferType<
106
+ ExpandSchemaBuilder<T[TSchemaName]>
107
+ >
108
+ >(
109
+ schemaName: TSchemaName
110
+ ) => IAliasSchemaBuilder<
111
+ TSchemaName,
112
+ true,
113
+ false,
114
+ {
115
+ [k in keyof T]: TSchemaName extends k ? T[k] : never;
116
+ },
117
+ TCompiledType
118
+ >;
119
+ }) => TSchema),
120
+ TSchema extends Schema | ISchemaBuilder
121
+ >(
122
+ oldName: TOldName,
123
+ name: TName,
124
+ param: TParam
125
+ ): SchemaRegistry<
126
+ T & {
127
+ [key in TName]: TParam extends (...args: any[]) => any
128
+ ? ReduceSchemaBuilder<ReturnType<TParam>>
129
+ : TParam;
130
+ }
131
+ > {
132
+ if (!this._schemasMap.has(oldName.toString())) {
133
+ throw new Error(`unknown schema name ${oldName.toString()}`);
134
+ }
135
+
136
+ const oldSchema = this._schemasMap.get(oldName.toString());
137
+
138
+ const schema =
139
+ typeof param === 'function'
140
+ ? param({
141
+ schema: oldSchema,
142
+ alias,
143
+ array,
144
+ boolean,
145
+ func,
146
+ number,
147
+ object,
148
+ string,
149
+ union
150
+ })
151
+ : param;
152
+
153
+ if (Array.isArray(schema)) {
154
+ this._schemasMap.set(name.toString(), schema as Schema);
155
+ this._schemasCache = null;
156
+ return this as any;
157
+ }
158
+
159
+ if (typeof schema !== 'object')
160
+ throw new Error('Array or Object is required');
161
+ this._schemasMap.set(name.toString(), {
162
+ ...(schema instanceof SchemaBuilder
163
+ ? schema._schema
164
+ : (schema as any))
165
+ } as any as Schema);
166
+
167
+ this._schemasCache = null;
168
+ return this as any;
169
+ }
170
+
171
+ public addSchema<
172
+ TName extends string,
173
+ TParam extends
174
+ | Record<string, any>
175
+ | ((params: {
176
+ boolean: typeof boolean;
177
+ array: typeof array;
178
+ string: typeof string;
179
+ number: typeof number;
180
+ union: typeof union;
181
+ object: typeof object;
182
+ func: typeof func;
183
+ alias: <
184
+ TSchemaName extends keyof T,
185
+ TCompiledType = InferType<
186
+ ExpandSchemaBuilder<T[TSchemaName]>
187
+ >
188
+ >(
189
+ schemaName: TSchemaName
190
+ ) => IAliasSchemaBuilder<
191
+ TSchemaName,
192
+ true,
193
+ false,
194
+ {
195
+ [k in keyof T]: TSchemaName extends k ? T[k] : never;
196
+ },
197
+ TCompiledType
198
+ >;
199
+ external: <
200
+ TRegistryKeys extends Record<string, any>,
201
+ TSchemaName extends keyof TRegistryKeys,
202
+ TCompiledType = InferType<
203
+ ExpandSchemaBuilder<TRegistryKeys[TSchemaName]>
204
+ >
205
+ >(
206
+ registry: ISchemaRegistry<TRegistryKeys>,
207
+ schemaName: TSchemaName
208
+ ) => IAliasSchemaBuilder<
209
+ TSchemaName,
210
+ true,
211
+ false,
212
+ {
213
+ [k in keyof TRegistryKeys]: TSchemaName extends k
214
+ ? TRegistryKeys[k]
215
+ : never;
216
+ },
217
+ TCompiledType
218
+ >;
219
+ }) => TSchema),
220
+ TSchema extends Schema | ISchemaBuilder
221
+ >(
222
+ name: TName,
223
+ param: TParam
224
+ ): SchemaRegistry<
225
+ T & {
226
+ [key in TName]: TParam extends (...args: any[]) => any
227
+ ? ReduceSchemaBuilder<ReturnType<TParam>>
228
+ : TParam;
229
+ }
230
+ > {
231
+ if (typeof name !== 'string' || !name)
232
+ throw new Error('Name is required');
233
+
234
+ if (isDefaultType(name.toString()))
235
+ throw new Error(
236
+ `You can't add a schema named "${name}" because it's a name of a default schema, please consider another name to be used`
237
+ );
238
+ if (this._schemasMap.has(name.toString())) {
239
+ throw new Error(`Schema "${name}" already exists`);
240
+ }
241
+
242
+ const schema =
243
+ typeof param === 'function'
244
+ ? param({
245
+ alias,
246
+ external: externalAlias,
247
+ array,
248
+ boolean,
249
+ number,
250
+ object,
251
+ string,
252
+ union,
253
+ func
254
+ })
255
+ : param;
256
+
257
+ if (Array.isArray(schema)) {
258
+ this._schemasMap.set(name.toString(), schema as Schema);
259
+ this._schemasCache = null;
260
+ return this as any;
261
+ }
262
+
263
+ if (typeof schema !== 'object')
264
+ throw new Error('Array or Object is required');
265
+ this._schemasMap.set(
266
+ name.toString(),
267
+ schema instanceof SchemaBuilder ? schema.clone() : schema
268
+ );
269
+
270
+ this._schemasCache = null;
271
+ return this as any;
272
+ }
273
+
274
+ public get schemas(): Unfold<T> {
275
+ if (this._schemasCache) return this._schemasCache;
276
+ const res = {};
277
+ for (const key of this._schemasMap.keys()) {
278
+ const parts = key.split('.');
279
+ let curr = res;
280
+ for (let i = 0; i < parts.length; i++) {
281
+ if (i === parts.length - 1) {
282
+ curr[parts[i]] = {
283
+ validate: async (value: any): Promise<any> => {
284
+ const result = await this.validate(
285
+ this._schemasMap.get(key),
286
+ value
287
+ );
288
+ if (!result.valid) {
289
+ return result;
290
+ }
291
+ return {
292
+ ...result,
293
+ object: value
294
+ };
295
+ },
296
+ schema: this._schemasMap.get(key)
297
+ };
298
+ } else {
299
+ if (typeof curr[parts[i]] === 'undefined') {
300
+ curr[parts[i]] = {};
301
+ }
302
+ }
303
+ curr = curr[parts[i]];
304
+ }
305
+ }
306
+ this._schemasCache = res as Unfold<T>;
307
+ return this._schemasCache;
308
+ }
309
+
310
+ private async validateDefaultType(
311
+ name: DefaultSchemaType,
312
+ value: any,
313
+ mergeSchema?: Schema
314
+ ): Promise<ValidationResult> {
315
+ const strategy = defaultSchemasValidationStrategies[name] as (
316
+ obj: any,
317
+ schema: Schema,
318
+ validator: SchemaRegistry<any>
319
+ ) => ValidationResult;
320
+ let finalSchema = defaultSchemas[name] as SchemaSpecification;
321
+ if (strategy) {
322
+ if (typeof mergeSchema === 'object' && mergeSchema) {
323
+ finalSchema = Object.assign({}, finalSchema, mergeSchema);
324
+ }
325
+ if (typeof mergeSchema === 'number') {
326
+ finalSchema = {
327
+ ...finalSchema,
328
+ equals: mergeSchema
329
+ } as NumberSchema;
330
+ mergeSchema;
331
+ }
332
+
333
+ let preliminaryResult = await strategy(
334
+ value,
335
+ finalSchema,
336
+ this as any
337
+ );
338
+ if (!preliminaryResult.valid) return preliminaryResult;
339
+
340
+ preliminaryResult = await this.checkValidators(finalSchema, value);
341
+
342
+ return preliminaryResult;
343
+ }
344
+ throw new Error('not implemented');
345
+ }
346
+
347
+ private async checkValidators(
348
+ schema: SchemaSpecification,
349
+ value: any
350
+ ): Promise<ValidationResult> {
351
+ if (!schema.isRequired && typeof value === 'undefined') {
352
+ return {
353
+ valid: true
354
+ };
355
+ }
356
+ if (Array.isArray(schema.validators)) {
357
+ const validatorsResults = await Promise.allSettled(
358
+ schema.validators.map((v) => Promise.resolve(v(value)))
359
+ );
360
+ const rejections = validatorsResults
361
+ .filter((f) => f.status === 'rejected')
362
+ .map((f: PromiseRejectedResult) => f.reason);
363
+ const errors = validatorsResults
364
+ .filter(
365
+ (f) =>
366
+ f.status === 'fulfilled' &&
367
+ typeof f.value !== 'boolean' &&
368
+ f.value.valid === false
369
+ )
370
+ .map(
371
+ (f: PromiseFulfilledResult<ValidationResultRaw>) => f.value
372
+ )
373
+ .map((f: ValidationResultRaw) => f.errors);
374
+
375
+ if (rejections.length === 0 && errors.length === 0) {
376
+ return {
377
+ valid: true
378
+ };
379
+ }
380
+ return {
381
+ valid: false,
382
+ errors: [...rejections, ...errors]
383
+ };
384
+ }
385
+ return {
386
+ valid: true
387
+ };
388
+ }
389
+
390
+ public async validate(
391
+ schemaToValidate: keyof T | Schema,
392
+ obj: any
393
+ ): Promise<ValidationResult> {
394
+ if (!schemaToValidate) throw new Error('schemaName is required');
395
+ const schema =
396
+ schemaToValidate instanceof SchemaBuilder
397
+ ? schemaToValidate._schema
398
+ : schemaToValidate;
399
+ if (typeof schema === 'string') {
400
+ if (isDefaultType(schema)) {
401
+ return await this.validateDefaultType(
402
+ schema as DefaultSchemaType,
403
+ obj
404
+ );
405
+ } else if (typeof this._schemasMap.get(schema) !== 'undefined') {
406
+ if (Array.isArray(this._schemasMap.get(schema))) {
407
+ return this.validate(this._schemasMap.get(schema), obj);
408
+ }
409
+ const objSchema = Object.assign(
410
+ {},
411
+ defaultSchemas.object,
412
+ this._schemasMap.get(schema)
413
+ ) as ObjectSchema;
414
+ const res = await validateObject(
415
+ obj,
416
+ objSchema as any,
417
+ this as any
418
+ );
419
+ if (!res.valid) return res;
420
+ return await this.checkValidators(objSchema, obj);
421
+ } else {
422
+ return await this.validateDefaultType('string', obj, {
423
+ type: 'string',
424
+ equals: schema
425
+ });
426
+ }
427
+ }
428
+
429
+ if (Array.isArray(schema)) {
430
+ for (let i = 0; i < schema.length; i++) {
431
+ const res = await this.validate(schema[i], obj);
432
+ if (res.valid) {
433
+ return res;
434
+ }
435
+ }
436
+ return {
437
+ valid: false,
438
+ errors: ['object does not match any schema']
439
+ };
440
+ }
441
+
442
+ if (typeof schema === 'number') {
443
+ return await this.validateDefaultType('number', obj, schema);
444
+ }
445
+
446
+ if (typeof schema === 'object') {
447
+ const spec = schema as SchemaSpecification;
448
+ if (typeof spec.type !== 'string')
449
+ throw new Error('Schema has no type');
450
+
451
+ if (isDefaultType(spec.type)) {
452
+ return await this.validateDefaultType(
453
+ spec.type as DefaultSchemaType,
454
+ obj,
455
+ schema
456
+ );
457
+ } else if (spec.type === 'alias') {
458
+ if (spec.isRequired === false && typeof obj === 'undefined') {
459
+ return {
460
+ valid: true
461
+ };
462
+ }
463
+ if (spec.isNullable === true && obj === null) {
464
+ return {
465
+ valid: true
466
+ };
467
+ }
468
+
469
+ const registry = (spec.externalRegistry ||
470
+ this) as ISchemaRegistry<any>;
471
+ const alias = (registry as any)._schemasMap.get(
472
+ spec.schemaName
473
+ );
474
+ if (typeof alias === 'undefined') {
475
+ throw new Error(
476
+ `Unknown schema alias - ${spec.schemaName}`
477
+ );
478
+ }
479
+ if (Array.isArray(alias)) {
480
+ if (
481
+ (!spec.isRequired && typeof obj === 'undefined') ||
482
+ (spec.isNullable && obj === null)
483
+ ) {
484
+ return {
485
+ valid: true
486
+ };
487
+ }
488
+ return await (registry as any).validate(alias as any, obj);
489
+ }
490
+ if (typeof alias !== 'object')
491
+ throw new Error(
492
+ 'it is only possible to use a full schema schema definition as alias'
493
+ );
494
+
495
+ let schemaToValidate = alias;
496
+
497
+ if (alias instanceof SchemaBuilder) {
498
+ if (typeof schema.isRequired === 'boolean') {
499
+ schemaToValidate = (schemaToValidate as any)[
500
+ schema.isRequired ? 'required' : 'optional'
501
+ ]();
502
+ }
503
+ if (typeof schema.isNullable === 'boolean') {
504
+ schemaToValidate = (schemaToValidate as any)[
505
+ schema.isNullable ? 'nullable' : 'notNullable'
506
+ ]();
507
+ }
508
+ }
509
+
510
+ return await (registry as any).validate(schemaToValidate, obj);
511
+ } else if (spec.type === 'union') {
512
+ return await validateUnion(obj, spec, this as any);
513
+ } else if (spec.type === 'object') {
514
+ const preliminaryResult = await validateObject(
515
+ obj,
516
+ schema as ObjectSchema<any>,
517
+ this as any
518
+ );
519
+ if (!preliminaryResult.valid) return preliminaryResult;
520
+
521
+ return await this.checkValidators(
522
+ schema as SchemaSpecification,
523
+ obj
524
+ );
525
+ } else if (spec.type === 'function') {
526
+ return await validateFunction(obj, spec);
527
+ }
528
+ }
529
+
530
+ throw new Error("Couldn't understand the Schema provided");
531
+ }
532
+ }
@@ -1,13 +1,10 @@
1
- import {
2
- ValidationResult,
3
- ArraySchemaDefinition,
4
- ISchemaValidator
5
- } from '../index';
1
+ import { ArraySchema, ValidationResult } from '../schema.js';
2
+ import SchemaRegistry from '../schemaRegistry.js';
6
3
 
7
4
  export const validateArray = async (
8
5
  obj: any,
9
- schema: ArraySchemaDefinition<any>,
10
- validator: ISchemaValidator<any>
6
+ schema: ArraySchema<any>,
7
+ validator: SchemaRegistry<any>
11
8
  ): Promise<ValidationResult> => {
12
9
  if (
13
10
  typeof obj === 'undefined' &&
@@ -1,13 +1,8 @@
1
- import {
2
- ValidationResult,
3
- BooleanSchemaDefinition,
4
- ISchemaValidator
5
- } from '../index';
1
+ import { BooleanSchema, ValidationResult } from '../schema.js';
6
2
 
7
3
  export const validateBoolean = async (
8
4
  obj: any,
9
- schema: BooleanSchemaDefinition<any>,
10
- validator: ISchemaValidator<any>
5
+ schema: BooleanSchema
11
6
  ): Promise<ValidationResult> => {
12
7
  if (
13
8
  typeof obj === 'undefined' &&
@@ -24,10 +19,6 @@ export const validateBoolean = async (
24
19
  errors: [`expected type boolean, but saw ${typeof obj}`]
25
20
  };
26
21
 
27
- if (typeof schema === 'boolean') {
28
- return { valid: true };
29
- }
30
-
31
22
  const bool = obj as boolean;
32
23
 
33
24
  if (typeof schema.equals === 'boolean') {
@@ -0,0 +1,25 @@
1
+ import { FunctionSchema, ValidationResult } from '../schema.js';
2
+
3
+ export const validateFunction = async (
4
+ obj: any,
5
+ schema: FunctionSchema
6
+ ): Promise<ValidationResult> => {
7
+ if (
8
+ typeof obj === 'undefined' &&
9
+ typeof schema === 'object' &&
10
+ schema.isRequired === false
11
+ ) {
12
+ return {
13
+ valid: true
14
+ };
15
+ }
16
+ if (typeof obj !== 'function')
17
+ return {
18
+ valid: false,
19
+ errors: [`expected type function, but saw ${typeof obj}`]
20
+ };
21
+
22
+ return {
23
+ valid: true
24
+ };
25
+ };
@@ -1,13 +1,8 @@
1
- import {
2
- ValidationResult,
3
- NumberSchemaDefinition,
4
- ISchemaValidator
5
- } from '../index';
1
+ import { NumberSchema, ValidationResult } from '../schema.js';
6
2
 
7
3
  export const validateNumber = async (
8
4
  obj: any,
9
- schema: NumberSchemaDefinition<any>,
10
- validator: ISchemaValidator<any>
5
+ schema: NumberSchema
11
6
  ): Promise<ValidationResult> => {
12
7
  if (
13
8
  typeof obj === 'undefined' &&