@cleverbrush/schema 1.0.0-beta.4 → 1.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.
Files changed (76) hide show
  1. package/README.md +118 -320
  2. package/dist/builders/AnySchemaBuilder.d.ts +76 -0
  3. package/dist/builders/AnySchemaBuilder.js +112 -0
  4. package/dist/builders/ArraySchemaBuilder.d.ts +112 -14
  5. package/dist/builders/ArraySchemaBuilder.js +254 -111
  6. package/dist/builders/BooleanSchemaBuilder.d.ts +69 -29
  7. package/dist/builders/BooleanSchemaBuilder.js +134 -74
  8. package/dist/builders/DateSchemaBuilder.d.ts +177 -0
  9. package/dist/builders/DateSchemaBuilder.js +433 -0
  10. package/dist/builders/FunctionSchemaBuilder.d.ts +59 -23
  11. package/dist/builders/FunctionSchemaBuilder.js +103 -56
  12. package/dist/builders/NumberSchemaBuilder.d.ts +159 -59
  13. package/dist/builders/NumberSchemaBuilder.js +345 -165
  14. package/dist/builders/ObjectSchemaBuilder.d.ts +357 -81
  15. package/dist/builders/ObjectSchemaBuilder.js +519 -283
  16. package/dist/builders/SchemaBuilder.d.ts +158 -34
  17. package/dist/builders/SchemaBuilder.js +258 -71
  18. package/dist/builders/StringSchemaBuilder.d.ts +138 -13
  19. package/dist/builders/StringSchemaBuilder.js +261 -115
  20. package/dist/builders/UnionSchemaBuilder.d.ts +129 -9
  21. package/dist/builders/UnionSchemaBuilder.js +196 -75
  22. package/dist/index.d.ts +20 -40
  23. package/dist/index.js +19 -32
  24. package/dist/utils/transaction.d.ts +46 -0
  25. package/dist/utils/transaction.js +178 -0
  26. package/package.json +27 -14
  27. package/dist/defaultSchemas.d.ts +0 -4
  28. package/dist/defaultSchemas.js +0 -45
  29. package/dist/schema.d.ts +0 -230
  30. package/dist/schema.js +0 -2
  31. package/dist/schemaRegistry.d.ts +0 -49
  32. package/dist/schemaRegistry.js +0 -278
  33. package/dist/validators/validateArray.d.ts +0 -3
  34. package/dist/validators/validateArray.js +0 -60
  35. package/dist/validators/validateBoolean.d.ts +0 -2
  36. package/dist/validators/validateBoolean.js +0 -30
  37. package/dist/validators/validateFunction.d.ts +0 -2
  38. package/dist/validators/validateFunction.js +0 -21
  39. package/dist/validators/validateNumber.d.ts +0 -2
  40. package/dist/validators/validateNumber.js +0 -69
  41. package/dist/validators/validateObject.d.ts +0 -3
  42. package/dist/validators/validateObject.js +0 -95
  43. package/dist/validators/validateString.d.ts +0 -2
  44. package/dist/validators/validateString.js +0 -50
  45. package/dist/validators/validateUnion.d.ts +0 -3
  46. package/dist/validators/validateUnion.js +0 -30
  47. package/src/builders/ArraySchemaBuilder.test.ts +0 -270
  48. package/src/builders/ArraySchemaBuilder.ts +0 -381
  49. package/src/builders/BooleanSchemaBuilder.test.ts +0 -196
  50. package/src/builders/BooleanSchemaBuilder.ts +0 -155
  51. package/src/builders/FunctionSchemaBuilder.test.ts +0 -134
  52. package/src/builders/FunctionSchemaBuilder.ts +0 -109
  53. package/src/builders/NumberSchemaBuilder.test.ts +0 -493
  54. package/src/builders/NumberSchemaBuilder.ts +0 -789
  55. package/src/builders/ObjectSchemaBuilder.test.ts +0 -657
  56. package/src/builders/ObjectSchemaBuilder.ts +0 -794
  57. package/src/builders/SchemaBuilder.test.ts +0 -73
  58. package/src/builders/SchemaBuilder.ts +0 -135
  59. package/src/builders/StringSchemaBuilder.test.ts +0 -318
  60. package/src/builders/StringSchemaBuilder.ts +0 -392
  61. package/src/builders/UnionSchemaBuilder.test.ts +0 -162
  62. package/src/builders/UnionSchemaBuilder.ts +0 -154
  63. package/src/defaultSchemas.ts +0 -44
  64. package/src/index.ts +0 -66
  65. package/src/schema.ts +0 -827
  66. package/src/schemaRegistry.builders.test.ts +0 -1393
  67. package/src/schemaRegistry.test.ts +0 -118
  68. package/src/schemaRegistry.ts +0 -461
  69. package/src/validators/validateArray.ts +0 -76
  70. package/src/validators/validateBoolean.ts +0 -36
  71. package/src/validators/validateFunction.ts +0 -25
  72. package/src/validators/validateNumber.ts +0 -82
  73. package/src/validators/validateObject.ts +0 -119
  74. package/src/validators/validateString.ts +0 -59
  75. package/src/validators/validateUnion.ts +0 -36
  76. package/tsconfig.json +0 -16
