justus 0.1.5 → 0.2.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 (116) hide show
  1. package/dist/{dts-generator.js → dts-generator.cjs} +3 -3
  2. package/dist/{dts-generator.js.map → dts-generator.cjs.map} +1 -1
  3. package/{dts-generator.d.ts → dist/dts-generator.d.ts} +1 -1
  4. package/dist/dts-generator.mjs +1 -1
  5. package/dist/dts-generator.mjs.map +1 -1
  6. package/dist/errors.cjs +113 -0
  7. package/dist/errors.cjs.map +6 -0
  8. package/dist/errors.d.ts +55 -0
  9. package/dist/errors.mjs +85 -0
  10. package/dist/errors.mjs.map +6 -0
  11. package/dist/index.cjs +133 -0
  12. package/dist/index.cjs.map +6 -0
  13. package/dist/index.d.ts +47 -0
  14. package/dist/index.mjs +23 -818
  15. package/dist/index.mjs.map +3 -3
  16. package/dist/schema.cjs +44 -0
  17. package/dist/schema.cjs.map +6 -0
  18. package/dist/schema.d.ts +16 -0
  19. package/dist/schema.mjs +18 -0
  20. package/dist/schema.mjs.map +6 -0
  21. package/dist/types.cjs +67 -0
  22. package/dist/types.cjs.map +6 -0
  23. package/dist/types.d.ts +136 -0
  24. package/dist/types.mjs +36 -0
  25. package/dist/types.mjs.map +6 -0
  26. package/dist/utilities.cjs +54 -0
  27. package/dist/utilities.cjs.map +6 -0
  28. package/dist/utilities.d.ts +7 -0
  29. package/dist/utilities.mjs +29 -0
  30. package/dist/utilities.mjs.map +6 -0
  31. package/dist/validators/any.cjs +39 -0
  32. package/dist/validators/any.cjs.map +6 -0
  33. package/dist/validators/any.d.ts +7 -0
  34. package/dist/validators/any.mjs +13 -0
  35. package/dist/validators/any.mjs.map +6 -0
  36. package/dist/validators/array.cjs +104 -0
  37. package/dist/validators/array.cjs.map +6 -0
  38. package/dist/validators/array.d.ts +32 -0
  39. package/dist/validators/array.mjs +76 -0
  40. package/dist/validators/array.mjs.map +6 -0
  41. package/dist/validators/boolean.cjs +56 -0
  42. package/dist/validators/boolean.cjs.map +6 -0
  43. package/dist/validators/boolean.d.ts +21 -0
  44. package/dist/validators/boolean.mjs +30 -0
  45. package/dist/validators/boolean.mjs.map +6 -0
  46. package/dist/validators/constant.cjs +51 -0
  47. package/dist/validators/constant.cjs.map +6 -0
  48. package/dist/validators/constant.d.ts +12 -0
  49. package/dist/validators/constant.mjs +24 -0
  50. package/dist/validators/constant.mjs.map +6 -0
  51. package/dist/validators/date.cjs +80 -0
  52. package/dist/validators/date.cjs.map +6 -0
  53. package/dist/validators/date.d.ts +22 -0
  54. package/dist/validators/date.mjs +54 -0
  55. package/dist/validators/date.mjs.map +6 -0
  56. package/dist/validators/never.cjs +44 -0
  57. package/dist/validators/never.cjs.map +6 -0
  58. package/dist/validators/never.d.ts +9 -0
  59. package/dist/validators/never.mjs +18 -0
  60. package/dist/validators/never.mjs.map +6 -0
  61. package/dist/validators/number.cjs +153 -0
  62. package/dist/validators/number.cjs.map +6 -0
  63. package/dist/validators/number.d.ts +48 -0
  64. package/dist/validators/number.mjs +126 -0
  65. package/dist/validators/number.mjs.map +6 -0
  66. package/dist/validators/object.cjs +129 -0
  67. package/dist/validators/object.cjs.map +6 -0
  68. package/dist/validators/object.d.ts +22 -0
  69. package/dist/validators/object.mjs +108 -0
  70. package/dist/validators/object.mjs.map +6 -0
  71. package/dist/validators/optional.cjs +61 -0
  72. package/dist/validators/optional.cjs.map +6 -0
  73. package/dist/validators/optional.d.ts +21 -0
  74. package/dist/validators/optional.mjs +35 -0
  75. package/dist/validators/optional.mjs.map +6 -0
  76. package/dist/validators/string.cjs +84 -0
  77. package/dist/validators/string.cjs.map +6 -0
  78. package/dist/validators/string.d.ts +35 -0
  79. package/dist/validators/string.mjs +57 -0
  80. package/dist/validators/string.mjs.map +6 -0
  81. package/dist/validators/tuple.cjs +95 -0
  82. package/dist/validators/tuple.cjs.map +6 -0
  83. package/dist/validators/tuple.d.ts +15 -0
  84. package/dist/validators/tuple.mjs +69 -0
  85. package/dist/validators/tuple.mjs.map +6 -0
  86. package/dist/validators/union.cjs +78 -0
  87. package/dist/validators/union.cjs.map +6 -0
  88. package/dist/validators/union.d.ts +22 -0
  89. package/dist/validators/union.mjs +50 -0
  90. package/dist/validators/union.mjs.map +6 -0
  91. package/dist/validators/url.cjs +117 -0
  92. package/dist/validators/url.cjs.map +6 -0
  93. package/dist/validators/url.d.ts +57 -0
  94. package/dist/validators/url.mjs +91 -0
  95. package/dist/validators/url.mjs.map +6 -0
  96. package/package.json +33 -23
  97. package/src/dts-generator.ts +4 -0
  98. package/src/index.ts +23 -23
  99. package/src/schema.ts +7 -5
  100. package/src/types.ts +51 -32
  101. package/src/utilities.ts +6 -2
  102. package/src/validators/array.ts +6 -5
  103. package/src/validators/boolean.ts +2 -2
  104. package/src/validators/constant.ts +3 -1
  105. package/src/validators/date.ts +1 -1
  106. package/src/validators/never.ts +4 -2
  107. package/src/validators/number.ts +8 -7
  108. package/src/validators/object.ts +12 -12
  109. package/src/validators/optional.ts +5 -8
  110. package/src/validators/string.ts +8 -6
  111. package/src/validators/tuple.ts +5 -3
  112. package/src/validators/union.ts +7 -5
  113. package/src/validators/url.ts +8 -7
  114. package/dist/index.js +0 -949
  115. package/dist/index.js.map +0 -6
  116. package/index.d.ts +0 -617
