@amazon/vinyl-validation 1.1.1 → 2.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 (68) hide show
  1. package/README.md +42 -0
  2. package/dist/index.cjs +337 -174
  3. package/dist/index.cjs.map +4 -4
  4. package/dist/index.js +325 -162
  5. package/dist/index.js.map +4 -4
  6. package/dist/types/current/index.d.ts +15 -14
  7. package/dist/types/current/index.d.ts.map +1 -1
  8. package/dist/types/current/index.js +15 -14
  9. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  10. package/dist/types/current/validation/ArraySchema.d.ts.map +1 -1
  11. package/dist/types/current/validation/ArraySchema.js +11 -4
  12. package/dist/types/current/validation/FunctionSchema.js +1 -1
  13. package/dist/types/current/validation/JsonSchema.d.ts +63 -0
  14. package/dist/types/current/validation/JsonSchema.d.ts.map +1 -0
  15. package/dist/types/current/validation/JsonSchema.js +59 -0
  16. package/dist/types/current/validation/NumberSchema.d.ts.map +1 -1
  17. package/dist/types/current/validation/NumberSchema.js +6 -6
  18. package/dist/types/current/validation/ObjectSchema.d.ts +2 -2
  19. package/dist/types/current/validation/ObjectSchema.d.ts.map +1 -1
  20. package/dist/types/current/validation/ObjectSchema.js +12 -1
  21. package/dist/types/current/validation/PropertyValidator.d.ts +1 -1
  22. package/dist/types/current/validation/PropertyValidator.d.ts.map +1 -1
  23. package/dist/types/current/validation/RecordSchema.d.ts.map +1 -1
  24. package/dist/types/current/validation/RecordSchema.js +4 -0
  25. package/dist/types/current/validation/SchemaBase.d.ts +23 -1
  26. package/dist/types/current/validation/SchemaBase.d.ts.map +1 -1
  27. package/dist/types/current/validation/SchemaBase.js +36 -0
  28. package/dist/types/current/validation/SetSchema.d.ts.map +1 -1
  29. package/dist/types/current/validation/SetSchema.js +6 -1
  30. package/dist/types/current/validation/StringSchema.d.ts.map +1 -1
  31. package/dist/types/current/validation/StringSchema.js +4 -4
  32. package/dist/types/current/validation/Validator.d.ts +14 -2
  33. package/dist/types/current/validation/Validator.d.ts.map +1 -1
  34. package/dist/types/current/validation/Validator.js +6 -2
  35. package/dist/types/current/validation/ValueSchema.d.ts +1 -0
  36. package/dist/types/current/validation/ValueSchema.d.ts.map +1 -1
  37. package/dist/types/current/validation/ValueSchema.js +7 -2
  38. package/dist/types/current/validation/andValidators.d.ts.map +1 -1
  39. package/dist/types/current/validation/andValidators.js +2 -1
  40. package/dist/types/current/validation/orValidators.d.ts.map +1 -1
  41. package/dist/types/current/validation/orValidators.js +18 -1
  42. package/dist/types/current/validation/typeOfValidators.d.ts.map +1 -1
  43. package/dist/types/current/validation/typeOfValidators.js +13 -1
  44. package/dist/types/current/validation/validators.d.ts.map +1 -1
  45. package/dist/types/current/validation/validators.js +1 -1
  46. package/dist/types/ts3.7/index.d.ts +15 -14
  47. package/dist/types/ts3.7/validation/JsonSchema.d.ts +63 -0
  48. package/dist/types/ts3.7/validation/ObjectSchema.d.ts +2 -2
  49. package/dist/types/ts3.7/validation/PropertyValidator.d.ts +1 -1
  50. package/dist/types/ts3.7/validation/SchemaBase.d.ts +18 -1
  51. package/dist/types/ts3.7/validation/Validator.d.ts +14 -2
  52. package/dist/types/ts3.7/validation/ValueSchema.d.ts +1 -0
  53. package/dist/types/ts4.1/index.d.ts +15 -14
  54. package/dist/types/ts4.1/validation/JsonSchema.d.ts +63 -0
  55. package/dist/types/ts4.1/validation/ObjectSchema.d.ts +2 -2
  56. package/dist/types/ts4.1/validation/PropertyValidator.d.ts +1 -1
  57. package/dist/types/ts4.1/validation/SchemaBase.d.ts +18 -1
  58. package/dist/types/ts4.1/validation/Validator.d.ts +14 -2
  59. package/dist/types/ts4.1/validation/ValueSchema.d.ts +1 -0
  60. package/dist/types/ts4.7/index.d.ts +15 -14
  61. package/dist/types/ts4.7/validation/JsonSchema.d.ts +63 -0
  62. package/dist/types/ts4.7/validation/ObjectSchema.d.ts +2 -2
  63. package/dist/types/ts4.7/validation/PropertyValidator.d.ts +1 -1
  64. package/dist/types/ts4.7/validation/SchemaBase.d.ts +23 -1
  65. package/dist/types/ts4.7/validation/Validator.d.ts +14 -2
  66. package/dist/types/ts4.7/validation/ValueSchema.d.ts +1 -0
  67. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -0
  68. package/package.json +14 -17