@@ -1,206 +1,386 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.number = exports.NumberSchemaBuilder = void 0;
4
- const SchemaBuilder_js_1 = require("./SchemaBuilder.js");
5
- const defaultSchemas_js_1 = require("../defaultSchemas.js");
6
- class NumberSchemaBuilder extends SchemaBuilder_js_1.SchemaBuilder {
7
- clone() {
8
- return NumberSchemaBuilder.create(this._schema);
9
- }
10
- get _schema() {
11
- return Object.assign({
12
- type: this.type,
13
- ensureNotNaN: this._ensureNotNaN,
14
- ensureIsFinite: this._ensureIsFinite
15
- }, this.getCommonSchema(), typeof this._min !== 'undefined' ? { min: this._min } : {}, typeof this._max !== 'undefined' ? { max: this._max } : {}, typeof this._isInteger !== 'undefined'
16
- ? { isInteger: this._isInteger }
17
- : {}, typeof this._equals !== 'undefined' ? { equals: this._equals } : {});
18
- }
19
- static create(obj) {
20
- return new NumberSchemaBuilder(obj);
21
- }
22
- constructor(obj) {
23
- super(obj);
24
- if (typeof obj === 'object' && obj) {
25
- if (typeof obj.min !== 'undefined') {
26
- this._min = obj.min;
27
- }
28
- if (typeof obj.max !== 'undefined') {
29
- this._max = obj.max;
30
- }
31
- if (typeof obj.isInteger !== 'undefined') {
32
- this._isInteger = obj.isInteger;
33
- }
34
- if (typeof obj.ensureNotNaN !== 'undefined') {
35
- this._ensureNotNaN = obj.ensureNotNaN;
36
- }
37
- if (typeof obj.ensureIsFinite !== 'undefined') {
38
- this._ensureIsFinite = obj.ensureIsFinite;
39
- }
40
- if (typeof obj.equals !== 'undefined') {
41
- this._equals = obj.equals;
42
- }
1
+ import { SchemaBuilder } from './SchemaBuilder.js';
2
+ /**
3
+ * Number schema builder class. Allows to create Number schemas.
4
+ * Can be required or optional, can be restricted to be equal to a certain value,
5
+ * can be restricted to be in a certain range, can be restricted to be integer.
6
+ *
7
+ * **NOTE** this class is exported only to give opportunity to extend it
8
+ * by inheriting. It is not recommended to create an instance of this class
9
+ * directly. Use {@link number | number()} function instead.
10
+ *
11
+ * @example ```ts
12
+ * const schema = number().equals(42);
13
+ * const result = await schema.validate(42);
14
+ * // result.valid === true
15
+ * // result.object === 42
16
+ * ```
17
+ * @example ```ts
18
+ * const schema = number();
19
+ * const result = await schema.validate('42');
20
+ * // result.valid === false
21
+ * // result.errors[0].message === 'is expected to be a number'
22
+ * ```
23
+ * @example ```ts
24
+ * const schema = number().min(0).max(100);
25
+ * const result = await schema.validate(42);
26
+ * // result.valid === true
27
+ * // result.object === 42
28
+ * ```
29
+ *
30
+ * @example ```ts
31
+ * const schema = number().min(0).max(100);
32
+ * const result = await schema.validate(142.5);
33
+ * // result.valid === false
34
+ * // result.errors[0].message === 'is expected to be less than or equal to 100'
35
+ * ```
36
+ *
37
+ * @see {@link number}
38
+ */
39
+ export class NumberSchemaBuilder extends SchemaBuilder {
40
+ #min;
41
+ #max;
42
+ #equalsTo;
43
+ #ensureNotNaN = true;
44
+ #ensureIsFinite = true;
45
+ #isInteger = true;
46
+ static create(props) {
47
+ return new NumberSchemaBuilder({
48
+ type: 'number',
49
+ ...props
50
+ });
51
+ }
52
+ constructor(props) {
53
+ super(props);
54
+ if (typeof props.min === 'number') {
55
+ this.#min = props.min;
43
56
  }
44
- else {
45
- const defaultSchema = defaultSchemas_js_1.defaultSchemas['number'];
46
- this.isRequired = defaultSchema.isRequired;
47
- this.isNullable = defaultSchema.isNullable;
48
- this._ensureNotNaN = defaultSchema.ensureNotNaN;
49
- this._ensureIsFinite = defaultSchema.ensureIsFinite;
57
+ if (typeof props.max === 'number') {
58
+ this.#max = props.max;
50
59
  }
51
- }
52
- type = 'number';
53
- _min;
54
- _max;
55
- _isInteger;
56
- _ensureNotNaN = true;
57
- _ensureIsFinite = true;
58
- _equals;
59
- min(val) {
60
- if (this._min === val) {
61
- return this;
60
+ if (typeof props.ensureNotNaN === 'boolean') {
61
+ this.#ensureNotNaN = props.ensureNotNaN;
62
62
  }
63
- return NumberSchemaBuilder.create({
64
- ...this._schema,
65
- min: val
66
- });
67
- }
68
- clearMin() {
69
- if (typeof this._min === 'undefined') {
70
- return this;
63
+ if (typeof props.ensureIsFinite === 'boolean') {
64
+ this.#ensureIsFinite = props.ensureIsFinite;
71
65
  }
72
- return NumberSchemaBuilder.create({
73
- ...this._schema,
74
- min: undefined
75
- });
76
- }
77
- max(val) {
78
- if (this._max === val) {
79
- return this;
66
+ if (typeof props.isInteger === 'boolean') {
67
+ this.#isInteger = props.isInteger;
80
68
  }
81
- return NumberSchemaBuilder.create({
82
- ...this._schema,
83
- max: val
84
- });
85
- }
86
- clearMax() {
87
- if (typeof this._max === 'undefined') {
88
- return this;
69
+ if (typeof props.equalsTo === 'number' ||
70
+ typeof props.equalsTo === 'undefined') {
71
+ this.#equalsTo = props.equalsTo;
89
72
  }
90
- return NumberSchemaBuilder.create({
91
- ...this._schema,
92
- max: undefined
93
- });
94
73
  }
95
- optional() {
96
- if (this.isRequired === false) {
97
- return this;
98
- }
99
- return NumberSchemaBuilder.create({
100
- ...this._schema,
101
- isRequired: false
102
- });
74
+ introspect() {
75
+ return {
76
+ ...super.introspect(),
77
+ /**
78
+ * Min valid value (if defined).
79
+ */
80
+ min: this.#min,
81
+ /**
82
+ * Max valid value (if defined).
83
+ */
84
+ max: this.#max,
85
+ /**
86
+ * Make sure that object is not `NaN`. `true` by default.
87
+ */
88
+ ensureNotNaN: this.#ensureNotNaN,
89
+ /**
90
+ * Make sure that object is not different kinds of `infinity`. `true` by default.
91
+ */
92
+ ensureIsFinite: this.#ensureIsFinite,
93
+ /**
94
+ * If set, restrict object to be equal to a certain value.
95
+ */
96
+ equalsTo: this.#equalsTo,
97
+ /**
98
+ * Allow only integer values (floating point values will be rejected
99
+ * as invalid)
100
+ */
101
+ isInteger: this.#isInteger,
102
+ /**
103
+ * Array of preprocessor functions
104
+ */
105
+ preprocessors: this.preprocessors,
106
+ /**
107
+ * Array of validator functions
108
+ */
109
+ validators: this.validators
110
+ };
103
111
  }
104
- required() {
105
- if (this.isRequired === true) {
106
- return this;
107
- }
108
- return NumberSchemaBuilder.create({
109
- ...this._schema,
110
- isRequired: true
112
+ /**
113
+ * @hidden
114
+ */
115
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
116
+ hasType(notUsed) {
117
+ return this.createFromProps({
118
+ ...this.introspect()
111
119
  });
112
120
  }
113
- nullable() {
114
- if (this.isNullable === true) {
115
- return this;
116
- }
117
- return NumberSchemaBuilder.create({
118
- ...this._schema,
119
- isNullable: true
121
+ /**
122
+ * @hidden
123
+ */
124
+ clearHasType() {
125
+ return this.createFromProps({
126
+ ...this.introspect()
120
127
  });
121
128
  }
122
- notNullable() {
123
- if (this.isNullable === false) {
124
- return this;
129
+ /**
130
+ * Performs validion of number schema over `object`.
131
+ * @param context Optional `ValidationContext` settings.
132
+ */
133
+ async validate(object, context) {
134
+ const superResult = await super.preValidate(object, context);
135
+ const { valid, context: prevalidationContext, transaction: preValidationTransaction, errors } = superResult;
136
+ const { path } = prevalidationContext;
137
+ if (!valid) {
138
+ return {
139
+ valid,
140
+ errors
141
+ };
125
142
  }
126
- return NumberSchemaBuilder.create({
127
- ...this._schema,
128
- isNullable: false
129
- });
130
- }
131
- equals(val) {
132
- if (this._equals === val) {
133
- return this;
143
+ const { object: { validatedObject: objToValidate } } = preValidationTransaction;
144
+ if ((typeof objToValidate === 'undefined' || objToValidate === null) &&
145
+ this.isRequired === false) {
146
+ return {
147
+ valid: true,
148
+ object: objToValidate
149
+ };
134
150
  }
135
- return NumberSchemaBuilder.create({
136
- ...this._schema,
137
- equals: val
151
+ if (typeof objToValidate !== 'number')
152
+ return {
153
+ valid: false,
154
+ errors: [
155
+ {
156
+ message: `expected type number, but saw ${typeof objToValidate}`,
157
+ path: path
158
+ }
159
+ ]
160
+ };
161
+ if (typeof this.#equalsTo !== 'undefined' &&
162
+ objToValidate !== this.#equalsTo) {
163
+ return {
164
+ valid: false,
165
+ errors: [
166
+ {
167
+ message: `is expected to be equal to ${this.#equalsTo}`,
168
+ path: path
169
+ }
170
+ ]
171
+ };
172
+ }
173
+ if (this.#ensureNotNaN && Number.isNaN(objToValidate)) {
174
+ return {
175
+ valid: false,
176
+ errors: [
177
+ {
178
+ message: 'is not expected to be NaN',
179
+ path: path
180
+ }
181
+ ]
182
+ };
183
+ }
184
+ if (this.#ensureIsFinite &&
185
+ !Number.isFinite(objToValidate) &&
186
+ this.#ensureNotNaN &&
187
+ !Number.isNaN(objToValidate)) {
188
+ return {
189
+ valid: false,
190
+ errors: [
191
+ {
192
+ message: 'is expected to be a finite number',
193
+ path: path
194
+ }
195
+ ]
196
+ };
197
+ }
198
+ if (this.#isInteger &&
199
+ !Number.isNaN(objToValidate) &&
200
+ Number.isFinite(objToValidate) &&
201
+ !Number.isInteger(objToValidate)) {
202
+ return {
203
+ valid: false,
204
+ errors: [
205
+ {
206
+ message: `is expected to be integer`,
207
+ path: path
208
+ }
209
+ ]
210
+ };
211
+ }
212
+ if (typeof this.#min !== 'undefined') {
213
+ if (objToValidate < this.#min)
214
+ return {
215
+ valid: false,
216
+ errors: [
217
+ {
218
+ message: `expected to be at least ${this.#min}`,
219
+ path: path
220
+ }
221
+ ]
222
+ };
223
+ }
224
+ if (typeof this.#max !== 'undefined') {
225
+ if (objToValidate > this.#max)
226
+ return {
227
+ valid: false,
228
+ errors: [
229
+ {
230
+ message: `expected to be no more than or equal to ${this.#max}`,
231
+ path: path
232
+ }
233
+ ]
234
+ };
235
+ }
236
+ return {
237
+ valid: true,
238
+ object: preValidationTransaction.commit().validatedObject
239
+ };
240
+ }
241
+ createFromProps(props) {
242
+ return NumberSchemaBuilder.create(props);
243
+ }
244
+ /**
245
+ * Restricts number to be equal to `value`.
246
+ */
247
+ equals(value) {
248
+ if (typeof value !== 'number')
249
+ throw new Error('number expected');
250
+ return this.createFromProps({
251
+ ...this.introspect(),
252
+ equalsTo: value
138
253
  });
139
254
  }
255
+ /**
256
+ * Clear `equals()` call.
257
+ */
140
258
  clearEquals() {
141
- if (typeof this._equals === 'undefined') {
142
- return this;
143
- }
144
- return NumberSchemaBuilder.create({
145
- ...this._schema,
146
- equals: undefined
259
+ return this.createFromProps({
260
+ ...this.introspect(),
261
+ equalsTo: undefined
262
+ });
263
+ }
264
+ /**
265
+ * Float values will be considered as valid after this call.
266
+ */
267
+ isFloat() {
268
+ return this.createFromProps({
269
+ ...this.introspect(),
270
+ isInteger: false
147
271
  });
148
272
  }
273
+ /**
274
+ * Only integer values will be considered as valid after this call.
275
+ */
149
276
  isInteger() {
150
- if (this._isInteger === true) {
151
- return this;
152
- }
153
- return NumberSchemaBuilder.create({
154
- ...this._schema,
277
+ return this.createFromProps({
278
+ ...this.introspect(),
155
279
  isInteger: true
156
280
  });
157
281
  }
158
- canBeNotInteger() {
159
- if (typeof this._isInteger === 'undefined') {
160
- return this;
161
- }
162
- return NumberSchemaBuilder.create({
163
- ...this._schema,
164
- isInteger: undefined
165
- });
282
+ /**
283
+ * @hidden
284
+ */
285
+ required() {
286
+ return super.required();
166
287
  }
288
+ /**
289
+ * @hidden
290
+ */
291
+ optional() {
292
+ return super.optional();
293
+ }
294
+ /**
295
+ * Do not accept NaN value
296
+ */
167
297
  notNaN() {
168
- if (this._ensureNotNaN === true) {
169
- return this;
170
- }
171
- return NumberSchemaBuilder.create({
172
- ...this._schema,
298
+ return this.createFromProps({
299
+ ...this.introspect(),
173
300
  ensureNotNaN: true
174
301
  });
175
302
  }
303
+ /**
304
+ * Consider NaN value as valid
305
+ */
176
306
  canBeNaN() {
177
- if (this._ensureNotNaN === false) {
178
- return this;
179
- }
180
- return NumberSchemaBuilder.create({
181
- ...this._schema,
307
+ return this.createFromProps({
308
+ ...this.introspect(),
182
309
  ensureNotNaN: false
183
310
  });
184
311
  }
312
+ /**
313
+ * Do not accept `Infinity`.
314
+ */
185
315
  isFinite() {
186
- if (this._ensureIsFinite === true) {
187
- return this;
188
- }
189
- return NumberSchemaBuilder.create({
190
- ...this._schema,
316
+ return this.createFromProps({
317
+ ...this.introspect(),
191
318
  ensureIsFinite: true
192
319
  });
193
320
  }
321
+ /**
322
+ * Consider `Infinity` as valid.
323
+ */
194
324
  canBeInfinite() {
195
- if (this._ensureIsFinite === false) {
196
- return this;
197
- }
198
- return NumberSchemaBuilder.create({
199
- ...this._schema,
325
+ return this.createFromProps({
326
+ ...this.introspect(),
200
327
  ensureIsFinite: false
201
328
  });
202
329
  }
330
+ /**
331
+ * Restrict number to be at least `minValue`.
332
+ */
333
+ min(minValue) {
334
+ if (typeof minValue !== 'number')
335
+ throw new Error('minValue must be a number');
336
+ return this.createFromProps({
337
+ ...this.introspect(),
338
+ min: minValue
339
+ });
340
+ }
341
+ /**
342
+ * Clear `min()` call.
343
+ */
344
+ clearMin() {
345
+ const schema = this.introspect();
346
+ delete schema.min;
347
+ return this.createFromProps({
348
+ ...schema
349
+ });
350
+ }
351
+ /**
352
+ * Restrict number to be no more than `maxValue`.
353
+ */
354
+ max(maxValue) {
355
+ if (typeof maxValue !== 'number')
356
+ throw new Error('maxValue must be a number');
357
+ return this.createFromProps({
358
+ ...this.introspect(),
359
+ max: maxValue
360
+ });
361
+ }
362
+ /**
363
+ * Clear `max()` call.
364
+ */
365
+ clearMax() {
366
+ const schema = this.introspect();
367
+ delete schema.max;
368
+ return this.createFromProps({
369
+ ...schema
370
+ });
371
+ }
372
+ }
373
+ /**
374
+ * Creates a number schema.
375
+ */
376
+ export function number(equals) {
377
+ if (typeof equals === 'number') {
378
+ return NumberSchemaBuilder.create({
379
+ isRequired: true,
380
+ equalsTo: equals
381
+ });
382
+ }
383
+ return NumberSchemaBuilder.create({
384
+ isRequired: true
385
+ });
203
386
  }
204
- exports.NumberSchemaBuilder = NumberSchemaBuilder;
205
- const number = () => NumberSchemaBuilder.create();
206
- exports.number = number;