package/dist/index.mjs CHANGED
@@ -1,803 +1,28 @@
1
- // src/errors.ts
2
- function pathToString(path) {
3
- return path.reduce((string2, key, index) => {
4
- if (typeof key === "number")
5
- return `${string2}[${key}]`;
6
- return index === 0 ? key : `${string2}.${key}`;
7
- }, "");
8
- }
9
- var ValidationError = class extends Error {
10
- /** An `Array` of validation errors encountered while validating */
11
- errors;
12
- /** Our stack, always present as we enforce it in the constructor */
13
- stack;
14
- constructor(builderOrCause, constructorOrPath, maybeConstructor) {
15
- let constructor;
16
- let errors;
17
- if (builderOrCause instanceof ValidationErrorBuilder) {
18
- errors = builderOrCause.errors;
19
- constructor = builderOrCause.assert;
20
- } else {
21
- const path = Array.isArray(constructorOrPath) ? constructorOrPath : [];
22
- if (builderOrCause instanceof ValidationError) {
23
- errors = builderOrCause.errors.map(({ path: subpath, message: message2 }) => ({ path: [...path, ...subpath], message: message2 }));
24
- } else {
25
- errors = [{ path, message: `${builderOrCause}` }];
26
- }
27
- constructor = typeof maybeConstructor === "function" ? maybeConstructor : typeof constructorOrPath === "function" ? constructorOrPath : ValidationError;
28
- }
29
- const details = errors.map(({ path, message: message2 }) => ({ key: pathToString(path), message: message2 })).map(({ key, message: message2 }) => key ? `${key}: ${message2}` : message2).join("\n ");
30
- const message = errors.length !== 1 ? `Found ${errors.length} validation errors` : "Found 1 validation error";
31
- super(`${message}
32
- ${details}`);
33
- Error.captureStackTrace(this, constructor);
34
- Object.defineProperty(this, "errors", { value: errors });
35
- }
36
- };
37
- var ValidationErrorBuilder = class {
38
- /** The current list of validation errors */
39
- errors = [];
40
- /**
41
- * Record a validation error associated with the specified key.
42
- *
43
- * @param error - The error (normally a `string` or a `ValidationError`)
44
- * to record and associate with the given key
45
- * @param key - The key in an object, or index in an array where the
46
- * vaildation error was encountered
47
- */
48
- record(error, ...key) {
49
- const path = [...key];
50
- if (error instanceof ValidationError) {
51
- error.errors.forEach(({ path: subpath, message }) => {
52
- this.errors.push({ path: [...path, ...subpath], message });
53
- });
54
- } else {
55
- this.errors.push({ path, message: `${error}` });
56
- }
57
- return this;
58
- }
59
- /**
60
- * Assert there are no validation errors and return the specified value, or
61
- * throw a `ValidationError` combining all errors
62
- *
63
- * @param value - The value to return if no errors have been recorded
64
- */
65
- assert(value) {
66
- if (this.errors.length > 0)
67
- throw new ValidationError(this);
68
- return value;
69
- }
70
- };
71
- function assertValidation(what, message) {
72
- if (!what)
73
- throw new ValidationError(message, assertValidation);
74
- }
75
- function assertSchema(what, message) {
76
- if (!what)
77
- throw new TypeError(message);
78
- }
79
-
80
- // src/types.ts
81
- var isValidator = Symbol.for("justus.isValidator");
82
- var restValidator = Symbol.for("justus.restValidator");
83
- var schemaValidator = Symbol.for("justus.schemaValidator");
84
- var additionalValidator = Symbol.for("justus.additionalValidator");
85
- function makeValidatorFactory(validator, factory) {
86
- return Object.assign(factory, {
87
- optional: validator.optional,
88
- validate: validator.validate.bind(validator),
89
- [Symbol.iterator]: validator[Symbol.iterator].bind(validator),
90
- [isValidator]: true
91
- });
92
- }
93
- var AbstractValidator = class {
94
- [isValidator] = true;
95
- optional = void 0;
96
- /** Allow any `Validator` to be used as a rest parameter in `Tuple`s */
97
- *[Symbol.iterator]() {
98
- yield { [restValidator]: this };
99
- }
100
- };
101
-
102
- // src/validators/any.ts
103
- var AnyValidator = class extends AbstractValidator {
104
- validate(value) {
105
- return value;
106
- }
107
- };
108
- var any = new AnyValidator();
109
-
110
- // src/validators/constant.ts
111
- var ConstantValidator = class extends AbstractValidator {
112
- constant;
113
- constructor(constant2) {
114
- super();
115
- this.constant = constant2;
116
- }
117
- validate(value) {
118
- assertValidation(value === this.constant, `Value does not match constant "${this.constant}"`);
119
- return value;
120
- }
121
- };
122
- function constant(constant2) {
123
- return new ConstantValidator(constant2);
124
- }
125
- var nullValidator = new ConstantValidator(null);
126
-
127
- // src/validators/tuple.ts
128
- var TupleValidator = class extends AbstractValidator {
129
- members;
130
- tuple;
131
- constructor(tuple2) {
132
- super();
133
- const members = [];
134
- for (const item of tuple2) {
135
- if (item === null) {
136
- members.push({ single: true, validator: nullValidator });
137
- } else if (typeof item === "object" && restValidator in item) {
138
- members.push({ single: false, validator: item[restValidator] });
139
- } else {
140
- members.push({ single: true, validator: getValidator(item) });
141
- }
142
- }
143
- this.members = members;
144
- this.tuple = tuple2;
145
- }
146
- validate(value, options) {
147
- assertValidation(Array.isArray(value), 'Value is not an "array"');
148
- if (this.members.length === 0) {
149
- const size = value.length;
150
- assertValidation(size === 0, `Found ${size} element${size === 1 ? "" : "s"} validating empty tuple`);
151
- return value;
152
- }
153
- const clone = new Array(value.length);
154
- let needle = 0;
155
- let haystack = 0;
156
- let { single, validator } = this.members[needle];
157
- while (needle < this.members.length && haystack < value.length) {
158
- try {
159
- clone[haystack] = validator.validate(value[haystack], options);
160
- if (single)
161
- ({ single, validator } = this.members[++needle] || {});
162
- haystack++;
163
- } catch (error) {
164
- if (single)
165
- throw new ValidationError(error, [haystack]);
166
- else
167
- ({ single, validator } = this.members[++needle] || {});
168
- }
169
- }
170
- while (needle < this.members.length && this.members[needle].single === false) {
171
- needle++;
172
- }
173
- const missing = this.members.length - needle;
174
- if (missing === 1 && single) {
175
- throw new ValidationError("Tuple defines 1 missing validation");
176
- } else if (missing > 1) {
177
- throw new ValidationError(`Tuple defines ${missing} missing validations`);
178
- }
179
- const extra = value.length - haystack;
180
- assertValidation(extra === 0, `Found ${extra} extra element${extra === 1 ? "" : "s"} in tuple`);
181
- return clone;
182
- }
183
- };
184
- function tuple(tuple2) {
185
- return new TupleValidator(tuple2);
186
- }
187
-
188
- // src/validators/object.ts
189
- var AnyObjectValidator = class extends AbstractValidator {
190
- validate(value) {
191
- assertValidation(typeof value == "object", 'Value is not an "object"');
192
- assertValidation(value !== null, 'Value is "null"');
193
- return value;
194
- }
195
- };
196
- var ObjectValidator = class extends AbstractValidator {
197
- schema;
198
- validators = /* @__PURE__ */ new Map();
199
- additionalProperties;
200
- constructor(schema) {
201
- super();
202
- const { [additionalValidator]: additional, ...properties } = schema;
203
- if (additional)
204
- this.additionalProperties = getValidator(additional);
205
- for (const key of Object.keys(properties)) {
206
- this.validators.set(key, getValidator(properties[key]));
207
- }
208
- this.schema = schema;
209
- }
210
- validate(value, options) {
211
- assertValidation(typeof value === "object", 'Value is not an "object"');
212
- assertValidation(value !== null, 'Value is "null"');
213
- const { stripAdditionalProperties, stripOptionalNulls } = options;
214
- const record = value;
215
- const builder = new ValidationErrorBuilder();
216
- const clone = {};
217
- for (const [key, validator] of this.validators.entries()) {
218
- const optional2 = !!validator.optional;
219
- const original = record[key];
220
- if (stripOptionalNulls && optional2 && original === null) {
221
- continue;
222
- }
223
- if (original === void 0) {
224
- try {
225
- const validated = validator.validate(original, options);
226
- if (!(optional2 && validated == void 0))
227
- clone[key] = validated;
228
- } catch (error) {
229
- if (optional2)
230
- continue;
231
- builder.record("Required property missing", key);
232
- }
233
- continue;
234
- }
235
- try {
236
- const validated = validator.validate(original, options);
237
- if (!(optional2 && validated == void 0))
238
- clone[key] = validated;
239
- } catch (error) {
240
- builder.record(error, key);
241
- }
242
- }
243
- const additionalKeys = Object.keys(record).filter((k) => !this.validators.has(k));
244
- const additional = this.additionalProperties;
245
- if (additional) {
246
- additionalKeys.forEach((key) => {
247
- if (record[key] === void 0)
248
- return;
249
- try {
250
- clone[key] = additional.validate(record[key], options);
251
- } catch (error) {
252
- builder.record(error, key);
253
- }
254
- });
255
- } else if (!stripAdditionalProperties) {
256
- additionalKeys.forEach((key) => {
257
- if (record[key] !== void 0)
258
- builder.record("Unknown property", key);
259
- });
260
- }
261
- return builder.assert(clone);
262
- }
263
- };
264
- function _object(schema) {
265
- const validator = new ObjectValidator(schema);
266
- function* iterator() {
267
- yield { [restValidator]: validator };
268
- }
269
- return Object.defineProperties(schema, {
270
- [schemaValidator]: { value: validator, enumerable: false },
271
- [Symbol.iterator]: { value: iterator, enumerable: false }
272
- });
273
- }
274
- var object = makeValidatorFactory(new AnyObjectValidator(), _object);
275
- function objectOf(validation) {
276
- return new ObjectValidator({ ...allowAdditionalProperties(validation) });
277
- }
278
-
279
- // src/utilities.ts
280
- function getValidator(validation) {
281
- if (validation === null)
282
- return nullValidator;
283
- if (validation[isValidator] === true)
284
- return validation;
285
- switch (typeof validation) {
286
- case "boolean":
287
- case "string":
288
- case "number":
289
- return new ConstantValidator(validation);
290
- case "object":
291
- if (schemaValidator in validation)
292
- return validation[schemaValidator];
293
- if (Array.isArray(validation))
294
- return new TupleValidator(validation);
295
- return new ObjectValidator(validation);
296
- default:
297
- throw new TypeError(`Invalid validation (type=${typeof validation})`);
298
- }
299
- }
300
-
301
- // src/schema.ts
302
- function _allowAdditionalProperties(options) {
303
- if (options === false)
304
- return { [additionalValidator]: false };
305
- if (options === true)
306
- return { [additionalValidator]: any };
307
- return { [additionalValidator]: options ? getValidator(options) : any };
308
- }
309
- var allowAdditionalProperties = _allowAdditionalProperties;
310
- allowAdditionalProperties[additionalValidator] = any;
311
-
312
- // src/validators/union.ts
313
- var OneOfValidator = class extends AbstractValidator {
314
- validators;
315
- constructor(args) {
316
- super();
317
- this.validators = args.map((validation) => getValidator(validation));
318
- assertSchema(this.validators.length > 0, 'At least one validation required in "oneOf"');
319
- }
320
- validate(value, options) {
321
- const builder = new ValidationErrorBuilder();
322
- for (const validator of this.validators) {
323
- try {
324
- return validator.validate(value, options);
325
- } catch (error) {
326
- builder.record(error);
327
- }
328
- }
329
- return builder.assert(value);
330
- }
331
- };
332
- function oneOf(...args) {
333
- return new OneOfValidator(args);
334
- }
335
- var AllOfValidator = class extends AbstractValidator {
336
- validators;
337
- constructor(args) {
338
- super();
339
- this.validators = args.map((validation) => getValidator(validation));
340
- assertSchema(this.validators.length > 0, 'At least one validation required in "allOf"');
341
- }
342
- validate(value, options) {
343
- for (const validator of this.validators) {
344
- value = validator.validate(value, options);
345
- }
346
- return value;
347
- }
348
- };
349
- function allOf(...args) {
350
- return new AllOfValidator(args);
351
- }
352
-
353
- // src/validators/array.ts
354
- var AnyArrayValidator = class extends AbstractValidator {
355
- validate(value, options) {
356
- assertValidation(Array.isArray(value), 'Value is not an "array"');
357
- return [...value];
358
- }
359
- };
360
- var ArrayValidator = class extends AbstractValidator {
361
- maxItems;
362
- minItems;
363
- uniqueItems;
364
- items;
365
- constructor(options = {}) {
366
- super();
367
- const {
368
- items = any,
369
- maxItems = Number.POSITIVE_INFINITY,
370
- minItems = 0,
371
- uniqueItems = false
372
- } = options;
373
- assertSchema(minItems >= 0, `Constraint "minItems" (${minItems}) must be non-negative`);
374
- assertSchema(maxItems >= 0, `Constraint "maxItems" (${maxItems}) must be non-negative`);
375
- assertSchema(minItems <= maxItems, `Constraint "minItems" (${minItems}) is greater than "maxItems" (${maxItems})`);
376
- this.items = items;
377
- this.maxItems = maxItems;
378
- this.minItems = minItems;
379
- this.uniqueItems = uniqueItems;
380
- }
381
- validate(value, options) {
382
- assertValidation(Array.isArray(value), 'Value is not an "array"');
383
- assertValidation(
384
- value.length >= this.minItems,
385
- `Array must have a minimum length of ${this.minItems}`
386
- );
387
- assertValidation(
388
- value.length <= this.maxItems,
389
- `Array must have a maximum length of ${this.maxItems}`
390
- );
391
- const builder = new ValidationErrorBuilder();
392
- const clone = new Array(value.length);
393
- value.forEach((item, i) => {
394
- try {
395
- const position = value.indexOf(value[i]);
396
- if (position === i) {
397
- clone[i] = this.items.validate(item, options);
398
- } else if (this.uniqueItems) {
399
- builder.record(`Duplicate of item at index ${position}`, i);
400
- } else {
401
- clone[i] = clone[position];
402
- }
403
- } catch (error) {
404
- builder.record(error, i);
405
- }
406
- });
407
- return builder.assert(clone);
408
- }
409
- };
410
- function _array(constraints) {
411
- const items = constraints.items ? getValidator(constraints.items) : any;
412
- return new ArrayValidator({ ...constraints, items });
413
- }
414
- var array = makeValidatorFactory(new AnyArrayValidator(), _array);
415
- function arrayOf(validation) {
416
- return new ArrayValidator({ items: getValidator(validation) });
417
- }
418
-
419
- // src/validators/boolean.ts
420
- var BooleanValidator = class extends AbstractValidator {
421
- fromString;
422
- constructor(constraints = {}) {
423
- super();
424
- const { fromString = false } = constraints;
425
- this.fromString = fromString;
426
- }
427
- validate(value) {
428
- if (typeof value == "string" && this.fromString) {
429
- const string2 = value.toLowerCase();
430
- const parsed = string2 === "true" ? true : string2 === "false" ? false : void 0;
431
- assertValidation(parsed !== void 0, "Boolean can not be parsed from string");
432
- value = parsed;
433
- }
434
- assertValidation(typeof value === "boolean", 'Value is not a "boolean"');
435
- return value;
436
- }
437
- };
438
- function _boolean(constraints) {
439
- return new BooleanValidator(constraints);
440
- }
441
- var boolean = makeValidatorFactory(new BooleanValidator(), _boolean);
442
-
443
- // src/validators/date.ts
444
- var ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
445
- var DateValidator = class extends AbstractValidator {
446
- format;
447
- from;
448
- until;
449
- constructor(constraints = {}) {
450
- super();
451
- const { format, from, until } = constraints;
452
- if (from != void 0 && until !== void 0) {
453
- assertSchema(
454
- until.getTime() >= from.getTime(),
455
- `Constraint "until" (${until.toISOString()}) must not be before "from" (${from.toISOString()})`
456
- );
457
- }
458
- this.format = format;
459
- this.from = from;
460
- this.until = until;
461
- }
462
- validate(value) {
463
- let date2;
464
- try {
465
- date2 = new Date(value);
466
- } catch (error) {
467
- throw new ValidationError('Value could not be converted to a "Date"');
468
- }
469
- if (isNaN(date2.getTime()))
470
- throw new ValidationError("Invalid date");
471
- if (this.format === "iso") {
472
- assertValidation(typeof value === "string", 'ISO Date is not a "string"');
473
- assertValidation(ISO_8601_REGEX.test(value), "Invalid format for ISO Date");
474
- } else if (this.format === "timestamp") {
475
- assertValidation(typeof value === "number", 'Timestamp is not a "number"');
476
- }
477
- if (this.from) {
478
- assertValidation(this.from.getTime() <= date2.getTime(), `Date is before ${this.from.toISOString()}`);
479
- }
480
- if (this.until) {
481
- assertValidation(this.until.getTime() >= date2.getTime(), `Date is after ${this.until.toISOString()}`);
482
- }
483
- return date2;
484
- }
485
- };
486
- function _date(constraints) {
487
- return new DateValidator(constraints);
488
- }
489
- var date = makeValidatorFactory(new DateValidator(), _date);
490
-
491
- // src/validators/never.ts
492
- var NeverValidator = class extends AbstractValidator {
493
- optional = true;
494
- validate(value, options) {
495
- const { stripForbiddenProperties } = options;
496
- if (stripForbiddenProperties || value === void 0)
497
- return;
498
- throw new ValidationError("Forbidden property");
499
- }
500
- };
501
- var never = new NeverValidator();
502
-
503
- // src/validators/number.ts
504
- var PRECISION = 6;
505
- var MULTIPLIER = Math.pow(10, PRECISION);
506
- function countDecimals(n) {
507
- const match = n.toExponential().match(/^\d+(\.\d+)?e([+-]\d+)$/);
508
- if (!match)
509
- throw new RangeError(`Can't calculate digits for number "${n}"`);
510
- const digits = (match[1] || ".").length - 1 - parseInt(match[2]);
511
- return digits < 0 ? 0 : digits;
512
- }
513
- var AnyNumberValidator = class extends AbstractValidator {
514
- validate(value) {
515
- assertValidation(typeof value == "number", 'Value is not a "number"');
516
- assertValidation(!isNaN(value), 'Number is "NaN"');
517
- return value;
518
- }
519
- };
520
- var NumberValidator = class extends AbstractValidator {
521
- #isMultipleOf;
522
- allowNaN;
523
- exclusiveMaximum;
524
- exclusiveMinimum;
525
- fromString;
526
- maximum;
527
- minimum;
528
- multipleOf;
529
- brand;
530
- constructor(constraints = {}) {
531
- super();
532
- const {
533
- allowNaN = false,
534
- exclusiveMaximum,
535
- exclusiveMinimum,
536
- fromString = false,
537
- maximum = Number.POSITIVE_INFINITY,
538
- minimum = Number.NEGATIVE_INFINITY,
539
- multipleOf
540
- } = constraints;
541
- if ("brand" in constraints)
542
- this.brand = constraints.brand;
543
- assertSchema(maximum >= minimum, `Constraint "minimum" (${minimum}) is greater than "maximum" (${maximum})`);
544
- if (exclusiveMaximum !== void 0) {
545
- assertSchema(
546
- exclusiveMaximum > minimum,
547
- `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "minimum" (${minimum})`
548
- );
549
- }
550
- if (exclusiveMinimum !== void 0) {
551
- assertSchema(
552
- maximum > exclusiveMinimum,
553
- `Constraint "maximum" (${maximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`
554
- );
555
- }
556
- if (exclusiveMinimum != void 0 && exclusiveMaximum !== void 0) {
557
- assertSchema(
558
- exclusiveMaximum > exclusiveMinimum,
559
- `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`
560
- );
561
- }
562
- if (multipleOf !== void 0) {
563
- assertSchema(multipleOf > 0, `Constraint "multipleOf" (${multipleOf}) must be greater than zero`);
564
- const decimals = countDecimals(multipleOf);
565
- if (decimals === 0) {
566
- this.#isMultipleOf = (value) => !(value % multipleOf);
567
- } else if (decimals <= PRECISION) {
568
- this.#isMultipleOf = (value) => {
569
- try {
570
- if (countDecimals(value) > PRECISION)
571
- return false;
572
- return !(value * MULTIPLIER % (multipleOf * MULTIPLIER));
573
- } catch (error) {
574
- throw new ValidationError(error.message);
575
- }
576
- };
577
- } else {
578
- assertSchema(false, `Constraint "multipleOf" (${multipleOf}) requires too much precision`);
579
- }
580
- }
581
- this.allowNaN = allowNaN;
582
- this.exclusiveMaximum = exclusiveMaximum;
583
- this.exclusiveMinimum = exclusiveMinimum;
584
- this.fromString = fromString;
585
- this.maximum = maximum;
586
- this.minimum = minimum;
587
- this.multipleOf = multipleOf;
588
- }
589
- validate(value) {
590
- if (typeof value == "string" && this.fromString) {
591
- const parsed = +`${value}`;
592
- assertValidation(!isNaN(parsed), "Number can not be parsed from string");
593
- value = parsed;
594
- }
595
- assertValidation(typeof value == "number", 'Value is not a "number"');
596
- if (isNaN(value)) {
597
- assertValidation(this.allowNaN, 'Number is "NaN"');
598
- return value;
599
- }
600
- assertValidation(value >= this.minimum, `Number is less than ${this.minimum}`);
601
- assertValidation(value <= this.maximum, `Number is greater than ${this.maximum}`);
602
- assertValidation(
603
- this.exclusiveMinimum == void 0 || value > this.exclusiveMinimum,
604
- `Number is less than or equal to ${this.exclusiveMinimum}`
605
- );
606
- assertValidation(
607
- this.exclusiveMaximum == void 0 || value < this.exclusiveMaximum,
608
- `Number is greater than or equal to ${this.exclusiveMaximum}`
609
- );
610
- assertValidation(
611
- this.#isMultipleOf ? this.#isMultipleOf(value) : true,
612
- `Number is not a multiple of ${this.multipleOf}`
613
- );
614
- return value;
615
- }
616
- };
617
- function _number(constraints) {
618
- return new NumberValidator(constraints);
619
- }
620
- var number = makeValidatorFactory(new AnyNumberValidator(), _number);
621
-
622
- // src/validators/optional.ts
623
- var OptionalValidator = class extends AbstractValidator {
624
- validator;
625
- defaultValue;
626
- optional;
627
- constructor(validator, defaultValue) {
628
- super();
629
- this.validator = validator;
630
- this.optional = defaultValue === void 0;
631
- if (this.optional) {
632
- this.defaultValue = void 0;
633
- return;
634
- }
635
- try {
636
- this.defaultValue = validator.validate(defaultValue, {
637
- stripAdditionalProperties: false,
638
- stripForbiddenProperties: false,
639
- stripOptionalNulls: false
640
- });
641
- } catch (cause) {
642
- throw new TypeError("Default value does not match validator", { cause });
643
- }
644
- }
645
- validate(value, options) {
646
- if (value === void 0)
647
- return this.defaultValue;
648
- return this.validator.validate(value, options);
649
- }
650
- };
651
- function optional(validation, defaultValue) {
652
- const validator = getValidator(validation);
653
- return new OptionalValidator(validator, defaultValue);
654
- }
655
-
656
- // src/validators/string.ts
657
- var AnyStringValidator = class extends AbstractValidator {
658
- validate(value) {
659
- assertValidation(typeof value == "string", 'Value is not a "string"');
660
- return value;
661
- }
662
- };
663
- var StringValidator = class extends AbstractValidator {
664
- maxLength;
665
- minLength;
666
- pattern;
667
- brand;
668
- constructor(constraints = {}) {
669
- super();
670
- const {
671
- minLength = 0,
672
- maxLength = Number.MAX_SAFE_INTEGER,
673
- pattern
674
- } = constraints;
675
- if ("brand" in constraints)
676
- this.brand = constraints.brand;
677
- assertSchema(minLength >= 0, `Constraint "minLength" (${minLength}) must be non-negative`);
678
- assertSchema(maxLength >= 0, `Constraint "maxLength" (${maxLength}) must be non-negative`);
679
- assertSchema(minLength <= maxLength, `Constraint "minLength" (${minLength}) is greater than "maxLength" (${maxLength})`);
680
- this.maxLength = maxLength;
681
- this.minLength = minLength;
682
- this.pattern = pattern;
683
- }
684
- validate(value) {
685
- assertValidation(typeof value == "string", 'Value is not a "string"');
686
- assertValidation(
687
- value.length >= this.minLength,
688
- `String must have a minimum length of ${this.minLength}`
689
- );
690
- assertValidation(
691
- value.length <= this.maxLength,
692
- `String must have a maximum length of ${this.maxLength}`
693
- );
694
- assertValidation(
695
- this.pattern ? this.pattern.test(value) : true,
696
- `String does not match required pattern ${this.pattern}`
697
- );
698
- return value;
699
- }
700
- };
701
- function _string(constraints) {
702
- return new StringValidator(constraints);
703
- }
704
- var string = makeValidatorFactory(new AnyStringValidator(), _string);
705
-
706
- // src/validators/url.ts
707
- var KEYS = [
708
- "href",
709
- "origin",
710
- "protocol",
711
- "username",
712
- "password",
713
- "host",
714
- "hostname",
715
- "port",
716
- "pathname",
717
- "search",
718
- "hash"
719
- ];
720
- var OPTIONS = {
721
- stripAdditionalProperties: false,
722
- stripForbiddenProperties: false,
723
- stripOptionalNulls: false
724
- };
725
- var URLValidator = class extends AbstractValidator {
726
- href;
727
- origin;
728
- protocol;
729
- username;
730
- password;
731
- host;
732
- hostname;
733
- port;
734
- pathname;
735
- search;
736
- hash;
737
- searchParams;
738
- constructor(constraints = {}) {
739
- super();
740
- for (const key of KEYS) {
741
- const constraint = constraints[key];
742
- if (typeof constraint === "string") {
743
- this[key] = new ConstantValidator(constraint);
744
- } else if (constraint) {
745
- this[key] = constraint;
746
- }
747
- }
748
- if (constraints.searchParams) {
749
- this.searchParams = new ObjectValidator(constraints.searchParams);
750
- }
751
- }
752
- validate(value) {
753
- let url2;
754
- try {
755
- url2 = value instanceof URL ? value : new URL(value);
756
- } catch (error) {
757
- throw new ValidationError('Value could not be converted to a "URL"');
758
- }
759
- const builder = new ValidationErrorBuilder();
760
- for (const key of KEYS) {
761
- const validator = this[key];
762
- if (validator) {
763
- try {
764
- validator.validate(url2[key], OPTIONS);
765
- } catch (error) {
766
- builder.record(error, key);
767
- }
768
- }
769
- }
770
- if (this.searchParams) {
771
- const parameters = {};
772
- for (const param of url2.searchParams.keys()) {
773
- parameters[param] = url2.searchParams.get(param);
774
- }
775
- try {
776
- this.searchParams.validate(parameters, OPTIONS);
777
- } catch (error) {
778
- builder.record(error, "searchParams");
779
- }
780
- }
781
- return builder.assert(url2);
782
- }
783
- };
784
- var anyURLValidator = new URLValidator();
785
- function _url(constraints) {
786
- return new URLValidator(constraints);
787
- }
788
- var url = makeValidatorFactory(anyURLValidator, _url);
789
-
790
- // src/index.ts
791
- function validate(validation, value, options = {}) {
792
- const opts = {
793
- stripAdditionalProperties: false,
794
- stripForbiddenProperties: false,
795
- stripOptionalNulls: false,
796
- ...options
797
- };
1
+ // index.ts
2
+ export * from "./errors.mjs";
3
+ export * from "./schema.mjs";
4
+ export * from "./types.mjs";
5
+ export * from "./utilities.mjs";
6
+ import { any, AnyValidator } from "./validators/any.mjs";
7
+ import { array, arrayOf, ArrayValidator, AnyArrayValidator } from "./validators/array.mjs";
8
+ import { boolean, BooleanValidator } from "./validators/boolean.mjs";
9
+ import { constant, ConstantValidator } from "./validators/constant.mjs";
10
+ import { date, DateValidator } from "./validators/date.mjs";
11
+ import { never, NeverValidator } from "./validators/never.mjs";
12
+ import { AnyNumberValidator, number, NumberValidator } from "./validators/number.mjs";
13
+ import { AnyObjectValidator, object, objectOf, ObjectValidator } from "./validators/object.mjs";
14
+ import { optional, OptionalValidator } from "./validators/optional.mjs";
15
+ import { AnyStringValidator, string, StringValidator } from "./validators/string.mjs";
16
+ import { tuple, TupleValidator } from "./validators/tuple.mjs";
17
+ import { allOf, AllOfValidator, oneOf, OneOfValidator } from "./validators/union.mjs";
18
+ import { url, URLValidator } from "./validators/url.mjs";
19
+ import { defaultValidationOptions } from "./types.mjs";
20
+ import { getValidator } from "./utilities.mjs";
21
+ function validate(validation, value, options) {
22
+ const opts = { ...defaultValidationOptions, ...options };
798
23
  return getValidator(validation).validate(value, opts);
799
24
  }
800
- function strip(validation, value, options = {}) {
25
+ function strip(validation, value, options) {
801
26
  const opts = {
802
27
  stripAdditionalProperties: true,
803
28
  stripForbiddenProperties: false,
@@ -807,7 +32,6 @@ function strip(validation, value, options = {}) {
807
32
  return getValidator(validation).validate(value, opts);
808
33
  }
809
34
  export {
810
- AbstractValidator,
811
35
  AllOfValidator,
812
36
  AnyArrayValidator,
813
37
  AnyNumberValidator,
@@ -826,38 +50,19 @@ export {
826
50
  StringValidator,
827
51
  TupleValidator,
828
52
  URLValidator,
829
- ValidationError,
830
- ValidationErrorBuilder,
831
- _allowAdditionalProperties,
832
- _array,
833
- _boolean,
834
- _date,
835
- _number,
836
- _object,
837
- _string,
838
- _url,
839
- additionalValidator,
840
53
  allOf,
841
- allowAdditionalProperties,
842
54
  any,
843
55
  array,
844
56
  arrayOf,
845
- assertSchema,
846
- assertValidation,
847
57
  boolean,
848
58
  constant,
849
59
  date,
850
- getValidator,
851
- isValidator,
852
- makeValidatorFactory,
853
60
  never,
854
61
  number,
855
62
  object,
856
63
  objectOf,
857
64
  oneOf,
858
65
  optional,
859
- restValidator,
860
- schemaValidator,
861
66
  string,
862
67
  strip,
863
68
  tuple,