package/dist/index.cjs CHANGED
@@ -66,6 +66,7 @@ __export(index_exports, {
66
66
  isValidatorWithPartial: () => isValidatorWithPartial,
67
67
  maybeToDeepPartial: () => maybeToDeepPartial,
68
68
  maybeToPartial: () => maybeToPartial,
69
+ mergeJsonSchema: () => mergeJsonSchema,
69
70
  nullish: () => nullish,
70
71
  number: () => number,
71
72
  numberValidators: () => numberValidators,
@@ -80,20 +81,15 @@ __export(index_exports, {
80
81
  string: () => string,
81
82
  stringValidators: () => stringValidators,
82
83
  symbol: () => symbol,
84
+ toJsonSchema: () => toJsonSchema,
83
85
  tuple: () => tuple,
84
86
  typeOfValidators: () => typeOfValidators,
85
87
  valueValidators: () => valueValidators
86
88
  });
87
89
  module.exports = __toCommonJS(index_exports);
88
90
 
89
- // src/validation/validators.ts
90
- var import_vinyl_util14 = require("@amazon/vinyl-util");
91
-
92
- // src/validation/ArraySchema.ts
93
- var import_vinyl_util6 = require("@amazon/vinyl-util");
94
-
95
91
  // src/validation/andValidators.ts
96
- var import_vinyl_util3 = require("@amazon/vinyl-util");
92
+ var import_vinyl_util4 = require("@amazon/vinyl-util");
97
93
 
98
94
  // src/validation/Validator.ts
99
95
  var import_vinyl_util = require("@amazon/vinyl-util");
@@ -115,9 +111,10 @@ function createValidationExpectationMessage(expectationMessage, input, path, inp
115
111
  path: path.join(".")
116
112
  });
117
113
  }
