@amazon/vinyl-validation 1.2.0 → 2.0.4

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 (58) hide show
  1. package/README.md +42 -0
  2. package/dist/index.cjs +334 -171
  3. package/dist/index.cjs.map +4 -4
  4. package/dist/index.js +322 -159
  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/JsonSchema.d.ts +63 -0
  13. package/dist/types/current/validation/JsonSchema.d.ts.map +1 -0
  14. package/dist/types/current/validation/JsonSchema.js +59 -0
  15. package/dist/types/current/validation/NumberSchema.d.ts.map +1 -1
  16. package/dist/types/current/validation/NumberSchema.js +6 -6
  17. package/dist/types/current/validation/ObjectSchema.d.ts.map +1 -1
  18. package/dist/types/current/validation/ObjectSchema.js +12 -1
  19. package/dist/types/current/validation/RecordSchema.d.ts.map +1 -1
  20. package/dist/types/current/validation/RecordSchema.js +4 -0
  21. package/dist/types/current/validation/SchemaBase.d.ts +23 -1
  22. package/dist/types/current/validation/SchemaBase.d.ts.map +1 -1
  23. package/dist/types/current/validation/SchemaBase.js +36 -0
  24. package/dist/types/current/validation/SetSchema.d.ts.map +1 -1
  25. package/dist/types/current/validation/SetSchema.js +6 -1
  26. package/dist/types/current/validation/StringSchema.d.ts.map +1 -1
  27. package/dist/types/current/validation/StringSchema.js +4 -4
  28. package/dist/types/current/validation/Validator.d.ts +14 -2
  29. package/dist/types/current/validation/Validator.d.ts.map +1 -1
  30. package/dist/types/current/validation/Validator.js +6 -2
  31. package/dist/types/current/validation/ValueSchema.d.ts +1 -0
  32. package/dist/types/current/validation/ValueSchema.d.ts.map +1 -1
  33. package/dist/types/current/validation/ValueSchema.js +7 -2
  34. package/dist/types/current/validation/andValidators.d.ts.map +1 -1
  35. package/dist/types/current/validation/andValidators.js +2 -1
  36. package/dist/types/current/validation/orValidators.d.ts.map +1 -1
  37. package/dist/types/current/validation/orValidators.js +18 -1
  38. package/dist/types/current/validation/typeOfValidators.d.ts.map +1 -1
  39. package/dist/types/current/validation/typeOfValidators.js +13 -1
  40. package/dist/types/current/validation/validators.d.ts.map +1 -1
  41. package/dist/types/current/validation/validators.js +1 -1
  42. package/dist/types/ts3.7/index.d.ts +15 -14
  43. package/dist/types/ts3.7/validation/JsonSchema.d.ts +63 -0
  44. package/dist/types/ts3.7/validation/SchemaBase.d.ts +18 -1
  45. package/dist/types/ts3.7/validation/Validator.d.ts +14 -2
  46. package/dist/types/ts3.7/validation/ValueSchema.d.ts +1 -0
  47. package/dist/types/ts4.1/index.d.ts +15 -14
  48. package/dist/types/ts4.1/validation/JsonSchema.d.ts +63 -0
  49. package/dist/types/ts4.1/validation/SchemaBase.d.ts +18 -1
  50. package/dist/types/ts4.1/validation/Validator.d.ts +14 -2
  51. package/dist/types/ts4.1/validation/ValueSchema.d.ts +1 -0
  52. package/dist/types/ts4.7/index.d.ts +15 -14
  53. package/dist/types/ts4.7/validation/JsonSchema.d.ts +63 -0
  54. package/dist/types/ts4.7/validation/SchemaBase.d.ts +23 -1
  55. package/dist/types/ts4.7/validation/Validator.d.ts +14 -2
  56. package/dist/types/ts4.7/validation/ValueSchema.d.ts +1 -0
  57. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  58. package/package.json +13 -12
package/dist/index.js CHANGED
@@ -19,15 +19,6 @@ var __spreadValues = (a, b) => {
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
20
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
21
 
22
- // src/validation/validators.ts
23
- import {
24
- stringifyForPrint as stringifyForPrint2,
25
- substitute as substitute12
26
- } from "@amazon/vinyl-util";
27
-
28
- // src/validation/ArraySchema.ts
29
- import { substitute as substitute4 } from "@amazon/vinyl-util";
30
-
31
22
  // src/validation/andValidators.ts
32
23
  import { substitute as substitute2 } from "@amazon/vinyl-util";
33
24
 
@@ -51,9 +42,10 @@ function createValidationExpectationMessage(expectationMessage, input, path, inp
51
42
  path: path.join(".")
52
43
  });
