complete-cli 1.0.5-dev.2 → 1.0.5-dev.3

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 (60) hide show
  1. package/dist/main.cjs +65139 -2
  2. package/dist/main.cjs.map +1 -1
  3. package/dist/vendors-node_modules_prettier_plugins_acorn_mjs.main.cjs +38 -0
  4. package/dist/vendors-node_modules_prettier_plugins_acorn_mjs.main.cjs.map +1 -0
  5. package/dist/vendors-node_modules_prettier_plugins_angular_mjs.main.cjs +25 -0
  6. package/dist/vendors-node_modules_prettier_plugins_angular_mjs.main.cjs.map +1 -0
  7. package/dist/vendors-node_modules_prettier_plugins_babel_mjs.main.cjs +38 -0
  8. package/dist/vendors-node_modules_prettier_plugins_babel_mjs.main.cjs.map +1 -0
  9. package/dist/vendors-node_modules_prettier_plugins_estree_mjs.main.cjs +61 -0
  10. package/dist/vendors-node_modules_prettier_plugins_estree_mjs.main.cjs.map +1 -0
  11. package/dist/vendors-node_modules_prettier_plugins_flow_mjs.main.cjs +42 -0
  12. package/dist/vendors-node_modules_prettier_plugins_flow_mjs.main.cjs.map +1 -0
  13. package/dist/vendors-node_modules_prettier_plugins_glimmer_mjs.main.cjs +55 -0
  14. package/dist/vendors-node_modules_prettier_plugins_glimmer_mjs.main.cjs.map +1 -0
  15. package/dist/vendors-node_modules_prettier_plugins_graphql_mjs.main.cjs +55 -0
  16. package/dist/vendors-node_modules_prettier_plugins_graphql_mjs.main.cjs.map +1 -0
  17. package/dist/vendors-node_modules_prettier_plugins_html_mjs.main.cjs +48 -0
  18. package/dist/vendors-node_modules_prettier_plugins_html_mjs.main.cjs.map +1 -0
  19. package/dist/vendors-node_modules_prettier_plugins_markdown_mjs.main.cjs +89 -0
  20. package/dist/vendors-node_modules_prettier_plugins_markdown_mjs.main.cjs.map +1 -0
  21. package/dist/vendors-node_modules_prettier_plugins_meriyah_mjs.main.cjs +27 -0
  22. package/dist/vendors-node_modules_prettier_plugins_meriyah_mjs.main.cjs.map +1 -0
  23. package/dist/vendors-node_modules_prettier_plugins_postcss_mjs.main.cjs +80 -0
  24. package/dist/vendors-node_modules_prettier_plugins_postcss_mjs.main.cjs.map +1 -0
  25. package/dist/vendors-node_modules_prettier_plugins_typescript_mjs.main.cjs +43 -0
  26. package/dist/vendors-node_modules_prettier_plugins_typescript_mjs.main.cjs.map +1 -0
  27. package/dist/vendors-node_modules_prettier_plugins_yaml_mjs.main.cjs +187 -0
  28. package/dist/vendors-node_modules_prettier_plugins_yaml_mjs.main.cjs.map +1 -0
  29. package/dist/vendors-node_modules_typanion_lib_index_js.main.cjs +1323 -0
  30. package/dist/vendors-node_modules_typanion_lib_index_js.main.cjs.map +1 -0
  31. package/package.json +1 -1
  32. package/dist/107.main.cjs +0 -2
  33. package/dist/107.main.cjs.map +0 -1
  34. package/dist/140.main.cjs +0 -2
  35. package/dist/140.main.cjs.map +0 -1
  36. package/dist/242.main.cjs +0 -2
  37. package/dist/242.main.cjs.map +0 -1
  38. package/dist/269.main.cjs +0 -2
  39. package/dist/269.main.cjs.map +0 -1
  40. package/dist/309.main.cjs +0 -2
  41. package/dist/309.main.cjs.map +0 -1
  42. package/dist/367.main.cjs +0 -2
  43. package/dist/367.main.cjs.map +0 -1
  44. package/dist/541.main.cjs +0 -2
  45. package/dist/541.main.cjs.map +0 -1
  46. package/dist/55.main.cjs +0 -2
  47. package/dist/55.main.cjs.map +0 -1
  48. package/dist/717.main.cjs +0 -2
  49. package/dist/717.main.cjs.map +0 -1
  50. package/dist/742.main.cjs +0 -2
  51. package/dist/742.main.cjs.map +0 -1
  52. package/dist/769.main.cjs +0 -2
  53. package/dist/769.main.cjs.map +0 -1
  54. package/dist/770.main.cjs +0 -2
  55. package/dist/770.main.cjs.map +0 -1
  56. package/dist/914.main.cjs +0 -2
  57. package/dist/914.main.cjs.map +0 -1
  58. package/dist/951.main.cjs +0 -2
  59. package/dist/951.main.cjs.map +0 -1
  60. package/dist/main.cjs.LICENSE.txt +0 -78