118
- function createValidator(expectationMessage, isValid, inputStringify = (input) => (0, import_vinyl_util2.stringifyForPrint)(input, 500)) {
114
+ function createValidator(expectationMessage, isValid, inputStringify = (input) => (0, import_vinyl_util2.stringifyForPrint)(input, 500), jsonSchema) {
119
115
  return {
120
116
  description: expectationMessage,
117
+ jsonSchema,
121
118
  isValid(input) {
122
119
  return isValid(input);
123
120
  },
@@ -153,9 +150,10 @@ function createValidator(expectationMessage, isValid, inputStringify = (input) =
153
150
  }
154
151
  };
155
152
  }
156
- function createDeepValidator(description, validate) {
153
+ function createDeepValidator(description, validate, jsonSchema) {
157
154
  return {
158
155
  description,
156
+ jsonSchema,
159
157
  isValid(input) {
160
158
  return validate(input, { all: false }, []).length === 0;
161
159
  },
@@ -172,6 +170,39 @@ function createDeepValidator(description, validate) {
172
170
  };
173
171
  }
174
172
 
173
+ // src/validation/JsonSchema.ts
174
+ var import_vinyl_util3 = require("@amazon/vinyl-util");
175
+ function mergeJsonSchema(...fragments) {
176
+ var _a;
177
+ const merged = {};
178
+ for (const fragment of fragments) {
179
+ if (fragment == null) continue;
180
+ for (const key of (0, import_vinyl_util3.ownKeys)(fragment)) {
181
+ if (fragment[key] === void 0) continue;
182
+ if (key === "properties") {
183
+ merged.properties = __spreadValues(__spreadValues({}, merged.properties), fragment.properties);
184
+ } else if (key === "required") {
185
+ merged.required = [
186
+ .../* @__PURE__ */ new Set([
187
+ ...(_a = merged.required) != null ? _a : [],
188
+ ...fragment.required
189
+ ])
190
+ ];
191
+ } else {
192
+ merged[key] = fragment[key];
193
+ }
194
+ }
195
+ }
196
+ return merged;
197
+ }
198
+ function toJsonSchema(source) {
199
+ const provider = source;
200
+ if (typeof provider.toJsonSchema === "function") {
201
+ return provider.toJsonSchema();
202
+ }
203
+ return __spreadValues({}, source.jsonSchema);
204
+ }
205
+
175
206
  // src/validation/andValidators.ts
176
207
  var locale = {
177
208
  /**
@@ -189,7 +220,7 @@ var locale = {
189
220
  };
190
221
  function andValidators(...validators) {
191
222
  return createDeepValidator(
192
- (0, import_vinyl_util3.substitute)(locale.template, {
223
+ (0, import_vinyl_util4.substitute)(locale.template, {
193
224
  value: validators.map((v) => v.description).join(locale.separator)
194
225
  }),
195
226
  (input, options, path) => {
@@ -198,12 +229,16 @@ function andValidators(...validators) {
198
229
  if (errors.length) return errors;
199
230
  }
200
231
  return [];
201
- }
232
+ },
233
+ mergeJsonSchema(...validators.map((v) => v.jsonSchema))
202
234
  );
203
235
  }
204
236
 
237
+ // src/validation/ArraySchema.ts
238
+ var import_vinyl_util7 = require("@amazon/vinyl-util");
239
+
205
240
  // src/validation/orValidators.ts
206
- var import_vinyl_util4 = require("@amazon/vinyl-util");
241
+ var import_vinyl_util5 = require("@amazon/vinyl-util");
207
242
  var locale2 = {
208
243
  /**
209
244
  * {value} - The child validators' descriptions, joined with `separator`.
@@ -214,51 +249,62 @@ var locale2 = {
214
249
  */
215
250
  separator: " | "
216
251
  };
252
+ function unionJsonSchema(validators) {
253
+ const branches = validators.map((v) => v.jsonSchema).filter((fragment) => fragment != null);
254
+ if (branches.length === 0) return void 0;
255
+ if (branches.length === 1) return branches[0];
256
+ return { anyOf: branches };
257
+ }
217
258
  function orValidators(...validators) {
218
- const description = (0, import_vinyl_util4.substitute)(locale2.template, {
259
+ const description = (0, import_vinyl_util5.substitute)(locale2.template, {
219
260
  value: validators.map((v) => v.description).join(locale2.separator)
220
261
  });
221
- return createDeepValidator(description, (input, options, path) => {
222
- let longestErrors = [];
223
- let longestPath = 0;
224
- for (const validator of validators) {
225
- const errors = validator.validate(input, options, path);
226
- if (!errors.length) return errors;
227
- const pathLength = errors.reduce(
228
- (max, m) => Math.max(m.path.length, max),
229
- 0
230
- );
231
- if (pathLength >= longestPath) {
232
- longestErrors = errors;
233
- longestPath = pathLength;
262
+ return createDeepValidator(
263
+ description,
264
+ (input, options, path) => {
265
+ let longestErrors = [];
266
+ let longestPath = 0;
267
+ for (const validator of validators) {
268
+ const errors = validator.validate(input, options, path);
269
+ if (!errors.length) return errors;
270
+ const pathLength = errors.reduce(
271
+ (max, m) => Math.max(m.path.length, max),
272
+ 0
273
+ );
274
+ if (pathLength >= longestPath) {
275
+ longestErrors = errors;
276
+ longestPath = pathLength;
277
+ }
234
278
  }
235
- }
236
- return longestPath > path.length ? longestErrors : [
237
- {
238
- message: createValidationExpectationMessage(
239
- description,
240
- input,
279
+ return longestPath > path.length ? longestErrors : [
280
+ {
281
+ message: createValidationExpectationMessage(
282
+ description,
283
+ input,
284
+ path
285
+ ),
241
286
  path
242
- ),
243
- path
244
- }
245
- ];
246
- });
287
+ }
288
+ ];
289
+ },
290
+ unionJsonSchema(validators)
291
+ );
247
292
  }
248
293
 
249
294
  // src/validation/SchemaBase.ts
250
- var import_vinyl_util5 = require("@amazon/vinyl-util");
295
+ var import_vinyl_util6 = require("@amazon/vinyl-util");
251
296
  var requiredValidationOptions = {
252
297
  optional: false
253
298
  };
254
299
  var SchemaBase = class {
255
300
  constructor(currentValidator, previousSchema, operation) {
256
- this.currentValidator = currentValidator;
257
- this.previousSchema = previousSchema;
258
- this.operation = operation;
259
- __publicField(this, "__type", /* @__PURE__ */ (0, import_vinyl_util5.invariant)());
301
+ __publicField(this, "currentValidator", currentValidator);
302
+ __publicField(this, "previousSchema", previousSchema);
303
+ __publicField(this, "operation", operation);
304
+ __publicField(this, "__type", /* @__PURE__ */ (0, import_vinyl_util6.invariant)());
260
305
  __publicField(this, "validator");
261
306
  __publicField(this, "_options", requiredValidationOptions);
307
+ __publicField(this, "_jsonSchemaDescription");
262
308
  __publicField(this, "assert", (input, origin, path) => {
263
309
  this.validator.assert(input, origin, path);
264
310
  });
@@ -272,6 +318,39 @@ var SchemaBase = class {
272
318
  get description() {
273
319
  return this.validator.description;
274
320
  }
321
+ /**
322
+ * The composed JSON Schema fragment for this schema, including any {@link describe} description.
323
+ * Composes through chaining the same way {@link description} does; serialize a complete
324
+ * definition with {@link toJsonSchema}.
325
+ */
326
+ get jsonSchema() {
327
+ const base = this.validator.jsonSchema;
328
+ if (this._jsonSchemaDescription == null) return base;
329
+ return mergeJsonSchema(base, {
330
+ description: this._jsonSchemaDescription
331
+ });
332
+ }
333
+ /**
334
+ * Attaches a human-readable description to this schema, akin to zod's `describe`.
335
+ * The description is metadata only; it does not affect validation, and surfaces in the output
336
+ * of {@link toJsonSchema}.
337
+ *
338
+ * @param description The description to attach.
339
+ * @return A clone of this schema carrying the description.
340
+ */
341
+ describe(description) {
342
+ const cloned = this.clone();
343
+ cloned._jsonSchemaDescription = description;
344
+ return cloned;
345
+ }
346
+ /**
347
+ * Serializes this schema to a JSON Schema definition, suitable for describing the shape to an
348
+ * LLM or other consumer. Works similarly to zod-to-json-schema.
349
+ */
350
+ toJsonSchema() {
351
+ var _a;
352
+ return (_a = this.jsonSchema) != null ? _a : {};
353
+ }
275
354
  /**
276
355
  * Clones this schema, transforming all validators with the given mutator.
277
356
  *
@@ -286,11 +365,12 @@ var SchemaBase = class {
286
365
  this.operation
287
366
  ) : this.self(transform(this.currentValidator));
288
367
  cloned._options = this._options;
368
+ cloned._jsonSchemaDescription = this._jsonSchemaDescription;
289
369
  return cloned;
290
370
  }
291
371
  self(current, previous, operation) {
292
372
  if (this.constructor.length > 3) {
293
- throw new import_vinyl_util5.IllegalArgumentError(
373
+ throw new import_vinyl_util6.IllegalArgumentError(
294
374
  "constructor should have at most three required arguments"
295
375
  );
296
376
  }
@@ -335,15 +415,30 @@ var valueValidators = {
335
415
  },
336
416
  /**
337
417
  * Creates a validator that asserts that the input is nullish.
418
+ * JSON Schema has no representation for `undefined`, so only `null` is expressed.
338
419
  */
339
420
  nullish() {
340
- return createValidator(locale3.nullish, (input) => input == null);
421
+ return createValidator(
422
+ locale3.nullish,
423
+ (input) => input == null,
424
+ void 0,
425
+ {
426
+ type: "null"
427
+ }
428
+ );
341
429
  },
342
430
  /**
343
431
  * Creates a validator that asserts that the input is strictly null.
344
432
  */
345
433
  null() {
346
- return createValidator(locale3.null, (input) => input === null);
434
+ return createValidator(
435
+ locale3.null,
436
+ (input) => input === null,
437
+ void 0,
438
+ {
439
+ type: "null"
440
+ }
441
+ );
347
442
  },
348
443
  /**
349
444
  * Creates a validator that asserts that the input is strictly undefined.
@@ -418,7 +513,9 @@ var arrayValidators = {
418
513
  isArray() {
419
514
  return createValidator(
420
515
  locale4.array,
421
- (input) => Array.isArray(input)
516
+ (input) => Array.isArray(input),
517
+ void 0,
518
+ { type: "array" }
422
519
  );
423
520
  },
424
521
  /**
@@ -428,7 +525,7 @@ var arrayValidators = {
428
525
  */
429
526
  withElements(elementValidator) {
430
527
  return createDeepValidator(
431
- (0, import_vinyl_util6.substitute)(locale4.withElements, {
528
+ (0, import_vinyl_util7.substitute)(locale4.withElements, {
432
529
  value: elementValidator.description
433
530
  }),
434
531
  (input, options, path) => {
@@ -445,7 +542,8 @@ var arrayValidators = {
445
542
  if (!options.all && errors.length) return errors;
446
543
  }
447
544
  return errors;
448
- }
545
+ },
546
+ { type: "array", items: toJsonSchema(elementValidator) }
449
547
  );
450
548
  },
451
549
  /**
@@ -456,13 +554,13 @@ var arrayValidators = {
456
554
  */
457
555
  tuple(...validators) {
458
556
  const lengthValidator = createValidator(
459
- (0, import_vinyl_util6.substitute)(locale4.exactlyLength, {
557
+ (0, import_vinyl_util7.substitute)(locale4.exactlyLength, {
460
558
  value: validators.length
461
559
  }),
462
560
  (length) => length === validators.length
463
561
  );
464
562
  return createDeepValidator(
465
- (0, import_vinyl_util6.substitute)(locale4.tuple, { value: validators.join(", ") }),
563
+ (0, import_vinyl_util7.substitute)(locale4.tuple, { value: validators.join(", ") }),
466
564
  (input, options, path) => {
467
565
  const errors = [];
468
566
  errors.push(
@@ -483,6 +581,13 @@ var arrayValidators = {
483
581
  if (!options.all && errors.length) return errors;
484
582
  }
485
583
  return errors;
584
+ },
585
+ {
586
+ type: "array",
587
+ items: validators.map((v) => toJsonSchema(v)),
588
+ minItems: validators.length,
589
+ maxItems: validators.length,
590
+ additionalItems: false
486
591
  }
487
592
  );
488
593
  },
@@ -492,9 +597,10 @@ var arrayValidators = {
492
597
  */
493
598
  minLength(min) {
494
599
  return createValidator(
495
- (0, import_vinyl_util6.substitute)(locale4.minLength, { value: min }),
600
+ (0, import_vinyl_util7.substitute)(locale4.minLength, { value: min }),
496
601
  (input) => input.length >= min,
497
- (input) => (0, import_vinyl_util6.substitute)(locale4.actualLength, { value: input.length })
602
+ (input) => (0, import_vinyl_util7.substitute)(locale4.actualLength, { value: input.length }),
603
+ { minItems: min }
498
604
  );
499
605
  },
500
606
  /**
@@ -504,9 +610,10 @@ var arrayValidators = {
504
610
  */
505
611
  maxLength(max) {
506
612
  return createValidator(
507
- (0, import_vinyl_util6.substitute)(locale4.maxLength, { value: max }),
613
+ (0, import_vinyl_util7.substitute)(locale4.maxLength, { value: max }),
508
614
  (input) => input.length <= max,
509
- (input) => (0, import_vinyl_util6.substitute)(locale4.actualLength, { value: input.length })
615
+ (input) => (0, import_vinyl_util7.substitute)(locale4.actualLength, { value: input.length }),
616
+ { maxItems: max }
510
617
  );
511
618
  }
512
619
  };
@@ -569,19 +676,29 @@ __publicField(_ArraySchema, "_base", null);
569
676
  var ArraySchema = _ArraySchema;
570
677
 
571
678
  // src/validation/FunctionSchema.ts
572
- var import_vinyl_util8 = require("@amazon/vinyl-util");
679
+ var import_vinyl_util9 = require("@amazon/vinyl-util");
573
680
 
574
681
  // src/validation/typeOfValidators.ts
575
- var import_vinyl_util7 = require("@amazon/vinyl-util");
682
+ var import_vinyl_util8 = require("@amazon/vinyl-util");
576
683
  var locale5 = {
577
684
  template: "type {value}"
578
685
  };
686
+ var jsonSchemaTypeByTypeof = {
687
+ string: "string",
688
+ number: "number",
689
+ boolean: "boolean",
690
+ object: "object"
691
+ };
579
692
  function typeOfValidator(expected) {
693
+ const jsonType = jsonSchemaTypeByTypeof[expected];
694
+ const jsonSchema = jsonType == null ? void 0 : { type: jsonType };
580
695
  return createValidator(
581
- (0, import_vinyl_util7.substitute)(locale5.template, { value: expected }),
696
+ (0, import_vinyl_util8.substitute)(locale5.template, { value: expected }),
582
697
  (input) => {
583
698
  return input != null && typeof input === expected;
584
- }
699
+ },
700
+ void 0,
701
+ jsonSchema
585
702
  );
586
703
  }
587
704
  var typeOfValidatorCache = {};
@@ -620,9 +737,9 @@ var locale6 = {
620
737
  var functionValidators = {
621
738
  length(max) {
622
739
  return createValidator(
623
- (0, import_vinyl_util8.substitute)(locale6.length, { value: max }),
740
+ (0, import_vinyl_util9.substitute)(locale6.length, { value: max }),
624
741
  (input) => input.length <= max,
625
- (input) => (0, import_vinyl_util8.substitute)(locale6.actualLength, { value: input.length })
742
+ (input) => (0, import_vinyl_util9.substitute)(locale6.actualLength, { value: input.length })
626
743
  );
627
744
  }
628
745
  };
@@ -650,88 +767,9 @@ var _FunctionSchema = class _FunctionSchema extends ValueSchema {
650
767
  __publicField(_FunctionSchema, "_base", null);
651
768
  var FunctionSchema = _FunctionSchema;
652
769
 
653
- // src/validation/SetSchema.ts
654
- var import_vinyl_util9 = require("@amazon/vinyl-util");
655
- var locale7 = {
656
- set: "Set",
657
- withElements: "Set<{value}>"
658
- };
659
- var setValidators = {
660
- /**
661
- * Creates a validator that asserts that the input is a set.
662
- */
663
- isSet() {
664
- return createValidator(
665
- locale7.set,
666
- (input) => input instanceof Set
667
- );
668
- },
669
- /**
670
- * Creates a validator that asserts that every element passes the given validator.
671
- *
672
- * @param elementValidator
673
- */
674
- withElements(elementValidator) {
675
- return createDeepValidator(
676
- (0, import_vinyl_util9.substitute)(locale7.withElements, {
677
- value: elementValidator.description
678
- }),
679
- (input, options, path) => {
680
- const errors = [];
681
- let i = 0;
682
- for (const element of input) {
683
- errors.push(
684
- ...elementValidator.validate(
685
- element,
686
- options,
687
- path.concat(i.toString())
688
- )
689
- );
690
- if (!options.all && errors.length) return errors;
691
- i++;
692
- }
693
- return errors;
694
- }
695
- );
696
- }
697
- };
698
- var _SetSchema = class _SetSchema extends ValueSchema {
699
- /**
700
- * The base SetSchema instance validating that the input is a Set.
701
- */
702
- static get base() {
703
- if (this._base == null)
704
- this._base = new _SetSchema(setValidators.isSet());
705
- return this._base;
706
- }
707
- /**
708
- * Creates a validator that asserts that every element passes the given validator.
709
- *
710
- * @param elementValidator
711
- */
712
- withElements(elementValidator) {
713
- return this.chain(setValidators.withElements(elementValidator));
714
- }
715
- /**
716
- * Casts to a readonly set.
717
- * This is a shallow cast, elements of the array will not be changed.
718
- */
719
- readonly() {
720
- return this;
721
- }
722
- /**
723
- * Casts the parameter type.
724
- */
725
- cast() {
726
- return this;
727
- }
728
- };
729
- __publicField(_SetSchema, "_base", null);
730
- var SetSchema = _SetSchema;
731
-
732
770
  // src/validation/NumberSchema.ts
733
771
  var import_vinyl_util10 = require("@amazon/vinyl-util");
734
- var locale8 = {
772
+ var locale7 = {
735
773
  gte: "at least {value}",
736
774
  gt: "greater than {value}",
737
775
  lte: "at most {value}",
@@ -749,8 +787,10 @@ var numberValidators = {
749
787
  */
750
788
  gte(min) {
751
789
  return createValidator(
752
- (0, import_vinyl_util10.substitute)(locale8.gte, { value: min }),
753
- (input) => input >= min
790
+ (0, import_vinyl_util10.substitute)(locale7.gte, { value: min }),
791
+ (input) => input >= min,
792
+ void 0,
793
+ { minimum: min }
754
794
  );
755
795
  },
756
796
  /**
@@ -761,8 +801,10 @@ var numberValidators = {
761
801
  */
762
802
  gt(min) {
763
803
  return createValidator(
764
- (0, import_vinyl_util10.substitute)(locale8.gt, { value: min }),
765
- (input) => input > min
804
+ (0, import_vinyl_util10.substitute)(locale7.gt, { value: min }),
805
+ (input) => input > min,
806
+ void 0,
807
+ { exclusiveMinimum: min }
766
808
  );
767
809
  },
768
810
  /**
@@ -773,8 +815,10 @@ var numberValidators = {
773
815
  */
774
816
  lte(max) {
775
817
  return createValidator(
776
- (0, import_vinyl_util10.substitute)(locale8.lte, { value: max }),
777
- (input) => input <= max
818
+ (0, import_vinyl_util10.substitute)(locale7.lte, { value: max }),
819
+ (input) => input <= max,
820
+ void 0,
821
+ { maximum: max }
778
822
  );
779
823
  },
780
824
  /**
@@ -785,8 +829,10 @@ var numberValidators = {
785
829
  */
786
830
  lt(max) {
787
831
  return createValidator(
788
- (0, import_vinyl_util10.substitute)(locale8.lt, { value: max }),
789
- (input) => input < max
832
+ (0, import_vinyl_util10.substitute)(locale7.lt, { value: max }),
833
+ (input) => input < max,
834
+ void 0,
835
+ { exclusiveMaximum: max }
790
836
  );
791
837
  },
792
838
  /**
@@ -798,23 +844,27 @@ var numberValidators = {
798
844
  */
799
845
  within(min, max) {
800
846
  return createValidator(
801
- (0, import_vinyl_util10.substitute)(locale8.within, { min, max }),
802
- (input) => input >= min && input <= max
847
+ (0, import_vinyl_util10.substitute)(locale7.within, { min, max }),
848
+ (input) => input >= min && input <= max,
849
+ void 0,
850
+ { minimum: min, maximum: max }
803
851
  );
804
852
  },
805
853
  /**
806
854
  * Creates a validator that asserts that the input number is finite.
807
855
  */
808
856
  finite() {
809
- return createValidator(locale8.finite, (input) => Number.isFinite(input));
857
+ return createValidator(locale7.finite, (input) => Number.isFinite(input));
810
858
  },
811
859
  /**
812
860
  * Creates a validator that asserts that the input number is a safe integer.
813
861
  */
814
862
  safeInteger() {
815
863
  return createValidator(
816
- locale8.safeInteger,
817
- (input) => Number.isSafeInteger(input)
864
+ locale7.safeInteger,
865
+ (input) => Number.isSafeInteger(input),
866
+ void 0,
867
+ { type: "integer" }
818
868
  );
819
869
  }
820
870
  };
@@ -904,7 +954,7 @@ function maybeToPartial(validator) {
904
954
  }
905
955
 
906
956
  // src/validation/ObjectSchema.ts
907
- var locale9 = {
957
+ var locale8 = {
908
958
  extend: "{\n{body}\n}",
909
959
  prop: "{key}: {value}",
910
960
  propSeparator: ",\n",
@@ -921,18 +971,26 @@ var objectValidators = {
921
971
  properties(propertyValidators) {
922
972
  const propertiesDescriptions = [];
923
973
  const keys = (0, import_vinyl_util11.ownKeys)(propertyValidators);
974
+ const jsonProperties = {};
975
+ const requiredKeys = [];
924
976
  for (const key of keys) {
925
977
  const validator2 = propertyValidators[key];
926
978
  propertiesDescriptions.push(
927
- (0, import_vinyl_util11.substitute)(locale9.prop, {
979
+ (0, import_vinyl_util11.substitute)(locale8.prop, {
928
980
  key: String(key) + (validator2.options.optional ? "?" : ""),
929
981
  value: validator2.description
930
982
  })
931
983
  );
984
+ jsonProperties[String(key)] = toJsonSchema(validator2);
985
+ if (!validator2.options.optional) requiredKeys.push(String(key));
932
986
  }
933
- const description = (0, import_vinyl_util11.substitute)(locale9.extend, {
934
- body: propertiesDescriptions.join(locale9.propSeparator).split("\n").map((line) => locale9.indent + line).join("\n")
987
+ const description = (0, import_vinyl_util11.substitute)(locale8.extend, {
988
+ body: propertiesDescriptions.join(locale8.propSeparator).split("\n").map((line) => locale8.indent + line).join("\n")
935
989
  });
990
+ const jsonSchema = __spreadValues({
991
+ type: "object",
992
+ properties: jsonProperties
993
+ }, requiredKeys.length ? { required: requiredKeys } : {});
936
994
  const validator = createDeepValidator(
937
995
  description,
938
996
  (input, options, path) => {
@@ -951,7 +1009,7 @@ var objectValidators = {
951
1009
  } else {
952
1010
  if (!validator2.options.optional) {
953
1011
  errors.push({
954
- message: (0, import_vinyl_util11.substitute)(locale9.required, { key }),
1012
+ message: (0, import_vinyl_util11.substitute)(locale8.required, { key }),
955
1013
  path: path.concat(String(key))
956
1014
  });
957
1015
  }
@@ -959,7 +1017,8 @@ var objectValidators = {
959
1017
  if (!options.all && errors.length) return errors;
960
1018
  }
961
1019
  return errors;
962
- }
1020
+ },
1021
+ jsonSchema
963
1022
  );
964
1023
  return (0, import_vinyl_util11.merge)(validator, {
965
1024
  partial() {
@@ -1030,7 +1089,7 @@ var import_vinyl_util13 = require("@amazon/vinyl-util");
1030
1089
 
1031
1090
  // src/validation/StringSchema.ts
1032
1091
  var import_vinyl_util12 = require("@amazon/vinyl-util");
1033
- var locale10 = {
1092
+ var locale9 = {
1034
1093
  notEmpty: "not empty",
1035
1094
  minLength: "at least {value} characters",
1036
1095
  maxLength: "at most {value} characters",
@@ -1042,7 +1101,12 @@ var stringValidators = {
1042
1101
  * Creates a validator that asserts that the input is not empty.
1043
1102
  */
1044
1103
  notEmpty() {
1045
- return createValidator(locale10.notEmpty, (input) => input !== "");
1104
+ return createValidator(
1105
+ locale9.notEmpty,
1106
+ (input) => input !== "",
1107
+ void 0,
1108
+ { minLength: 1 }
1109
+ );
1046
1110
  },
1047
1111
  /**
1048
1112
  * Creates a validator that asserts that the input string has at least the given minimum
@@ -1052,8 +1116,10 @@ var stringValidators = {
1052
1116
  */
1053
1117
  minLength(min) {
1054
1118
  return createValidator(
1055
- (0, import_vinyl_util12.substitute)(locale10.minLength, { value: min }),
1056
- (input) => input.length >= min
1119
+ (0, import_vinyl_util12.substitute)(locale9.minLength, { value: min }),
1120
+ (input) => input.length >= min,
1121
+ void 0,
1122
+ { minLength: min }
1057
1123
  );
1058
1124
  },
1059
1125
  /**
@@ -1064,8 +1130,10 @@ var stringValidators = {
1064
1130
  */
1065
1131
  maxLength(max) {
1066
1132
  return createValidator(
1067
- (0, import_vinyl_util12.substitute)(locale10.maxLength, { value: max }),
1068
- (input) => input.length <= max
1133
+ (0, import_vinyl_util12.substitute)(locale9.maxLength, { value: max }),
1134
+ (input) => input.length <= max,
1135
+ void 0,
1136
+ { maxLength: max }
1069
1137
  );
1070
1138
  },
1071
1139
  /**
@@ -1074,7 +1142,7 @@ var stringValidators = {
1074
1142
  */
1075
1143
  noWhitespace() {
1076
1144
  return createValidator(
1077
- locale10.noWhitespace,
1145
+ locale9.noWhitespace,
1078
1146
  (input) => input.search(/\s/g) === -1
1079
1147
  );
1080
1148
  },
@@ -1084,10 +1152,12 @@ var stringValidators = {
1084
1152
  */
1085
1153
  matches(regex) {
1086
1154
  return createValidator(
1087
- (0, import_vinyl_util12.substitute)(locale10.matches, { value: regex.toString() }),
1155
+ (0, import_vinyl_util12.substitute)(locale9.matches, { value: regex.toString() }),
1088
1156
  (input) => {
1089
1157
  return regex.test(input);
1090
- }
1158
+ },
1159
+ void 0,
1160
+ { pattern: regex.source }
1091
1161
  );
1092
1162
  }
1093
1163
  };
@@ -1143,7 +1213,7 @@ __publicField(_StringSchema, "_base", null);
1143
1213
  var StringSchema = _StringSchema;
1144
1214
 
1145
1215
  // src/validation/RecordSchema.ts
1146
- var locale11 = {
1216
+ var locale10 = {
1147
1217
  record: "{ [key: {key}]: {value} }"
1148
1218
  };
1149
1219
  var recordValidators = {
@@ -1160,7 +1230,7 @@ var recordValidators = {
1160
1230
  */
1161
1231
  record(keyValidator, valueValidator) {
1162
1232
  return createDeepValidator(
1163
- (0, import_vinyl_util13.substitute)(locale11.record, {
1233
+ (0, import_vinyl_util13.substitute)(locale10.record, {
1164
1234
  key: keyValidator.description,
1165
1235
  value: valueValidator.description
1166
1236
  }),
@@ -1187,6 +1257,10 @@ var recordValidators = {
1187
1257
  if (!options.all && errors.length) return errors;
1188
1258
  }
1189
1259
  return errors;
1260
+ },
1261
+ {
1262
+ type: "object",
1263
+ additionalProperties: toJsonSchema(valueValidator)
1190
1264
  }
1191
1265
  );
1192
1266
  }
@@ -1244,7 +1318,94 @@ var _RecordSchema = class _RecordSchema extends ValueSchema {
1244
1318
  __publicField(_RecordSchema, "_base", null);
1245
1319
  var RecordSchema = _RecordSchema;
1246
1320
 
1321
+ // src/validation/SetSchema.ts
1322
+ var import_vinyl_util14 = require("@amazon/vinyl-util");
1323
+ var locale11 = {
1324
+ set: "Set",
1325
+ withElements: "Set<{value}>"
1326
+ };
1327
+ var setValidators = {
1328
+ /**
1329
+ * Creates a validator that asserts that the input is a set.
1330
+ */
1331
+ isSet() {
1332
+ return createValidator(
1333
+ locale11.set,
1334
+ (input) => input instanceof Set,
1335
+ void 0,
1336
+ { type: "array", uniqueItems: true }
1337
+ );
1338
+ },
1339
+ /**
1340
+ * Creates a validator that asserts that every element passes the given validator.
1341
+ *
1342
+ * @param elementValidator
1343
+ */
1344
+ withElements(elementValidator) {
1345
+ return createDeepValidator(
1346
+ (0, import_vinyl_util14.substitute)(locale11.withElements, {
1347
+ value: elementValidator.description
1348
+ }),
1349
+ (input, options, path) => {
1350
+ const errors = [];
1351
+ let i = 0;
1352
+ for (const element of input) {
1353
+ errors.push(
1354
+ ...elementValidator.validate(
1355
+ element,
1356
+ options,
1357
+ path.concat(i.toString())
1358
+ )
1359
+ );
1360
+ if (!options.all && errors.length) return errors;
1361
+ i++;
1362
+ }
1363
+ return errors;
1364
+ },
1365
+ {
1366
+ type: "array",
1367
+ uniqueItems: true,
1368
+ items: toJsonSchema(elementValidator)
1369
+ }
1370
+ );
1371
+ }
1372
+ };
1373
+ var _SetSchema = class _SetSchema extends ValueSchema {
1374
+ /**
1375
+ * The base SetSchema instance validating that the input is a Set.
1376
+ */
1377
+ static get base() {
1378
+ if (this._base == null)
1379
+ this._base = new _SetSchema(setValidators.isSet());
1380
+ return this._base;
1381
+ }
1382
+ /**
1383
+ * Creates a validator that asserts that every element passes the given validator.
1384
+ *
1385
+ * @param elementValidator
1386
+ */
1387
+ withElements(elementValidator) {
1388
+ return this.chain(setValidators.withElements(elementValidator));
1389
+ }
1390
+ /**
1391
+ * Casts to a readonly set.
1392
+ * This is a shallow cast, elements of the array will not be changed.
1393
+ */
1394
+ readonly() {
1395
+ return this;
1396
+ }
1397
+ /**
1398
+ * Casts the parameter type.
1399
+ */
1400
+ cast() {
1401
+ return this;
1402
+ }
1403
+ };
1404
+ __publicField(_SetSchema, "_base", null);
1405
+ var SetSchema = _SetSchema;
1406
+
1247
1407
  // src/validation/validators.ts
1408
+ var import_vinyl_util15 = require("@amazon/vinyl-util");
1248
1409
  var locale12 = {
1249
1410
  isOneOf: "one of: {value}",
1250
1411
  instanceOf: "instance of {value}",
@@ -1266,7 +1427,7 @@ function func() {
1266
1427
  function instanceOf(clazz) {
1267
1428
  return new ValueSchema(
1268
1429
  createValidator(
1269
- (0, import_vinyl_util14.substitute)(locale12.instanceOf, { value: clazz.name }),
1430
+ (0, import_vinyl_util15.substitute)(locale12.instanceOf, { value: clazz.name }),
1270
1431
  (input) => input instanceof clazz
1271
1432
  )
1272
1433
  );
@@ -1274,10 +1435,12 @@ function instanceOf(clazz) {
1274
1435
  function isOneOf(...possibleValues) {
1275
1436
  return new ValueSchema(
1276
1437
  createValidator(
1277
- (0, import_vinyl_util14.substitute)(locale12.isOneOf, {
1438
+ (0, import_vinyl_util15.substitute)(locale12.isOneOf, {
1278
1439
  value: possibleValues.join(locale12.oneOfSeparator)
1279
1440
  }),
1280
- (input) => possibleValues.includes(input)
1441
+ (input) => possibleValues.includes(input),
1442
+ void 0,
1443
+ { enum: [...possibleValues] }
1281
1444
  )
1282
1445
  );
1283
1446
  }
@@ -1317,7 +1480,7 @@ function symbol() {
1317
1480
  function exactlyUndefined() {
1318
1481
  return new ValueSchema(valueValidators.undefined());
1319
1482
  }
1320
- function custom(expectationMessage, isValid, inputStringify = (input) => (0, import_vinyl_util14.stringifyForPrint)(input, 500)) {
1483
+ function custom(expectationMessage, isValid, inputStringify = (input) => (0, import_vinyl_util15.stringifyForPrint)(input, 500)) {
1321
1484
  return new ValueSchema(
1322
1485
  createValidator(expectationMessage, isValid, inputStringify)
1323
1486
  );