53
44
  }
54
- function createValidator(expectationMessage, isValid, inputStringify = (input) => stringifyForPrint(input, 500)) {
45
+ function createValidator(expectationMessage, isValid, inputStringify = (input) => stringifyForPrint(input, 500), jsonSchema) {
55
46
  return {
56
47
  description: expectationMessage,
48
+ jsonSchema,
57
49
  isValid(input) {
58
50
  return isValid(input);
59
51
  },
@@ -89,9 +81,10 @@ function createValidator(expectationMessage, isValid, inputStringify = (input) =
89
81
  }
90
82
  };
91
83
  }
92
- function createDeepValidator(description, validate) {
84
+ function createDeepValidator(description, validate, jsonSchema) {
93
85
  return {
94
86
  description,
87
+ jsonSchema,
95
88
  isValid(input) {
96
89
  return validate(input, { all: false }, []).length === 0;
97
90
  },
@@ -108,6 +101,39 @@ function createDeepValidator(description, validate) {
108
101
  };
109
102
  }
110
103
 
104
+ // src/validation/JsonSchema.ts
105
+ import { ownKeys } from "@amazon/vinyl-util";
106
+ function mergeJsonSchema(...fragments) {
107
+ var _a;
108
+ const merged = {};
109
+ for (const fragment of fragments) {
110
+ if (fragment == null) continue;
111
+ for (const key of ownKeys(fragment)) {
112
+ if (fragment[key] === void 0) continue;
113
+ if (key === "properties") {
114
+ merged.properties = __spreadValues(__spreadValues({}, merged.properties), fragment.properties);
115
+ } else if (key === "required") {
116
+ merged.required = [
117
+ .../* @__PURE__ */ new Set([
118
+ ...(_a = merged.required) != null ? _a : [],
119
+ ...fragment.required
120
+ ])
121
+ ];
122
+ } else {
123
+ merged[key] = fragment[key];
124
+ }
125
+ }
126
+ }
127
+ return merged;
128
+ }
129
+ function toJsonSchema(source) {
130
+ const provider = source;
131
+ if (typeof provider.toJsonSchema === "function") {
132
+ return provider.toJsonSchema();
133
+ }
134
+ return __spreadValues({}, source.jsonSchema);
135
+ }
136
+
111
137
  // src/validation/andValidators.ts
112
138
  var locale = {
113
139
  /**
@@ -134,10 +160,14 @@ function andValidators(...validators) {
134
160
  if (errors.length) return errors;
135
161
  }
136
162
  return [];
137
- }
163
+ },
164
+ mergeJsonSchema(...validators.map((v) => v.jsonSchema))
138
165
  );
139
166
  }
140
167
 
168
+ // src/validation/ArraySchema.ts
169
+ import { substitute as substitute4 } from "@amazon/vinyl-util";
170
+
141
171
  // src/validation/orValidators.ts
142
172
  import { substitute as substitute3 } from "@amazon/vinyl-util";
143
173
  var locale2 = {
@@ -150,36 +180,46 @@ var locale2 = {
150
180
  */
151
181
  separator: " | "
152
182
  };
183
+ function unionJsonSchema(validators) {
184
+ const branches = validators.map((v) => v.jsonSchema).filter((fragment) => fragment != null);
185
+ if (branches.length === 0) return void 0;
186
+ if (branches.length === 1) return branches[0];
187
+ return { anyOf: branches };
188
+ }
153
189
  function orValidators(...validators) {
154
190
  const description = substitute3(locale2.template, {
155
191
  value: validators.map((v) => v.description).join(locale2.separator)
156
192
  });
157
- return createDeepValidator(description, (input, options, path) => {
158
- let longestErrors = [];
159
- let longestPath = 0;
160
- for (const validator of validators) {
161
- const errors = validator.validate(input, options, path);
162
- if (!errors.length) return errors;
163
- const pathLength = errors.reduce(
164
- (max, m) => Math.max(m.path.length, max),
165
- 0
166
- );
167
- if (pathLength >= longestPath) {
168
- longestErrors = errors;
169
- longestPath = pathLength;
193
+ return createDeepValidator(
194
+ description,
195
+ (input, options, path) => {
196
+ let longestErrors = [];
197
+ let longestPath = 0;
198
+ for (const validator of validators) {
199
+ const errors = validator.validate(input, options, path);
200
+ if (!errors.length) return errors;
201
+ const pathLength = errors.reduce(
202
+ (max, m) => Math.max(m.path.length, max),
203
+ 0
204
+ );
205
+ if (pathLength >= longestPath) {
206
+ longestErrors = errors;
207
+ longestPath = pathLength;
208
+ }
170
209
  }
171
- }
172
- return longestPath > path.length ? longestErrors : [
173
- {
174
- message: createValidationExpectationMessage(
175
- description,
176
- input,
210
+ return longestPath > path.length ? longestErrors : [
211
+ {
212
+ message: createValidationExpectationMessage(
213
+ description,
214
+ input,
215
+ path
216
+ ),
177
217
  path
178
- ),
179
- path
180
- }
181
- ];
182
- });
218
+ }
219
+ ];
220
+ },
221
+ unionJsonSchema(validators)
222
+ );
183
223
  }
184
224
 
185
225
  // src/validation/SchemaBase.ts
@@ -195,6 +235,7 @@ var SchemaBase = class {
195
235
  __publicField(this, "__type", /* @__PURE__ */ invariant());
196
236
  __publicField(this, "validator");
197
237
  __publicField(this, "_options", requiredValidationOptions);
238
+ __publicField(this, "_jsonSchemaDescription");
198
239
  __publicField(this, "assert", (input, origin, path) => {
199
240
  this.validator.assert(input, origin, path);
200
241
  });
@@ -208,6 +249,39 @@ var SchemaBase = class {
208
249
  get description() {
209
250
  return this.validator.description;
210
251
  }
252
+ /**
253
+ * The composed JSON Schema fragment for this schema, including any {@link describe} description.
254
+ * Composes through chaining the same way {@link description} does; serialize a complete
255
+ * definition with {@link toJsonSchema}.
256
+ */
257
+ get jsonSchema() {
258
+ const base = this.validator.jsonSchema;
259
+ if (this._jsonSchemaDescription == null) return base;
260
+ return mergeJsonSchema(base, {
261
+ description: this._jsonSchemaDescription
262
+ });
263
+ }
264
+ /**
265
+ * Attaches a human-readable description to this schema, akin to zod's `describe`.
266
+ * The description is metadata only; it does not affect validation, and surfaces in the output
267
+ * of {@link toJsonSchema}.
268
+ *
269
+ * @param description The description to attach.
270
+ * @return A clone of this schema carrying the description.
271
+ */
272
+ describe(description) {
273
+ const cloned = this.clone();
274
+ cloned._jsonSchemaDescription = description;
275
+ return cloned;
276
+ }
277
+ /**
278
+ * Serializes this schema to a JSON Schema definition, suitable for describing the shape to an
279
+ * LLM or other consumer. Works similarly to zod-to-json-schema.
280
+ */
281
+ toJsonSchema() {
282
+ var _a;
283
+ return (_a = this.jsonSchema) != null ? _a : {};
284
+ }
211
285
  /**
212
286
  * Clones this schema, transforming all validators with the given mutator.
213
287
  *
@@ -222,6 +296,7 @@ var SchemaBase = class {
222
296
  this.operation
223
297
  ) : this.self(transform(this.currentValidator));
224
298
  cloned._options = this._options;
299
+ cloned._jsonSchemaDescription = this._jsonSchemaDescription;
225
300
  return cloned;
226
301
  }
227
302
  self(current, previous, operation) {
@@ -271,15 +346,30 @@ var valueValidators = {
271
346
  },
272
347
  /**
273
348
  * Creates a validator that asserts that the input is nullish.
349
+ * JSON Schema has no representation for `undefined`, so only `null` is expressed.
274
350
  */
275
351
  nullish() {
276
- return createValidator(locale3.nullish, (input) => input == null);
352
+ return createValidator(
353
+ locale3.nullish,
354
+ (input) => input == null,
355
+ void 0,
356
+ {
357
+ type: "null"
358
+ }
359
+ );
277
360
  },
278
361
  /**
279
362
  * Creates a validator that asserts that the input is strictly null.
280
363
  */
281
364
  null() {
282
- return createValidator(locale3.null, (input) => input === null);
365
+ return createValidator(
366
+ locale3.null,
367
+ (input) => input === null,
368
+ void 0,
369
+ {
370
+ type: "null"
371
+ }
372
+ );
283
373
  },
284
374
  /**
285
375
  * Creates a validator that asserts that the input is strictly undefined.
@@ -354,7 +444,9 @@ var arrayValidators = {
354
444
  isArray() {
355
445
  return createValidator(
356
446
  locale4.array,
357
- (input) => Array.isArray(input)
447
+ (input) => Array.isArray(input),
448
+ void 0,
449
+ { type: "array" }
358
450
  );
359
451
  },
360
452
  /**
@@ -381,7 +473,8 @@ var arrayValidators = {
381
473
  if (!options.all && errors.length) return errors;
382
474
  }
383
475
  return errors;
384
- }
476
+ },
477
+ { type: "array", items: toJsonSchema(elementValidator) }
385
478
  );
386
479
  },
387
480
  /**
@@ -419,6 +512,13 @@ var arrayValidators = {
419
512
  if (!options.all && errors.length) return errors;
420
513
  }
421
514
  return errors;
515
+ },
516
+ {
517
+ type: "array",
518
+ items: validators.map((v) => toJsonSchema(v)),
519
+ minItems: validators.length,
520
+ maxItems: validators.length,
521
+ additionalItems: false
422
522
  }
423
523
  );
424
524
  },
@@ -430,7 +530,8 @@ var arrayValidators = {
430
530
  return createValidator(
431
531
  substitute4(locale4.minLength, { value: min }),
432
532
  (input) => input.length >= min,
433
- (input) => substitute4(locale4.actualLength, { value: input.length })
533
+ (input) => substitute4(locale4.actualLength, { value: input.length }),
534
+ { minItems: min }
434
535
  );
435
536
  },
436
537
  /**
@@ -442,7 +543,8 @@ var arrayValidators = {
442
543
  return createValidator(
443
544
  substitute4(locale4.maxLength, { value: max }),
444
545
  (input) => input.length <= max,
445
- (input) => substitute4(locale4.actualLength, { value: input.length })
546
+ (input) => substitute4(locale4.actualLength, { value: input.length }),
547
+ { maxItems: max }
446
548
  );
447
549
  }
448
550
  };
@@ -512,12 +614,22 @@ import { substitute as substitute5 } from "@amazon/vinyl-util";
512
614
  var locale5 = {
513
615
  template: "type {value}"
514
616
  };
617
+ var jsonSchemaTypeByTypeof = {
618
+ string: "string",
619
+ number: "number",
620
+ boolean: "boolean",
621
+ object: "object"
622
+ };
515
623
  function typeOfValidator(expected) {
624
+ const jsonType = jsonSchemaTypeByTypeof[expected];
625
+ const jsonSchema = jsonType == null ? void 0 : { type: jsonType };
516
626
  return createValidator(
517
627
  substitute5(locale5.template, { value: expected }),
518
628
  (input) => {
519
629
  return input != null && typeof input === expected;
520
- }
630
+ },
631
+ void 0,
632
+ jsonSchema
521
633
  );
522
634
  }
523
635
  var typeOfValidatorCache = {};
@@ -586,88 +698,9 @@ var _FunctionSchema = class _FunctionSchema extends ValueSchema {
586
698
  __publicField(_FunctionSchema, "_base", null);
587
699
  var FunctionSchema = _FunctionSchema;
588
700
 
589
- // src/validation/SetSchema.ts
701
+ // src/validation/NumberSchema.ts
590
702
  import { substitute as substitute7 } from "@amazon/vinyl-util";
591
703
  var locale7 = {
592
- set: "Set",
593
- withElements: "Set<{value}>"
594
- };
595
- var setValidators = {
596
- /**
597
- * Creates a validator that asserts that the input is a set.
598
- */
599
- isSet() {
600
- return createValidator(
601
- locale7.set,
602
- (input) => input instanceof Set
603
- );
604
- },
605
- /**
606
- * Creates a validator that asserts that every element passes the given validator.
607
- *
608
- * @param elementValidator
609
- */
610
- withElements(elementValidator) {
611
- return createDeepValidator(
612
- substitute7(locale7.withElements, {
613
- value: elementValidator.description
614
- }),
615
- (input, options, path) => {
616
- const errors = [];
617
- let i = 0;
618
- for (const element of input) {
619
- errors.push(
620
- ...elementValidator.validate(
621
- element,
622
- options,
623
- path.concat(i.toString())
624
- )
625
- );
626
- if (!options.all && errors.length) return errors;
627
- i++;
628
- }
629
- return errors;
630
- }
631
- );
632
- }
633
- };
634
- var _SetSchema = class _SetSchema extends ValueSchema {
635
- /**
636
- * The base SetSchema instance validating that the input is a Set.
637
- */
638
- static get base() {
639
- if (this._base == null)
640
- this._base = new _SetSchema(setValidators.isSet());
641
- return this._base;
642
- }
643
- /**
644
- * Creates a validator that asserts that every element passes the given validator.
645
- *
646
- * @param elementValidator
647
- */
648
- withElements(elementValidator) {
649
- return this.chain(setValidators.withElements(elementValidator));
650
- }
651
- /**
652
- * Casts to a readonly set.
653
- * This is a shallow cast, elements of the array will not be changed.
654
- */
655
- readonly() {
656
- return this;
657
- }
658
- /**
659
- * Casts the parameter type.
660
- */
661
- cast() {
662
- return this;
663
- }
664
- };
665
- __publicField(_SetSchema, "_base", null);
666
- var SetSchema = _SetSchema;
667
-
668
- // src/validation/NumberSchema.ts
669
- import { substitute as substitute8 } from "@amazon/vinyl-util";
670
- var locale8 = {
671
704
  gte: "at least {value}",
672
705
  gt: "greater than {value}",
673
706
  lte: "at most {value}",
@@ -685,8 +718,10 @@ var numberValidators = {
685
718
  */
686
719
  gte(min) {
687
720
  return createValidator(
688
- substitute8(locale8.gte, { value: min }),
689
- (input) => input >= min
721
+ substitute7(locale7.gte, { value: min }),
722
+ (input) => input >= min,
723
+ void 0,
724
+ { minimum: min }
690
725
  );
691
726
  },
692
727
  /**
@@ -697,8 +732,10 @@ var numberValidators = {
697
732
  */
698
733
  gt(min) {
699
734
  return createValidator(
700
- substitute8(locale8.gt, { value: min }),
701
- (input) => input > min
735
+ substitute7(locale7.gt, { value: min }),
736
+ (input) => input > min,
737
+ void 0,
738
+ { exclusiveMinimum: min }
702
739
  );
703
740
  },
704
741
  /**
@@ -709,8 +746,10 @@ var numberValidators = {
709
746
  */
710
747
  lte(max) {
711
748
  return createValidator(
712
- substitute8(locale8.lte, { value: max }),
713
- (input) => input <= max
749
+ substitute7(locale7.lte, { value: max }),
750
+ (input) => input <= max,
751
+ void 0,
752
+ { maximum: max }
714
753
  );
715
754
  },
716
755
  /**
@@ -721,8 +760,10 @@ var numberValidators = {
721
760
  */
722
761
  lt(max) {
723
762
  return createValidator(
724
- substitute8(locale8.lt, { value: max }),
725
- (input) => input < max
763
+ substitute7(locale7.lt, { value: max }),
764
+ (input) => input < max,
765
+ void 0,
766
+ { exclusiveMaximum: max }
726
767
  );
727
768
  },
728
769
  /**
@@ -734,23 +775,27 @@ var numberValidators = {
734
775
  */
735
776
  within(min, max) {
736
777
  return createValidator(
737
- substitute8(locale8.within, { min, max }),
738
- (input) => input >= min && input <= max
778
+ substitute7(locale7.within, { min, max }),
779
+ (input) => input >= min && input <= max,
780
+ void 0,
781
+ { minimum: min, maximum: max }
739
782
  );
740
783
  },
741
784
  /**
742
785
  * Creates a validator that asserts that the input number is finite.
743
786
  */
744
787
  finite() {
745
- return createValidator(locale8.finite, (input) => Number.isFinite(input));
788
+ return createValidator(locale7.finite, (input) => Number.isFinite(input));
746
789
  },
747
790
  /**
748
791
  * Creates a validator that asserts that the input number is a safe integer.
749
792
  */
750
793
  safeInteger() {
751
794
  return createValidator(
752
- locale8.safeInteger,
753
- (input) => Number.isSafeInteger(input)
795
+ locale7.safeInteger,
796
+ (input) => Number.isSafeInteger(input),
797
+ void 0,
798
+ { type: "integer" }
754
799
  );
755
800
  }
756
801
  };
@@ -826,7 +871,7 @@ __publicField(_NumberSchema, "_base", null);
826
871
  var NumberSchema = _NumberSchema;
827
872
 
828
873
  // src/validation/ObjectSchema.ts
829
- import { merge, ownKeys, substitute as substitute9 } from "@amazon/vinyl-util";
874
+ import { merge, ownKeys as ownKeys2, substitute as substitute8 } from "@amazon/vinyl-util";
830
875
 
831
876
  // src/validation/ValidatorWithPartial.ts
832
877
  function isValidatorWithPartial(validator) {
@@ -840,7 +885,7 @@ function maybeToPartial(validator) {
840
885
  }
841
886
 
842
887
  // src/validation/ObjectSchema.ts
843
- var locale9 = {
888
+ var locale8 = {
844
889
  extend: "{\n{body}\n}",
845
890
  prop: "{key}: {value}",
846
891
  propSeparator: ",\n",
@@ -856,19 +901,27 @@ var objectValidators = {
856
901
  */
857
902
  properties(propertyValidators) {
858
903
  const propertiesDescriptions = [];
859
- const keys = ownKeys(propertyValidators);
904
+ const keys = ownKeys2(propertyValidators);
905
+ const jsonProperties = {};
906
+ const requiredKeys = [];
860
907
  for (const key of keys) {
861
908
  const validator2 = propertyValidators[key];
862
909
  propertiesDescriptions.push(
863
- substitute9(locale9.prop, {
910
+ substitute8(locale8.prop, {
864
911
  key: String(key) + (validator2.options.optional ? "?" : ""),
865
912
  value: validator2.description
866
913
  })
867
914
  );
915
+ jsonProperties[String(key)] = toJsonSchema(validator2);
916
+ if (!validator2.options.optional) requiredKeys.push(String(key));
868
917
  }
869
- const description = substitute9(locale9.extend, {
870
- body: propertiesDescriptions.join(locale9.propSeparator).split("\n").map((line) => locale9.indent + line).join("\n")
918
+ const description = substitute8(locale8.extend, {
919
+ body: propertiesDescriptions.join(locale8.propSeparator).split("\n").map((line) => locale8.indent + line).join("\n")
871
920
  });
921
+ const jsonSchema = __spreadValues({
922
+ type: "object",
923
+ properties: jsonProperties
924
+ }, requiredKeys.length ? { required: requiredKeys } : {});
872
925
  const validator = createDeepValidator(
873
926
  description,
874
927
  (input, options, path) => {
@@ -887,7 +940,7 @@ var objectValidators = {
887
940
  } else {
888
941
  if (!validator2.options.optional) {
889
942
  errors.push({
890
- message: substitute9(locale9.required, { key }),
943
+ message: substitute8(locale8.required, { key }),
891
944
  path: path.concat(String(key))
892
945
  });
893
946
  }
@@ -895,7 +948,8 @@ var objectValidators = {
895
948
  if (!options.all && errors.length) return errors;
896
949
  }
897
950
  return errors;
898
- }
951
+ },
952
+ jsonSchema
899
953
  );
900
954
  return merge(validator, {
901
955
  partial() {
@@ -962,11 +1016,11 @@ __publicField(_ObjectSchema, "_base", null);
962
1016
  var ObjectSchema = _ObjectSchema;
963
1017
 
964
1018
  // src/validation/RecordSchema.ts
965
- import { ownKeys as ownKeys2, substitute as substitute11 } from "@amazon/vinyl-util";
1019
+ import { ownKeys as ownKeys3, substitute as substitute10 } from "@amazon/vinyl-util";
966
1020
 
967
1021
  // src/validation/StringSchema.ts
968
- import { substitute as substitute10 } from "@amazon/vinyl-util";
969
- var locale10 = {
1022
+ import { substitute as substitute9 } from "@amazon/vinyl-util";
1023
+ var locale9 = {
970
1024
  notEmpty: "not empty",
971
1025
  minLength: "at least {value} characters",
972
1026
  maxLength: "at most {value} characters",
@@ -978,7 +1032,12 @@ var stringValidators = {
978
1032
  * Creates a validator that asserts that the input is not empty.
979
1033
  */
980
1034
  notEmpty() {
981
- return createValidator(locale10.notEmpty, (input) => input !== "");
1035
+ return createValidator(
1036
+ locale9.notEmpty,
1037
+ (input) => input !== "",
1038
+ void 0,
1039
+ { minLength: 1 }
1040
+ );
982
1041
  },
983
1042
  /**
984
1043
  * Creates a validator that asserts that the input string has at least the given minimum
@@ -988,8 +1047,10 @@ var stringValidators = {
988
1047
  */
989
1048
  minLength(min) {
990
1049
  return createValidator(
991
- substitute10(locale10.minLength, { value: min }),
992
- (input) => input.length >= min
1050
+ substitute9(locale9.minLength, { value: min }),
1051
+ (input) => input.length >= min,
1052
+ void 0,
1053
+ { minLength: min }
993
1054
  );
994
1055
  },
995
1056
  /**
@@ -1000,8 +1061,10 @@ var stringValidators = {
1000
1061
  */
1001
1062
  maxLength(max) {
1002
1063
  return createValidator(
1003
- substitute10(locale10.maxLength, { value: max }),
1004
- (input) => input.length <= max
1064
+ substitute9(locale9.maxLength, { value: max }),
1065
+ (input) => input.length <= max,
1066
+ void 0,
1067
+ { maxLength: max }
1005
1068
  );
1006
1069
  },
1007
1070
  /**
@@ -1010,7 +1073,7 @@ var stringValidators = {
1010
1073
  */
1011
1074
  noWhitespace() {
1012
1075
  return createValidator(
1013
- locale10.noWhitespace,
1076
+ locale9.noWhitespace,
1014
1077
  (input) => input.search(/\s/g) === -1
1015
1078
  );
1016
1079
  },
@@ -1020,10 +1083,12 @@ var stringValidators = {
1020
1083
  */
1021
1084
  matches(regex) {
1022
1085
  return createValidator(
1023
- substitute10(locale10.matches, { value: regex.toString() }),
1086
+ substitute9(locale9.matches, { value: regex.toString() }),
1024
1087
  (input) => {
1025
1088
  return regex.test(input);
1026
- }
1089
+ },
1090
+ void 0,
1091
+ { pattern: regex.source }
1027
1092
  );
1028
1093
  }
1029
1094
  };
@@ -1079,7 +1144,7 @@ __publicField(_StringSchema, "_base", null);
1079
1144
  var StringSchema = _StringSchema;
1080
1145
 
1081
1146
  // src/validation/RecordSchema.ts
1082
- var locale11 = {
1147
+ var locale10 = {
1083
1148
  record: "{ [key: {key}]: {value} }"
1084
1149
  };
1085
1150
  var recordValidators = {
@@ -1096,13 +1161,13 @@ var recordValidators = {
1096
1161
  */
1097
1162
  record(keyValidator, valueValidator) {
1098
1163
  return createDeepValidator(
1099
- substitute11(locale11.record, {
1164
+ substitute10(locale10.record, {
1100
1165
  key: keyValidator.description,
1101
1166
  value: valueValidator.description
1102
1167
  }),
1103
1168
  (input, options, path) => {
1104
1169
  const errors = [];
1105
- for (const key of ownKeys2(input)) {
1170
+ for (const key of ownKeys3(input)) {
1106
1171
  const keyStr = String(key);
1107
1172
  errors.push(
1108
1173
  ...keyValidator.validate(
@@ -1123,6 +1188,10 @@ var recordValidators = {
1123
1188
  if (!options.all && errors.length) return errors;
1124
1189
  }
1125
1190
  return errors;
1191
+ },
1192
+ {
1193
+ type: "object",
1194
+ additionalProperties: toJsonSchema(valueValidator)
1126
1195
  }
1127
1196
  );
1128
1197
  }
@@ -1180,7 +1249,97 @@ var _RecordSchema = class _RecordSchema extends ValueSchema {
1180
1249
  __publicField(_RecordSchema, "_base", null);
1181
1250
  var RecordSchema = _RecordSchema;
1182
1251
 
1252
+ // src/validation/SetSchema.ts
1253
+ import { substitute as substitute11 } from "@amazon/vinyl-util";
1254
+ var locale11 = {
1255
+ set: "Set",
1256
+ withElements: "Set<{value}>"
1257
+ };
1258
+ var setValidators = {
1259
+ /**
1260
+ * Creates a validator that asserts that the input is a set.
1261
+ */
1262
+ isSet() {
1263
+ return createValidator(
1264
+ locale11.set,
1265
+ (input) => input instanceof Set,
1266
+ void 0,
1267
+ { type: "array", uniqueItems: true }
1268
+ );
1269
+ },
1270
+ /**
1271
+ * Creates a validator that asserts that every element passes the given validator.
1272
+ *
1273
+ * @param elementValidator
1274
+ */
1275
+ withElements(elementValidator) {
1276
+ return createDeepValidator(
1277
+ substitute11(locale11.withElements, {
1278
+ value: elementValidator.description
1279
+ }),
1280
+ (input, options, path) => {
1281
+ const errors = [];
1282
+ let i = 0;
1283
+ for (const element of input) {
1284
+ errors.push(
1285
+ ...elementValidator.validate(
1286
+ element,
1287
+ options,
1288
+ path.concat(i.toString())
1289
+ )
1290
+ );
1291
+ if (!options.all && errors.length) return errors;
1292
+ i++;
1293
+ }
1294
+ return errors;
1295
+ },
1296
+ {
1297
+ type: "array",
1298
+ uniqueItems: true,
1299
+ items: toJsonSchema(elementValidator)
1300
+ }
1301
+ );
1302
+ }
1303
+ };
1304
+ var _SetSchema = class _SetSchema extends ValueSchema {
1305
+ /**
1306
+ * The base SetSchema instance validating that the input is a Set.
1307
+ */
1308
+ static get base() {
1309
+ if (this._base == null)
1310
+ this._base = new _SetSchema(setValidators.isSet());
1311
+ return this._base;
1312
+ }
1313
+ /**
1314
+ * Creates a validator that asserts that every element passes the given validator.
1315
+ *
1316
+ * @param elementValidator
1317
+ */
1318
+ withElements(elementValidator) {
1319
+ return this.chain(setValidators.withElements(elementValidator));
1320
+ }
1321
+ /**
1322
+ * Casts to a readonly set.
1323
+ * This is a shallow cast, elements of the array will not be changed.
1324
+ */
1325
+ readonly() {
1326
+ return this;
1327
+ }
1328
+ /**
1329
+ * Casts the parameter type.
1330
+ */
1331
+ cast() {
1332
+ return this;
1333
+ }
1334
+ };
1335
+ __publicField(_SetSchema, "_base", null);
1336
+ var SetSchema = _SetSchema;
1337
+
1183
1338
  // src/validation/validators.ts
1339
+ import {
1340
+ stringifyForPrint as stringifyForPrint2,
1341
+ substitute as substitute12
1342
+ } from "@amazon/vinyl-util";
1184
1343
  var locale12 = {
1185
1344
  isOneOf: "one of: {value}",
1186
1345
  instanceOf: "instance of {value}",
@@ -1213,7 +1372,9 @@ function isOneOf(...possibleValues) {
1213
1372
  substitute12(locale12.isOneOf, {
1214
1373
  value: possibleValues.join(locale12.oneOfSeparator)
1215
1374
  }),
1216
- (input) => possibleValues.includes(input)
1375
+ (input) => possibleValues.includes(input),
1376
+ void 0,
1377
+ { enum: [...possibleValues] }
1217
1378
  )
1218
1379
  );
1219
1380
  }
@@ -1287,6 +1448,7 @@ export {
1287
1448
  isValidatorWithPartial,
1288
1449
  maybeToDeepPartial,
1289
1450
  maybeToPartial,
1451
+ mergeJsonSchema,
1290
1452
  nullish,
1291
1453
  number,
1292
1454
  numberValidators,
@@ -1301,6 +1463,7 @@ export {
1301
1463
  string,
1302
1464
  stringValidators,
1303
1465
  symbol,
1466
+ toJsonSchema,
1304
1467
  tuple,
1305
1468
  typeOfValidators,
1306
1469
  valueValidators