justus 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/{dts-generator.js → dts-generator.cjs} +6 -15
  2. package/dist/dts-generator.cjs.map +6 -0
  3. package/{dts-generator.d.ts → dist/dts-generator.d.ts} +1 -1
  4. package/dist/dts-generator.mjs +5 -23
  5. package/dist/dts-generator.mjs.map +2 -2
  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 -817
  15. package/dist/index.mjs.map +3 -3
  16. package/dist/schema.cjs +43 -0
  17. package/dist/schema.cjs.map +6 -0
  18. package/dist/schema.d.ts +16 -0
  19. package/dist/schema.mjs +17 -0
  20. package/dist/schema.mjs.map +6 -0
  21. package/dist/types.cjs +60 -0
  22. package/dist/types.cjs.map +6 -0
  23. package/dist/types.d.ts +138 -0
  24. package/dist/types.mjs +33 -0
  25. package/dist/types.mjs.map +6 -0
  26. package/dist/utilities.cjs +52 -0
  27. package/dist/utilities.cjs.map +6 -0
  28. package/dist/utilities.d.ts +7 -0
  29. package/dist/utilities.mjs +27 -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 +105 -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 +6 -21
  98. package/src/index.ts +23 -23
  99. package/src/schema.ts +11 -9
  100. package/src/types.ts +42 -26
  101. package/src/utilities.ts +9 -6
  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 +15 -18
  109. package/src/validators/optional.ts +5 -7
  110. package/src/validators/string.ts +8 -6
  111. package/src/validators/tuple.ts +7 -5
  112. package/src/validators/union.ts +7 -5
  113. package/src/validators/url.ts +8 -7
  114. package/dist/dts-generator.js.map +0 -6
  115. package/dist/index.js +0 -948
  116. package/dist/index.js.map +0 -6
  117. package/index.d.ts +0 -618