@@ -0,0 +1,1323 @@
1
+ "use strict";
2
+ exports.id = "vendors-node_modules_typanion_lib_index_js";
3
+ exports.ids = ["vendors-node_modules_typanion_lib_index_js"];
4
+ exports.modules = {
5
+
6
+ /***/ "../../node_modules/typanion/lib/index.js":
7
+ /*!************************************************!*\
8
+ !*** ../../node_modules/typanion/lib/index.js ***!
9
+ \************************************************/
10
+ /***/ ((__unused_webpack_module, exports) => {
11
+
12
+
13
+
14
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
15
+
16
+ const simpleKeyRegExp = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
17
+ function getPrintable(value) {
18
+ if (value === null)
19
+ return `null`;
20
+ if (value === undefined)
21
+ return `undefined`;
22
+ if (value === ``)
23
+ return `an empty string`;
24
+ if (typeof value === 'symbol')
25
+ return `<${value.toString()}>`;
26
+ if (Array.isArray(value))
27
+ return `an array`;
28
+ return JSON.stringify(value);
29
+ }
30
+ function getPrintableArray(value, conjunction) {
31
+ if (value.length === 0)
32
+ return `nothing`;
33
+ if (value.length === 1)
34
+ return getPrintable(value[0]);
35
+ const rest = value.slice(0, -1);
36
+ const trailing = value[value.length - 1];
37
+ const separator = value.length > 2
38
+ ? `, ${conjunction} `
39
+ : ` ${conjunction} `;
40
+ return `${rest.map(value => getPrintable(value)).join(`, `)}${separator}${getPrintable(trailing)}`;
41
+ }
42
+ function computeKey(state, key) {
43
+ var _a, _b, _c;
44
+ if (typeof key === `number`) {
45
+ return `${(_a = state === null || state === void 0 ? void 0 : state.p) !== null && _a !== void 0 ? _a : `.`}[${key}]`;
46
+ }
47
+ else if (simpleKeyRegExp.test(key)) {
48
+ return `${(_b = state === null || state === void 0 ? void 0 : state.p) !== null && _b !== void 0 ? _b : ``}.${key}`;
49
+ }
50
+ else {
51
+ return `${(_c = state === null || state === void 0 ? void 0 : state.p) !== null && _c !== void 0 ? _c : `.`}[${JSON.stringify(key)}]`;
52
+ }
53
+ }
54
+ function plural(n, singular, plural) {
55
+ return n === 1 ? singular : plural;
56
+ }
57
+
58
+ const colorStringRegExp = /^#[0-9a-f]{6}$/i;
59
+ const colorStringAlphaRegExp = /^#[0-9a-f]{6}([0-9a-f]{2})?$/i;
60
+ // https://stackoverflow.com/a/475217/880703
61
+ const base64RegExp = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
62
+ // https://stackoverflow.com/a/14166194/880703
63
+ const uuid4RegExp = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}$/i;
64
+ // https://stackoverflow.com/a/28022901/880703 + https://www.debuggex.com/r/bl8J35wMKk48a7u_
65
+ const iso8601RegExp = /^(?:[1-9]\d{3}(-?)(?:(?:0[1-9]|1[0-2])\1(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])\1(?:29|30)|(?:0[13578]|1[02])(?:\1)31|00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[0-5]))|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)(?:(-?)02(?:\2)29|-?366))T(?:[01]\d|2[0-3])(:?)[0-5]\d(?:\3[0-5]\d)?(?:Z|[+-][01]\d(?:\3[0-5]\d)?)$/;
66
+
67
+ function pushError({ errors, p } = {}, message) {
68
+ errors === null || errors === void 0 ? void 0 : errors.push(`${p !== null && p !== void 0 ? p : `.`}: ${message}`);
69
+ return false;
70
+ }
71
+ function makeSetter(target, key) {
72
+ return (v) => {
73
+ target[key] = v;
74
+ };
75
+ }
76
+ function makeCoercionFn(target, key) {
77
+ return (v) => {
78
+ const previous = target[key];
79
+ target[key] = v;
80
+ return makeCoercionFn(target, key).bind(null, previous);
81
+ };
82
+ }
83
+ function makeLazyCoercionFn(fn, orig, generator) {
84
+ const commit = () => {
85
+ fn(generator());
86
+ return revert;
87
+ };
88
+ const revert = () => {
89
+ fn(orig);
90
+ return commit;
91
+ };
92
+ return commit;
93
+ }
94
+
95
+ /**
96
+ * Create a validator that always returns true and never refines the type.
97
+ */
98
+ function isUnknown() {
99
+ return makeValidator({
100
+ test: (value, state) => {
101
+ return true;
102
+ },
103
+ });
104
+ }
105
+ function isLiteral(expected) {
106
+ return makeValidator({
107
+ test: (value, state) => {
108
+ if (value !== expected)
109
+ return pushError(state, `Expected ${getPrintable(expected)} (got ${getPrintable(value)})`);
110
+ return true;
111
+ },
112
+ });
113
+ }
114
+ /**
115
+ * Create a validator that only returns true when the tested value is a string.
116
+ * Refines the type to `string`.
117
+ */
118
+ function isString() {
119
+ return makeValidator({
120
+ test: (value, state) => {
121
+ if (typeof value !== `string`)
122
+ return pushError(state, `Expected a string (got ${getPrintable(value)})`);
123
+ return true;
124
+ },
125
+ });
126
+ }
127
+ function isEnum(enumSpec) {
128
+ const valuesArray = Array.isArray(enumSpec) ? enumSpec : Object.values(enumSpec);
129
+ const isAlphaNum = valuesArray.every(item => typeof item === 'string' || typeof item === 'number');
130
+ const values = new Set(valuesArray);
131
+ if (values.size === 1)
132
+ return isLiteral([...values][0]);
133
+ return makeValidator({
134
+ test: (value, state) => {
135
+ if (!values.has(value)) {
136
+ if (isAlphaNum) {
137
+ return pushError(state, `Expected one of ${getPrintableArray(valuesArray, `or`)} (got ${getPrintable(value)})`);
138
+ }
139
+ else {
140
+ return pushError(state, `Expected a valid enumeration value (got ${getPrintable(value)})`);
141
+ }
142
+ }
143
+ return true;
144
+ },
145
+ });
146
+ }
147
+ const BOOLEAN_COERCIONS = new Map([
148
+ [`true`, true],
149
+ [`True`, true],
150
+ [`1`, true],
151
+ [1, true],
152
+ [`false`, false],
153
+ [`False`, false],
154
+ [`0`, false],
155
+ [0, false],
156
+ ]);
157
+ /**
158
+ * Create a validator that only returns true when the tested value is a
159
+ * boolean. Refines the type to `boolean`.
160
+ *
161
+ * Supports coercion:
162
+ * - 'true' / 'True' / '1' / 1 will turn to `true`
163
+ * - 'false' / 'False' / '0' / 0 will turn to `false`
164
+ */
165
+ function isBoolean() {
166
+ return makeValidator({
167
+ test: (value, state) => {
168
+ var _a;
169
+ if (typeof value !== `boolean`) {
170
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
171
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
172
+ return pushError(state, `Unbound coercion result`);
173
+ const coercion = BOOLEAN_COERCIONS.get(value);
174
+ if (typeof coercion !== `undefined`) {
175
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, coercion)]);
176
+ return true;
177
+ }
178
+ }
179
+ return pushError(state, `Expected a boolean (got ${getPrintable(value)})`);
180
+ }
181
+ return true;
182
+ },
183
+ });
184
+ }
185
+ /**
186
+ * Create a validator that only returns true when the tested value is a
187
+ * number (including floating numbers; use `cascade` and `isInteger` to
188
+ * restrict the range further). Refines the type to `number`.
189
+ *
190
+ * Supports coercion.
191
+ */
192
+ function isNumber() {
193
+ return makeValidator({
194
+ test: (value, state) => {
195
+ var _a;
196
+ if (typeof value !== `number`) {
197
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
198
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
199
+ return pushError(state, `Unbound coercion result`);
200
+ let coercion;
201
+ if (typeof value === `string`) {
202
+ let val;
203
+ try {
204
+ val = JSON.parse(value);
205
+ }
206
+ catch (_b) { }
207
+ // We check against JSON.stringify that the output is the same to ensure that the number can be safely represented in JS
208
+ if (typeof val === `number`) {
209
+ if (JSON.stringify(val) === value) {
210
+ coercion = val;
211
+ }
212
+ else {
213
+ return pushError(state, `Received a number that can't be safely represented by the runtime (${value})`);
214
+ }
215
+ }
216
+ }
217
+ if (typeof coercion !== `undefined`) {
218
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, coercion)]);
219
+ return true;
220
+ }
221
+ }
222
+ return pushError(state, `Expected a number (got ${getPrintable(value)})`);
223
+ }
224
+ return true;
225
+ },
226
+ });
227
+ }
228
+ /**
229
+ * Important: This validator only makes sense when used in conjunction with
230
+ * coercion! It will always error when used without.
231
+ *
232
+ * Create a validator that only returns true when the tested value is a
233
+ * JSON representation of the expected type. Refines the type to the
234
+ * expected type, and casts the value into its inner value.
235
+ */
236
+ function isPayload(spec) {
237
+ return makeValidator({
238
+ test: (value, state) => {
239
+ var _a;
240
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) === `undefined`)
241
+ return pushError(state, `The isPayload predicate can only be used with coercion enabled`);
242
+ if (typeof state.coercion === `undefined`)
243
+ return pushError(state, `Unbound coercion result`);
244
+ if (typeof value !== `string`)
245
+ return pushError(state, `Expected a string (got ${getPrintable(value)})`);
246
+ let inner;
247
+ try {
248
+ inner = JSON.parse(value);
249
+ }
250
+ catch (_b) {
251
+ return pushError(state, `Expected a JSON string (got ${getPrintable(value)})`);
252
+ }
253
+ const wrapper = { value: inner };
254
+ if (!spec(inner, Object.assign(Object.assign({}, state), { coercion: makeCoercionFn(wrapper, `value`) })))
255
+ return false;
256
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, wrapper.value)]);
257
+ return true;
258
+ },
259
+ });
260
+ }
261
+ /**
262
+ * Create a validator that only returns true when the tested value is a
263
+ * valid date. Refines the type to `Date`.
264
+ *
265
+ * Supports coercion via one of the following formats:
266
+ * - ISO86001 strings
267
+ * - Unix timestamps
268
+ */
269
+ function isDate() {
270
+ return makeValidator({
271
+ test: (value, state) => {
272
+ var _a;
273
+ if (!(value instanceof Date)) {
274
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
275
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
276
+ return pushError(state, `Unbound coercion result`);
277
+ let coercion;
278
+ if (typeof value === `string` && iso8601RegExp.test(value)) {
279
+ coercion = new Date(value);
280
+ }
281
+ else {
282
+ let timestamp;
283
+ if (typeof value === `string`) {
284
+ let val;
285
+ try {
286
+ val = JSON.parse(value);
287
+ }
288
+ catch (_b) { }
289
+ if (typeof val === `number`) {
290
+ timestamp = val;
291
+ }
292
+ }
293
+ else if (typeof value === `number`) {
294
+ timestamp = value;
295
+ }
296
+ if (typeof timestamp !== `undefined`) {
297
+ if (Number.isSafeInteger(timestamp) || !Number.isSafeInteger(timestamp * 1000)) {
298
+ coercion = new Date(timestamp * 1000);
299
+ }
300
+ else {
301
+ return pushError(state, `Received a timestamp that can't be safely represented by the runtime (${value})`);
302
+ }
303
+ }
304
+ }
305
+ if (typeof coercion !== `undefined`) {
306
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, coercion)]);
307
+ return true;
308
+ }
309
+ }
310
+ return pushError(state, `Expected a date (got ${getPrintable(value)})`);
311
+ }
312
+ return true;
313
+ },
314
+ });
315
+ }
316
+ /**
317
+ * Create a validator that only returns true when the tested value is an
318
+ * array whose all values match the provided subspec. Refines the type to
319
+ * `Array<T>`, with `T` being the subspec inferred type.
320
+ *
321
+ * Supports coercion if the `delimiter` option is set, in which case strings
322
+ * will be split accordingly.
323
+ */
324
+ function isArray(spec, { delimiter } = {}) {
325
+ return makeValidator({
326
+ test: (value, state) => {
327
+ var _a;
328
+ const originalValue = value;
329
+ if (typeof value === `string` && typeof delimiter !== `undefined`) {
330
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
331
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
332
+ return pushError(state, `Unbound coercion result`);
333
+ value = value.split(delimiter);
334
+ }
335
+ }
336
+ if (!Array.isArray(value))
337
+ return pushError(state, `Expected an array (got ${getPrintable(value)})`);
338
+ let valid = true;
339
+ for (let t = 0, T = value.length; t < T; ++t) {
340
+ valid = spec(value[t], Object.assign(Object.assign({}, state), { p: computeKey(state, t), coercion: makeCoercionFn(value, t) })) && valid;
341
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
342
+ break;
343
+ }
344
+ }
345
+ if (value !== originalValue)
346
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, value)]);
347
+ return valid;
348
+ },
349
+ });
350
+ }
351
+ /**
352
+ * Create a validator that only returns true when the tested value is an
353
+ * set whose all values match the provided subspec. Refines the type to
354
+ * `Set<T>`, with `T` being the subspec inferred type.
355
+ *
356
+ * Supports coercion from arrays (or anything that can be coerced into an
357
+ * array).
358
+ */
359
+ function isSet(spec, { delimiter } = {}) {
360
+ const isArrayValidator = isArray(spec, { delimiter });
361
+ return makeValidator({
362
+ test: (value, state) => {
363
+ var _a, _b;
364
+ if (Object.getPrototypeOf(value).toString() === `[object Set]`) {
365
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
366
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
367
+ return pushError(state, `Unbound coercion result`);
368
+ const originalValues = [...value];
369
+ const coercedValues = [...value];
370
+ if (!isArrayValidator(coercedValues, Object.assign(Object.assign({}, state), { coercion: undefined })))
371
+ return false;
372
+ const updateValue = () => coercedValues.some((val, t) => val !== originalValues[t])
373
+ ? new Set(coercedValues)
374
+ : value;
375
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, makeLazyCoercionFn(state.coercion, value, updateValue)]);
376
+ return true;
377
+ }
378
+ else {
379
+ let valid = true;
380
+ for (const subValue of value) {
381
+ valid = spec(subValue, Object.assign({}, state)) && valid;
382
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
383
+ break;
384
+ }
385
+ }
386
+ return valid;
387
+ }
388
+ }
389
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
390
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
391
+ return pushError(state, `Unbound coercion result`);
392
+ const store = { value };
393
+ if (!isArrayValidator(value, Object.assign(Object.assign({}, state), { coercion: makeCoercionFn(store, `value`) })))
394
+ return false;
395
+ state.coercions.push([(_b = state.p) !== null && _b !== void 0 ? _b : `.`, makeLazyCoercionFn(state.coercion, value, () => new Set(store.value))]);
396
+ return true;
397
+ }
398
+ return pushError(state, `Expected a set (got ${getPrintable(value)})`);
399
+ }
400
+ });
401
+ }
402
+ /**
403
+ * Create a validator that only returns true when the tested value is an
404
+ * map whose all values match the provided subspecs. Refines the type to
405
+ * `Map<U, V>`, with `U` being the key subspec inferred type and `V` being
406
+ * the value subspec inferred type.
407
+ *
408
+ * Supports coercion from array of tuples (or anything that can be coerced into
409
+ * an array of tuples).
410
+ */
411
+ function isMap(keySpec, valueSpec) {
412
+ const isArrayValidator = isArray(isTuple([keySpec, valueSpec]));
413
+ const isRecordValidator = isRecord(valueSpec, { keys: keySpec });
414
+ return makeValidator({
415
+ test: (value, state) => {
416
+ var _a, _b, _c;
417
+ if (Object.getPrototypeOf(value).toString() === `[object Map]`) {
418
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
419
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
420
+ return pushError(state, `Unbound coercion result`);
421
+ const originalValues = [...value];
422
+ const coercedValues = [...value];
423
+ if (!isArrayValidator(coercedValues, Object.assign(Object.assign({}, state), { coercion: undefined })))
424
+ return false;
425
+ const updateValue = () => coercedValues.some((val, t) => val[0] !== originalValues[t][0] || val[1] !== originalValues[t][1])
426
+ ? new Map(coercedValues)
427
+ : value;
428
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, makeLazyCoercionFn(state.coercion, value, updateValue)]);
429
+ return true;
430
+ }
431
+ else {
432
+ let valid = true;
433
+ for (const [key, subValue] of value) {
434
+ valid = keySpec(key, Object.assign({}, state)) && valid;
435
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
436
+ break;
437
+ }
438
+ valid = valueSpec(subValue, Object.assign(Object.assign({}, state), { p: computeKey(state, key) })) && valid;
439
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
440
+ break;
441
+ }
442
+ }
443
+ return valid;
444
+ }
445
+ }
446
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
447
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
448
+ return pushError(state, `Unbound coercion result`);
449
+ const store = { value };
450
+ if (Array.isArray(value)) {
451
+ if (!isArrayValidator(value, Object.assign(Object.assign({}, state), { coercion: undefined })))
452
+ return false;
453
+ state.coercions.push([(_b = state.p) !== null && _b !== void 0 ? _b : `.`, makeLazyCoercionFn(state.coercion, value, () => new Map(store.value))]);
454
+ return true;
455
+ }
456
+ else {
457
+ if (!isRecordValidator(value, Object.assign(Object.assign({}, state), { coercion: makeCoercionFn(store, `value`) })))
458
+ return false;
459
+ state.coercions.push([(_c = state.p) !== null && _c !== void 0 ? _c : `.`, makeLazyCoercionFn(state.coercion, value, () => new Map(Object.entries(store.value)))]);
460
+ return true;
461
+ }
462
+ }
463
+ return pushError(state, `Expected a map (got ${getPrintable(value)})`);
464
+ }
465
+ });
466
+ }
467
+ /**
468
+ * Create a validator that only returns true when the tested value is a
469
+ * tuple whose each value matches the corresponding subspec. Refines the type
470
+ * into a tuple whose each item has the type inferred by the corresponding
471
+ * tuple.
472
+ *
473
+ * Supports coercion if the `delimiter` option is set, in which case strings
474
+ * will be split accordingly.
475
+ */
476
+ function isTuple(spec, { delimiter } = {}) {
477
+ const lengthValidator = hasExactLength(spec.length);
478
+ return makeValidator({
479
+ test: (value, state) => {
480
+ var _a;
481
+ if (typeof value === `string` && typeof delimiter !== `undefined`) {
482
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
483
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
484
+ return pushError(state, `Unbound coercion result`);
485
+ value = value.split(delimiter);
486
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, value)]);
487
+ }
488
+ }
489
+ if (!Array.isArray(value))
490
+ return pushError(state, `Expected a tuple (got ${getPrintable(value)})`);
491
+ let valid = lengthValidator(value, Object.assign({}, state));
492
+ for (let t = 0, T = value.length; t < T && t < spec.length; ++t) {
493
+ valid = spec[t](value[t], Object.assign(Object.assign({}, state), { p: computeKey(state, t), coercion: makeCoercionFn(value, t) })) && valid;
494
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
495
+ break;
496
+ }
497
+ }
498
+ return valid;
499
+ },
500
+ });
501
+ }
502
+ /**
503
+ * Create a validator that only returns true when the tested value is an
504
+ * object with any amount of properties that must all match the provided
505
+ * subspec. Refines the type to `Record<string, T>`, with `T` being the
506
+ * subspec inferred type.
507
+ *
508
+ * Keys can be optionally validated as well by using the `keys` optional
509
+ * subspec parameter.
510
+ */
511
+ function isRecord(spec, { keys: keySpec = null, } = {}) {
512
+ const isArrayValidator = isArray(isTuple([keySpec !== null && keySpec !== void 0 ? keySpec : isString(), spec]));
513
+ return makeValidator({
514
+ test: (value, state) => {
515
+ var _a;
516
+ if (Array.isArray(value)) {
517
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
518
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
519
+ return pushError(state, `Unbound coercion result`);
520
+ if (!isArrayValidator(value, Object.assign(Object.assign({}, state), { coercion: undefined })))
521
+ return false;
522
+ value = Object.fromEntries(value);
523
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, value)]);
524
+ return true;
525
+ }
526
+ }
527
+ if (typeof value !== `object` || value === null)
528
+ return pushError(state, `Expected an object (got ${getPrintable(value)})`);
529
+ const keys = Object.keys(value);
530
+ let valid = true;
531
+ for (let t = 0, T = keys.length; t < T && (valid || (state === null || state === void 0 ? void 0 : state.errors) != null); ++t) {
532
+ const key = keys[t];
533
+ const sub = value[key];
534
+ if (key === `__proto__` || key === `constructor`) {
535
+ valid = pushError(Object.assign(Object.assign({}, state), { p: computeKey(state, key) }), `Unsafe property name`);
536
+ continue;
537
+ }
538
+ if (keySpec !== null && !keySpec(key, state)) {
539
+ valid = false;
540
+ continue;
541
+ }
542
+ if (!spec(sub, Object.assign(Object.assign({}, state), { p: computeKey(state, key), coercion: makeCoercionFn(value, key) }))) {
543
+ valid = false;
544
+ continue;
545
+ }
546
+ }
547
+ return valid;
548
+ },
549
+ });
550
+ }
551
+ /**
552
+ * @deprecated Replace `isDict` by `isRecord`
553
+ */
554
+ function isDict(spec, opts = {}) {
555
+ return isRecord(spec, opts);
556
+ }
557
+ /**
558
+ * Create a validator that only returns true when the tested value is an
559
+ * object whose all properties match their corresponding subspec. Refines
560
+ * the type into an object whose each property has the type inferred by the
561
+ * corresponding subspec.
562
+ *
563
+ * Unlike `t.isPartial`, `t.isObject` doesn't allow extraneous properties by
564
+ * default. This behaviour can be altered by using the `extra` optional
565
+ * subspec parameter, which will be called to validate an object only
566
+ * containing the extraneous properties.
567
+ *
568
+ * Calling `t.isObject(..., {extra: t.isRecord(t.isUnknown())})` is
569
+ * essentially the same as calling `t.isPartial(...)`.
570
+ */
571
+ function isObject(props, { extra: extraSpec = null, } = {}) {
572
+ const specKeys = Object.keys(props);
573
+ const validator = makeValidator({
574
+ test: (value, state) => {
575
+ if (typeof value !== `object` || value === null)
576
+ return pushError(state, `Expected an object (got ${getPrintable(value)})`);
577
+ const keys = new Set([...specKeys, ...Object.keys(value)]);
578
+ const extra = {};
579
+ let valid = true;
580
+ for (const key of keys) {
581
+ if (key === `constructor` || key === `__proto__`) {
582
+ valid = pushError(Object.assign(Object.assign({}, state), { p: computeKey(state, key) }), `Unsafe property name`);
583
+ }
584
+ else {
585
+ const spec = Object.prototype.hasOwnProperty.call(props, key)
586
+ ? props[key]
587
+ : undefined;
588
+ const sub = Object.prototype.hasOwnProperty.call(value, key)
589
+ ? value[key]
590
+ : undefined;
591
+ if (typeof spec !== `undefined`) {
592
+ valid = spec(sub, Object.assign(Object.assign({}, state), { p: computeKey(state, key), coercion: makeCoercionFn(value, key) })) && valid;
593
+ }
594
+ else if (extraSpec === null) {
595
+ valid = pushError(Object.assign(Object.assign({}, state), { p: computeKey(state, key) }), `Extraneous property (got ${getPrintable(sub)})`);
596
+ }
597
+ else {
598
+ Object.defineProperty(extra, key, {
599
+ enumerable: true,
600
+ get: () => sub,
601
+ set: makeSetter(value, key)
602
+ });
603
+ }
604
+ }
605
+ if (!valid && (state === null || state === void 0 ? void 0 : state.errors) == null) {
606
+ break;
607
+ }
608
+ }
609
+ if (extraSpec !== null && (valid || (state === null || state === void 0 ? void 0 : state.errors) != null))
610
+ valid = extraSpec(extra, state) && valid;
611
+ return valid;
612
+ },
613
+ });
614
+ return Object.assign(validator, {
615
+ properties: props,
616
+ });
617
+ }
618
+ /**
619
+ * Create a validator that only returns true when the tested value is an
620
+ * object whose all properties match their corresponding subspec. Refines
621
+ * the type into an object whose each property has the type inferred by the
622
+ * corresponding subspec.
623
+ *
624
+ * Unlike `t.isObject`, `t.isPartial` allows extraneous properties. The
625
+ * resulting type will reflect this behaviour by including an index
626
+ * signature (each extraneous property being typed `unknown`).
627
+ *
628
+ * Calling `t.isPartial(...)` is essentially the same as calling
629
+ * `t.isObject(..., {extra: t.isRecord(t.isUnknown())})`.
630
+ */
631
+ function isPartial(props) {
632
+ return isObject(props, { extra: isRecord(isUnknown()) });
633
+ }
634
+ /**
635
+ * Create a validator that only returns true when the tested value is an
636
+ * object whose prototype is derived from the given class. Refines the type
637
+ * into a class instance.
638
+ */
639
+ const isInstanceOf = (constructor) => makeValidator({
640
+ test: (value, state) => {
641
+ if (!(value instanceof constructor))
642
+ return pushError(state, `Expected an instance of ${constructor.name} (got ${getPrintable(value)})`);
643
+ return true;
644
+ },
645
+ });
646
+ /**
647
+ * Create a validator that only returns true when the tested value is an
648
+ * object matching any of the provided subspecs. If the optional `exclusive`
649
+ * parameter is set to `true`, the behaviour changes so that the validator
650
+ * only returns true when exactly one subspec matches.
651
+ */
652
+ const isOneOf = (specs, { exclusive = false, } = {}) => makeValidator({
653
+ test: (value, state) => {
654
+ var _a, _b, _c;
655
+ const matches = [];
656
+ const errorBuffer = typeof (state === null || state === void 0 ? void 0 : state.errors) !== `undefined`
657
+ ? [] : undefined;
658
+ for (let t = 0, T = specs.length; t < T; ++t) {
659
+ const subErrors = typeof (state === null || state === void 0 ? void 0 : state.errors) !== `undefined`
660
+ ? [] : undefined;
661
+ const subCoercions = typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`
662
+ ? [] : undefined;
663
+ if (specs[t](value, Object.assign(Object.assign({}, state), { errors: subErrors, coercions: subCoercions, p: `${(_a = state === null || state === void 0 ? void 0 : state.p) !== null && _a !== void 0 ? _a : `.`}#${t + 1}` }))) {
664
+ matches.push([`#${t + 1}`, subCoercions]);
665
+ if (!exclusive) {
666
+ break;
667
+ }
668
+ }
669
+ else {
670
+ errorBuffer === null || errorBuffer === void 0 ? void 0 : errorBuffer.push(subErrors[0]);
671
+ }
672
+ }
673
+ if (matches.length === 1) {
674
+ const [, subCoercions] = matches[0];
675
+ if (typeof subCoercions !== `undefined`)
676
+ (_b = state === null || state === void 0 ? void 0 : state.coercions) === null || _b === void 0 ? void 0 : _b.push(...subCoercions);
677
+ return true;
678
+ }
679
+ if (matches.length > 1)
680
+ pushError(state, `Expected to match exactly a single predicate (matched ${matches.join(`, `)})`);
681
+ else
682
+ (_c = state === null || state === void 0 ? void 0 : state.errors) === null || _c === void 0 ? void 0 : _c.push(...errorBuffer);
683
+ return false;
684
+ },
685
+ });
686
+
687
+ function makeTrait(value) {
688
+ return () => {
689
+ return value;
690
+ };
691
+ }
692
+ function makeValidator({ test }) {
693
+ return makeTrait(test)();
694
+ }
695
+ class TypeAssertionError extends Error {
696
+ constructor({ errors } = {}) {
697
+ let errorMessage = `Type mismatch`;
698
+ if (errors && errors.length > 0) {
699
+ errorMessage += `\n`;
700
+ for (const error of errors) {
701
+ errorMessage += `\n- ${error}`;
702
+ }
703
+ }
704
+ super(errorMessage);
705
+ }
706
+ }
707
+ /**
708
+ * Check that the specified value matches the given validator, and throws an
709
+ * exception if it doesn't. Refine the type if it passes.
710
+ */
711
+ function assert(val, validator) {
712
+ if (!validator(val)) {
713
+ throw new TypeAssertionError();
714
+ }
715
+ }
716
+ /**
717
+ * Check that the specified value matches the given validator, and throws an
718
+ * exception if it doesn't. Refine the type if it passes.
719
+ *
720
+ * Thrown exceptions include details about what exactly looks invalid in the
721
+ * tested value.
722
+ */
723
+ function assertWithErrors(val, validator) {
724
+ const errors = [];
725
+ if (!validator(val, { errors })) {
726
+ throw new TypeAssertionError({ errors });
727
+ }
728
+ }
729
+ /**
730
+ * Compile-time only. Refine the type as if the validator was matching the
731
+ * tested value, but doesn't actually run it. Similar to the classic `as`
732
+ * operator in TypeScript.
733
+ */
734
+ function softAssert(val, validator) {
735
+ // It's a soft assert; we tell TypeScript about the type, but we don't need to check it
736
+ }
737
+ function as(value, validator, { coerce = false, errors: storeErrors, throw: throws } = {}) {
738
+ const errors = storeErrors ? [] : undefined;
739
+ if (!coerce) {
740
+ if (validator(value, { errors })) {
741
+ return throws ? value : { value, errors: undefined };
742
+ }
743
+ else if (!throws) {
744
+ return { value: undefined, errors: errors !== null && errors !== void 0 ? errors : true };
745
+ }
746
+ else {
747
+ throw new TypeAssertionError({ errors });
748
+ }
749
+ }
750
+ const state = { value };
751
+ const coercion = makeCoercionFn(state, `value`);
752
+ const coercions = [];
753
+ if (!validator(value, { errors, coercion, coercions })) {
754
+ if (!throws) {
755
+ return { value: undefined, errors: errors !== null && errors !== void 0 ? errors : true };
756
+ }
757
+ else {
758
+ throw new TypeAssertionError({ errors });
759
+ }
760
+ }
761
+ for (const [, apply] of coercions)
762
+ apply();
763
+ if (throws) {
764
+ return state.value;
765
+ }
766
+ else {
767
+ return { value: state.value, errors: undefined };
768
+ }
769
+ }
770
+ /**
771
+ * Create and return a new function that apply the given validators to each
772
+ * corresponding argument passed to the function and throws an exception in
773
+ * case of a mismatch.
774
+ */
775
+ function fn(validators, fn) {
776
+ const isValidArgList = isTuple(validators);
777
+ return ((...args) => {
778
+ const check = isValidArgList(args);
779
+ if (!check)
780
+ throw new TypeAssertionError();
781
+ return fn(...args);
782
+ });
783
+ }
784
+
785
+ /**
786
+ * Create a validator that checks that the tested array or string has at least
787
+ * the specified length.
788
+ */
789
+ function hasMinLength(length) {
790
+ return makeValidator({
791
+ test: (value, state) => {
792
+ if (!(value.length >= length))
793
+ return pushError(state, `Expected to have a length of at least ${length} elements (got ${value.length})`);
794
+ return true;
795
+ },
796
+ });
797
+ }
798
+ /**
799
+ * Create a validator that checks that the tested array or string has at most
800
+ * the specified length.
801
+ */
802
+ function hasMaxLength(length) {
803
+ return makeValidator({
804
+ test: (value, state) => {
805
+ if (!(value.length <= length))
806
+ return pushError(state, `Expected to have a length of at most ${length} elements (got ${value.length})`);
807
+ return true;
808
+ },
809
+ });
810
+ }
811
+ /**
812
+ * Create a validator that checks that the tested array or string has exactly
813
+ * the specified length.
814
+ */
815
+ function hasExactLength(length) {
816
+ return makeValidator({
817
+ test: (value, state) => {
818
+ if (!(value.length === length))
819
+ return pushError(state, `Expected to have a length of exactly ${length} elements (got ${value.length})`);
820
+ return true;
821
+ },
822
+ });
823
+ }
824
+ /**
825
+ * Create a validator that checks that the tested array only contains unique
826
+ * elements. The optional `map` parameter lets you define a transform to
827
+ * apply before making the check (the result of this transform will be
828
+ * discarded afterwards).
829
+ */
830
+ function hasUniqueItems({ map, } = {}) {
831
+ return makeValidator({
832
+ test: (value, state) => {
833
+ const set = new Set();
834
+ const dup = new Set();
835
+ for (let t = 0, T = value.length; t < T; ++t) {
836
+ const sub = value[t];
837
+ const key = typeof map !== `undefined`
838
+ ? map(sub)
839
+ : sub;
840
+ if (set.has(key)) {
841
+ if (dup.has(key))
842
+ continue;
843
+ pushError(state, `Expected to contain unique elements; got a duplicate with ${getPrintable(value)}`);
844
+ dup.add(key);
845
+ }
846
+ else {
847
+ set.add(key);
848
+ }
849
+ }
850
+ return dup.size === 0;
851
+ },
852
+ });
853
+ }
854
+ /**
855
+ * Create a validator that checks that the tested number is strictly less than 0.
856
+ */
857
+ function isNegative() {
858
+ return makeValidator({
859
+ test: (value, state) => {
860
+ if (!(value <= 0))
861
+ return pushError(state, `Expected to be negative (got ${value})`);
862
+ return true;
863
+ },
864
+ });
865
+ }
866
+ /**
867
+ * Create a validator that checks that the tested number is equal or greater
868
+ * than 0.
869
+ */
870
+ function isPositive() {
871
+ return makeValidator({
872
+ test: (value, state) => {
873
+ if (!(value >= 0))
874
+ return pushError(state, `Expected to be positive (got ${value})`);
875
+ return true;
876
+ },
877
+ });
878
+ }
879
+ /**
880
+ * Create a validator that checks that the tested number is equal or greater
881
+ * than the specified reference.
882
+ */
883
+ function isAtLeast(n) {
884
+ return makeValidator({
885
+ test: (value, state) => {
886
+ if (!(value >= n))
887
+ return pushError(state, `Expected to be at least ${n} (got ${value})`);
888
+ return true;
889
+ },
890
+ });
891
+ }
892
+ /**
893
+ * Create a validator that checks that the tested number is equal or smaller
894
+ * than the specified reference.
895
+ */
896
+ function isAtMost(n) {
897
+ return makeValidator({
898
+ test: (value, state) => {
899
+ if (!(value <= n))
900
+ return pushError(state, `Expected to be at most ${n} (got ${value})`);
901
+ return true;
902
+ },
903
+ });
904
+ }
905
+ /**
906
+ * Create a validator that checks that the tested number is between the
907
+ * specified references (including the upper boundary).
908
+ */
909
+ function isInInclusiveRange(a, b) {
910
+ return makeValidator({
911
+ test: (value, state) => {
912
+ if (!(value >= a && value <= b))
913
+ return pushError(state, `Expected to be in the [${a}; ${b}] range (got ${value})`);
914
+ return true;
915
+ },
916
+ });
917
+ }
918
+ /**
919
+ * Create a validator that checks that the tested number is between the
920
+ * specified references (excluding the upper boundary).
921
+ */
922
+ function isInExclusiveRange(a, b) {
923
+ return makeValidator({
924
+ test: (value, state) => {
925
+ if (!(value >= a && value < b))
926
+ return pushError(state, `Expected to be in the [${a}; ${b}[ range (got ${value})`);
927
+ return true;
928
+ },
929
+ });
930
+ }
931
+ /**
932
+ * Create a validator that checks that the tested number is an integer.
933
+ *
934
+ * By default Typanion will also check that it's a *safe* integer. For example,
935
+ * 2^53 wouldn't be a safe integer because 2^53+1 would be rounded to 2^53,
936
+ * which could put your applications at risk when used in loops.
937
+ */
938
+ function isInteger({ unsafe = false, } = {}) {
939
+ return makeValidator({
940
+ test: (value, state) => {
941
+ if (value !== Math.round(value))
942
+ return pushError(state, `Expected to be an integer (got ${value})`);
943
+ if (!unsafe && !Number.isSafeInteger(value))
944
+ return pushError(state, `Expected to be a safe integer (got ${value})`);
945
+ return true;
946
+ },
947
+ });
948
+ }
949
+ /**
950
+ * Create a validator that checks that the tested string matches the given
951
+ * regular expression.
952
+ */
953
+ function matchesRegExp(regExp) {
954
+ return makeValidator({
955
+ test: (value, state) => {
956
+ if (!regExp.test(value))
957
+ return pushError(state, `Expected to match the pattern ${regExp.toString()} (got ${getPrintable(value)})`);
958
+ return true;
959
+ },
960
+ });
961
+ }
962
+ /**
963
+ * Create a validator that checks that the tested string only contain lowercase
964
+ * characters.
965
+ */
966
+ function isLowerCase() {
967
+ return makeValidator({
968
+ test: (value, state) => {
969
+ if (value !== value.toLowerCase())
970
+ return pushError(state, `Expected to be all-lowercase (got ${value})`);
971
+ return true;
972
+ },
973
+ });
974
+ }
975
+ /**
976
+ * Create a validator that checks that the tested string only contain uppercase
977
+ * characters.
978
+ */
979
+ function isUpperCase() {
980
+ return makeValidator({
981
+ test: (value, state) => {
982
+ if (value !== value.toUpperCase())
983
+ return pushError(state, `Expected to be all-uppercase (got ${value})`);
984
+ return true;
985
+ },
986
+ });
987
+ }
988
+ /**
989
+ * Create a validator that checks that the tested string is a valid UUID v4.
990
+ */
991
+ function isUUID4() {
992
+ return makeValidator({
993
+ test: (value, state) => {
994
+ if (!uuid4RegExp.test(value))
995
+ return pushError(state, `Expected to be a valid UUID v4 (got ${getPrintable(value)})`);
996
+ return true;
997
+ },
998
+ });
999
+ }
1000
+ /**
1001
+ * Create a validator that checks that the tested string is a valid ISO8601
1002
+ * date.
1003
+ */
1004
+ function isISO8601() {
1005
+ return makeValidator({
1006
+ test: (value, state) => {
1007
+ if (!iso8601RegExp.test(value))
1008
+ return pushError(state, `Expected to be a valid ISO 8601 date string (got ${getPrintable(value)})`);
1009
+ return true;
1010
+ },
1011
+ });
1012
+ }
1013
+ /**
1014
+ * Create a validator that checks that the tested string is a valid hexadecimal
1015
+ * color. Setting the optional `alpha` parameter to `true` allows an additional
1016
+ * transparency channel to be included.
1017
+ */
1018
+ function isHexColor({ alpha = false, }) {
1019
+ return makeValidator({
1020
+ test: (value, state) => {
1021
+ const res = alpha
1022
+ ? colorStringRegExp.test(value)
1023
+ : colorStringAlphaRegExp.test(value);
1024
+ if (!res)
1025
+ return pushError(state, `Expected to be a valid hexadecimal color string (got ${getPrintable(value)})`);
1026
+ return true;
1027
+ },
1028
+ });
1029
+ }
1030
+ /**
1031
+ * Create a validator that checks that the tested string is valid base64.
1032
+ */
1033
+ function isBase64() {
1034
+ return makeValidator({
1035
+ test: (value, state) => {
1036
+ if (!base64RegExp.test(value))
1037
+ return pushError(state, `Expected to be a valid base 64 string (got ${getPrintable(value)})`);
1038
+ return true;
1039
+ },
1040
+ });
1041
+ }
1042
+ /**
1043
+ * Create a validator that checks that the tested string is valid JSON. A
1044
+ * optional spec can be passed as parameter, in which case the data will be
1045
+ * deserialized and validated against the spec (coercion will be disabled
1046
+ * for this check, and even if successful the returned value will still be
1047
+ * the original string).
1048
+ */
1049
+ function isJSON(spec = isUnknown()) {
1050
+ return makeValidator({
1051
+ test: (value, state) => {
1052
+ let data;
1053
+ try {
1054
+ data = JSON.parse(value);
1055
+ }
1056
+ catch (_a) {
1057
+ return pushError(state, `Expected to be a valid JSON string (got ${getPrintable(value)})`);
1058
+ }
1059
+ return spec(data, state);
1060
+ },
1061
+ });
1062
+ }
1063
+
1064
+ function cascade(spec, ...followups) {
1065
+ const resolvedFollowups = Array.isArray(followups[0])
1066
+ ? followups[0]
1067
+ : followups;
1068
+ return makeValidator({
1069
+ test: (value, state) => {
1070
+ var _a, _b;
1071
+ const context = { value: value };
1072
+ const subCoercion = typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`
1073
+ ? makeCoercionFn(context, `value`) : undefined;
1074
+ const subCoercions = typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`
1075
+ ? [] : undefined;
1076
+ if (!spec(value, Object.assign(Object.assign({}, state), { coercion: subCoercion, coercions: subCoercions })))
1077
+ return false;
1078
+ const reverts = [];
1079
+ if (typeof subCoercions !== `undefined`)
1080
+ for (const [, coercion] of subCoercions)
1081
+ reverts.push(coercion());
1082
+ try {
1083
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercions) !== `undefined`) {
1084
+ if (context.value !== value) {
1085
+ if (typeof (state === null || state === void 0 ? void 0 : state.coercion) === `undefined`)
1086
+ return pushError(state, `Unbound coercion result`);
1087
+ state.coercions.push([(_a = state.p) !== null && _a !== void 0 ? _a : `.`, state.coercion.bind(null, context.value)]);
1088
+ }
1089
+ (_b = state === null || state === void 0 ? void 0 : state.coercions) === null || _b === void 0 ? void 0 : _b.push(...subCoercions);
1090
+ }
1091
+ return resolvedFollowups.every(spec => {
1092
+ return spec(context.value, state);
1093
+ });
1094
+ }
1095
+ finally {
1096
+ for (const revert of reverts) {
1097
+ revert();
1098
+ }
1099
+ }
1100
+ },
1101
+ });
1102
+ }
1103
+ function applyCascade(spec, ...followups) {
1104
+ const resolvedFollowups = Array.isArray(followups[0])
1105
+ ? followups[0]
1106
+ : followups;
1107
+ return cascade(spec, resolvedFollowups);
1108
+ }
1109
+ /**
1110
+ * Wraps the given spec to also allow `undefined`.
1111
+ */
1112
+ function isOptional(spec) {
1113
+ return makeValidator({
1114
+ test: (value, state) => {
1115
+ if (typeof value === `undefined`)
1116
+ return true;
1117
+ return spec(value, state);
1118
+ },
1119
+ });
1120
+ }
1121
+ /**
1122
+ * Wraps the given spec to also allow `null`.
1123
+ */
1124
+ function isNullable(spec) {
1125
+ return makeValidator({
1126
+ test: (value, state) => {
1127
+ if (value === null)
1128
+ return true;
1129
+ return spec(value, state);
1130
+ },
1131
+ });
1132
+ }
1133
+ const checks = {
1134
+ missing: (keys, key) => keys.has(key),
1135
+ undefined: (keys, key, value) => keys.has(key) && typeof value[key] !== `undefined`,
1136
+ nil: (keys, key, value) => keys.has(key) && value[key] != null,
1137
+ falsy: (keys, key, value) => keys.has(key) && !!value[key],
1138
+ };
1139
+ /**
1140
+ * Create a validator that checks that the tested object contains the specified
1141
+ * keys.
1142
+ */
1143
+ function hasRequiredKeys(requiredKeys, options) {
1144
+ var _a;
1145
+ const requiredSet = new Set(requiredKeys);
1146
+ const check = checks[(_a = options === null || options === void 0 ? void 0 : options.missingIf) !== null && _a !== void 0 ? _a : 'missing'];
1147
+ return makeValidator({
1148
+ test: (value, state) => {
1149
+ const keys = new Set(Object.keys(value));
1150
+ const problems = [];
1151
+ for (const key of requiredSet)
1152
+ if (!check(keys, key, value))
1153
+ problems.push(key);
1154
+ if (problems.length > 0)
1155
+ return pushError(state, `Missing required ${plural(problems.length, `property`, `properties`)} ${getPrintableArray(problems, `and`)}`);
1156
+ return true;
1157
+ },
1158
+ });
1159
+ }
1160
+ /**
1161
+ * Create a validator that checks that the tested object contains at least one
1162
+ * of the specified keys.
1163
+ */
1164
+ function hasAtLeastOneKey(requiredKeys, options) {
1165
+ var _a;
1166
+ const requiredSet = new Set(requiredKeys);
1167
+ const check = checks[(_a = options === null || options === void 0 ? void 0 : options.missingIf) !== null && _a !== void 0 ? _a : 'missing'];
1168
+ return makeValidator({
1169
+ test: (value, state) => {
1170
+ const keys = Object.keys(value);
1171
+ const valid = keys.some(key => check(requiredSet, key, value));
1172
+ if (!valid)
1173
+ return pushError(state, `Missing at least one property from ${getPrintableArray(Array.from(requiredSet), `or`)}`);
1174
+ return true;
1175
+ },
1176
+ });
1177
+ }
1178
+ /**
1179
+ * Create a validator that checks that the tested object contains none of the
1180
+ * specified keys.
1181
+ */
1182
+ function hasForbiddenKeys(forbiddenKeys, options) {
1183
+ var _a;
1184
+ const forbiddenSet = new Set(forbiddenKeys);
1185
+ const check = checks[(_a = options === null || options === void 0 ? void 0 : options.missingIf) !== null && _a !== void 0 ? _a : 'missing'];
1186
+ return makeValidator({
1187
+ test: (value, state) => {
1188
+ const keys = new Set(Object.keys(value));
1189
+ const problems = [];
1190
+ for (const key of forbiddenSet)
1191
+ if (check(keys, key, value))
1192
+ problems.push(key);
1193
+ if (problems.length > 0)
1194
+ return pushError(state, `Forbidden ${plural(problems.length, `property`, `properties`)} ${getPrintableArray(problems, `and`)}`);
1195
+ return true;
1196
+ },
1197
+ });
1198
+ }
1199
+ /**
1200
+ * Create a validator that checks that the tested object contains at most one
1201
+ * of the specified keys.
1202
+ */
1203
+ function hasMutuallyExclusiveKeys(exclusiveKeys, options) {
1204
+ var _a;
1205
+ const exclusiveSet = new Set(exclusiveKeys);
1206
+ const check = checks[(_a = options === null || options === void 0 ? void 0 : options.missingIf) !== null && _a !== void 0 ? _a : 'missing'];
1207
+ return makeValidator({
1208
+ test: (value, state) => {
1209
+ const keys = new Set(Object.keys(value));
1210
+ const used = [];
1211
+ for (const key of exclusiveSet)
1212
+ if (check(keys, key, value))
1213
+ used.push(key);
1214
+ if (used.length > 1)
1215
+ return pushError(state, `Mutually exclusive properties ${getPrintableArray(used, `and`)}`);
1216
+ return true;
1217
+ },
1218
+ });
1219
+ }
1220
+ (function (KeyRelationship) {
1221
+ KeyRelationship["Forbids"] = "Forbids";
1222
+ KeyRelationship["Requires"] = "Requires";
1223
+ })(exports.KeyRelationship || (exports.KeyRelationship = {}));
1224
+ const keyRelationships = {
1225
+ [exports.KeyRelationship.Forbids]: {
1226
+ expect: false,
1227
+ message: `forbids using`,
1228
+ },
1229
+ [exports.KeyRelationship.Requires]: {
1230
+ expect: true,
1231
+ message: `requires using`,
1232
+ },
1233
+ };
1234
+ /**
1235
+ * Create a validator that checks that, when the specified subject property is
1236
+ * set, the relationship is satisfied.
1237
+ */
1238
+ function hasKeyRelationship(subject, relationship, others, options) {
1239
+ var _a, _b;
1240
+ const skipped = new Set((_a = options === null || options === void 0 ? void 0 : options.ignore) !== null && _a !== void 0 ? _a : []);
1241
+ const check = checks[(_b = options === null || options === void 0 ? void 0 : options.missingIf) !== null && _b !== void 0 ? _b : 'missing'];
1242
+ const otherSet = new Set(others);
1243
+ const spec = keyRelationships[relationship];
1244
+ const conjunction = relationship === exports.KeyRelationship.Forbids
1245
+ ? `or`
1246
+ : `and`;
1247
+ return makeValidator({
1248
+ test: (value, state) => {
1249
+ const keys = new Set(Object.keys(value));
1250
+ if (!check(keys, subject, value) || skipped.has(value[subject]))
1251
+ return true;
1252
+ const problems = [];
1253
+ for (const key of otherSet)
1254
+ if ((check(keys, key, value) && !skipped.has(value[key])) !== spec.expect)
1255
+ problems.push(key);
1256
+ if (problems.length >= 1)
1257
+ return pushError(state, `Property "${subject}" ${spec.message} ${plural(problems.length, `property`, `properties`)} ${getPrintableArray(problems, conjunction)}`);
1258
+ return true;
1259
+ },
1260
+ });
1261
+ }
1262
+
1263
+ exports.TypeAssertionError = TypeAssertionError;
1264
+ exports.applyCascade = applyCascade;
1265
+ exports.as = as;
1266
+ exports.assert = assert;
1267
+ exports.assertWithErrors = assertWithErrors;
1268
+ exports.cascade = cascade;
1269
+ exports.fn = fn;
1270
+ exports.hasAtLeastOneKey = hasAtLeastOneKey;
1271
+ exports.hasExactLength = hasExactLength;
1272
+ exports.hasForbiddenKeys = hasForbiddenKeys;
1273
+ exports.hasKeyRelationship = hasKeyRelationship;
1274
+ exports.hasMaxLength = hasMaxLength;
1275
+ exports.hasMinLength = hasMinLength;
1276
+ exports.hasMutuallyExclusiveKeys = hasMutuallyExclusiveKeys;
1277
+ exports.hasRequiredKeys = hasRequiredKeys;
1278
+ exports.hasUniqueItems = hasUniqueItems;
1279
+ exports.isArray = isArray;
1280
+ exports.isAtLeast = isAtLeast;
1281
+ exports.isAtMost = isAtMost;
1282
+ exports.isBase64 = isBase64;
1283
+ exports.isBoolean = isBoolean;
1284
+ exports.isDate = isDate;
1285
+ exports.isDict = isDict;
1286
+ exports.isEnum = isEnum;
1287
+ exports.isHexColor = isHexColor;
1288
+ exports.isISO8601 = isISO8601;
1289
+ exports.isInExclusiveRange = isInExclusiveRange;
1290
+ exports.isInInclusiveRange = isInInclusiveRange;
1291
+ exports.isInstanceOf = isInstanceOf;
1292
+ exports.isInteger = isInteger;
1293
+ exports.isJSON = isJSON;
1294
+ exports.isLiteral = isLiteral;
1295
+ exports.isLowerCase = isLowerCase;
1296
+ exports.isMap = isMap;
1297
+ exports.isNegative = isNegative;
1298
+ exports.isNullable = isNullable;
1299
+ exports.isNumber = isNumber;
1300
+ exports.isObject = isObject;
1301
+ exports.isOneOf = isOneOf;
1302
+ exports.isOptional = isOptional;
1303
+ exports.isPartial = isPartial;
1304
+ exports.isPayload = isPayload;
1305
+ exports.isPositive = isPositive;
1306
+ exports.isRecord = isRecord;
1307
+ exports.isSet = isSet;
1308
+ exports.isString = isString;
1309
+ exports.isTuple = isTuple;
1310
+ exports.isUUID4 = isUUID4;
1311
+ exports.isUnknown = isUnknown;
1312
+ exports.isUpperCase = isUpperCase;
1313
+ exports.makeTrait = makeTrait;
1314
+ exports.makeValidator = makeValidator;
1315
+ exports.matchesRegExp = matchesRegExp;
1316
+ exports.softAssert = softAssert;
1317
+
1318
+
1319
+ /***/ })
1320
+
1321
+ };
1322
+ ;
1323
+ //# sourceMappingURL=vendors-node_modules_typanion_lib_index_js.main.cjs.map