package/dist/index.mjs CHANGED
@@ -1,802 +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
- constructor(validator, defaultValue) {
627
- super();
628
- this.validator = validator;
629
- this.optional = defaultValue === void 0;
630
- if (this.optional) {
631
- this.defaultValue = void 0;
632
- return;
633
- }
634
- try {
635
- this.defaultValue = validator.validate(defaultValue, {
636
- stripAdditionalProperties: false,
637
- stripForbiddenProperties: false,
638
- stripOptionalNulls: false
639
- });
640
- } catch (cause) {
641
- throw new TypeError("Default value does not match validator", { cause });
642
- }
643
- }
644
- validate(value, options) {
645
- if (value === void 0)
646
- return this.defaultValue;
647
- return this.validator.validate(value, options);
648
- }
649
- };
650
- function optional(validation, defaultValue) {
651
- const validator = getValidator(validation);
652
- return new OptionalValidator(validator, defaultValue);
653
- }
654
-
655
- // src/validators/string.ts
656
- var AnyStringValidator = class extends AbstractValidator {
657
- validate(value) {
658
- assertValidation(typeof value == "string", 'Value is not a "string"');
659
- return value;
660
- }
661
- };
662
- var StringValidator = class extends AbstractValidator {
663
- maxLength;
664
- minLength;
665
- pattern;
666
- brand;
667
- constructor(constraints = {}) {
668
- super();
669
- const {
670
- minLength = 0,
671
- maxLength = Number.MAX_SAFE_INTEGER,
672
- pattern
673
- } = constraints;
674
- if ("brand" in constraints)
675
- this.brand = constraints.brand;
676
- assertSchema(minLength >= 0, `Constraint "minLength" (${minLength}) must be non-negative`);
677
- assertSchema(maxLength >= 0, `Constraint "maxLength" (${maxLength}) must be non-negative`);
678
- assertSchema(minLength <= maxLength, `Constraint "minLength" (${minLength}) is greater than "maxLength" (${maxLength})`);
679
- this.maxLength = maxLength;
680
- this.minLength = minLength;
681
- this.pattern = pattern;
682
- }
683
- validate(value) {
684
- assertValidation(typeof value == "string", 'Value is not a "string"');
685
- assertValidation(
686
- value.length >= this.minLength,
687
- `String must have a minimum length of ${this.minLength}`
688
- );
689
- assertValidation(
690
- value.length <= this.maxLength,
691
- `String must have a maximum length of ${this.maxLength}`
692
- );
693
- assertValidation(
694
- this.pattern ? this.pattern.test(value) : true,
695
- `String does not match required pattern ${this.pattern}`
696
- );
697
- return value;
698
- }
699
- };
700
- function _string(constraints) {
701
- return new StringValidator(constraints);
702
- }
703
- var string = makeValidatorFactory(new AnyStringValidator(), _string);
704
-
705
- // src/validators/url.ts
706
- var KEYS = [
707
- "href",
708
- "origin",
709
- "protocol",
710
- "username",
711
- "password",
712
- "host",
713
- "hostname",
714
- "port",
715
- "pathname",
716
- "search",
717
- "hash"
718
- ];
719
- var OPTIONS = {
720
- stripAdditionalProperties: false,
721
- stripForbiddenProperties: false,
722
- stripOptionalNulls: false
723
- };
724
- var URLValidator = class extends AbstractValidator {
725
- href;
726
- origin;
727
- protocol;
728
- username;
729
- password;
730
- host;
731
- hostname;
732
- port;
733
- pathname;
734
- search;
735
- hash;
736
- searchParams;
737
- constructor(constraints = {}) {
738
- super();
739
- for (const key of KEYS) {
740
- const constraint = constraints[key];
741
- if (typeof constraint === "string") {
742
- this[key] = new ConstantValidator(constraint);
743
- } else if (constraint) {
744
- this[key] = constraint;
745
- }
746
- }
747
- if (constraints.searchParams) {
748
- this.searchParams = new ObjectValidator(constraints.searchParams);
749
- }
750
- }
751
- validate(value) {
752
- let url2;
753
- try {
754
- url2 = value instanceof URL ? value : new URL(value);
755
- } catch (error) {
756
- throw new ValidationError('Value could not be converted to a "URL"');
757
- }
758
- const builder = new ValidationErrorBuilder();
759
- for (const key of KEYS) {
760
- const validator = this[key];
761
- if (validator) {
762
- try {
763
- validator.validate(url2[key], OPTIONS);
764
- } catch (error) {
765
- builder.record(error, key);
766
- }
767
- }
768
- }
769
- if (this.searchParams) {
770
- const parameters = {};
771
- for (const param of url2.searchParams.keys()) {
772
- parameters[param] = url2.searchParams.get(param);
773
- }
774
- try {
775
- this.searchParams.validate(parameters, OPTIONS);
776
- } catch (error) {
777
- builder.record(error, "searchParams");
778
- }
779
- }
780
- return builder.assert(url2);
781
- }
782
- };
783
- var anyURLValidator = new URLValidator();
784
- function _url(constraints) {
785
- return new URLValidator(constraints);
786
- }
787
- var url = makeValidatorFactory(anyURLValidator, _url);
788
-
789
- // src/index.ts
790
- function validate(validation, value, options = {}) {
791
- const opts = {
792
- stripAdditionalProperties: false,
793
- stripForbiddenProperties: false,
794
- stripOptionalNulls: false,
795
- ...options
796
- };
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 };
797
23
  return getValidator(validation).validate(value, opts);
798
24
  }
799
- function strip(validation, value, options = {}) {
25
+ function strip(validation, value, options) {
800
26
  const opts = {
801
27
  stripAdditionalProperties: true,
802
28
  stripForbiddenProperties: false,
@@ -806,7 +32,6 @@ function strip(validation, value, options = {}) {
806
32
  return getValidator(validation).validate(value, opts);
807
33
  }
808
34
  export {
809
- AbstractValidator,
810
35
  AllOfValidator,
811
36
  AnyArrayValidator,
812
37
  AnyNumberValidator,
@@ -825,38 +50,19 @@ export {
825
50
  StringValidator,
826
51
  TupleValidator,
827
52
  URLValidator,
828
- ValidationError,
829
- ValidationErrorBuilder,
830
- _allowAdditionalProperties,
831
- _array,
832
- _boolean,
833
- _date,
834
- _number,
835
- _object,
836
- _string,
837
- _url,
838
- additionalValidator,
839
53
  allOf,
840
- allowAdditionalProperties,
841
54
  any,
842
55
  array,
843
56
  arrayOf,
844
- assertSchema,
845
- assertValidation,
846
57
  boolean,
847
58
  constant,
848
59
  date,
849
- getValidator,
850
- isValidator,
851
- makeValidatorFactory,
852
60
  never,
853
61
  number,
854
62
  object,
855
63
  objectOf,
856
64
  oneOf,
857
65
  optional,
858
- restValidator,
859
- schemaValidator,
860
66
  string,
861
67
  strip,
862
68
  tuple,