decoders 2.7.5 → 2.8.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -11,8 +11,11 @@ function isBigInt(value) {
11
11
  function isDate(value) {
12
12
  return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
13
13
  }
14
- function isPojo(value) {
15
- return value !== null && value !== void 0 && typeof value === "object" && // This still seems to be the only reliable way to determine whether
14
+ function isPromiseLike(value) {
15
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
16
+ }
17
+ function isPlainObject(value) {
18
+ return value !== null && typeof value === "object" && // This still seems to be the only reliable way to determine whether
16
19
  // something is a pojo... ¯\_(ツ)_/¯
17
20
  Object.prototype.toString.call(value) === "[object Object]";
18
21
  }
@@ -68,7 +71,7 @@ function annotateObject(obj, text, seen) {
68
71
  return makeObjectAnn(fields, text);
69
72
  }
70
73
  function annotate(value, text, seen) {
71
- if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value.getMonth === "function") {
74
+ if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value === "bigint" || typeof value.getMonth === "function") {
72
75
  return makeScalarAnn(value, text);
73
76
  }
74
77
  if (isAnnotation(value)) {
@@ -81,7 +84,7 @@ function annotate(value, text, seen) {
81
84
  return annotateArray(value, text, seen);
82
85
  }
83
86
  }
84
- if (isPojo(value)) {
87
+ if (isPlainObject(value)) {
85
88
  if (seen.has(value)) {
86
89
  return makeOpaqueAnn("<circular ref>", text);
87
90
  } else {
@@ -91,7 +94,14 @@ function annotate(value, text, seen) {
91
94
  if (typeof value === "function") {
92
95
  return makeOpaqueAnn("<function>", text);
93
96
  }
94
- return makeOpaqueAnn("???", text);
97
+ if (isPromiseLike(value)) {
98
+ return makeOpaqueAnn("<Promise>", text);
99
+ }
100
+ if (_optionalChain([value, 'optionalAccess', _2 => _2.constructor, 'optionalAccess', _3 => _3.name])) {
101
+ return makeOpaqueAnn(`<${value.constructor.name}>`, text);
102
+ } else {
103
+ return makeOpaqueAnn("???", text);
104
+ }
95
105
  }
96
106
  function public_annotate(value, text) {
97
107
  return annotate(value, text, /* @__PURE__ */ new WeakSet());
@@ -200,6 +210,8 @@ function serializeValue(value) {
200
210
  return "null";
201
211
  } else if (value === void 0) {
202
212
  return "undefined";
213
+ } else if (typeof value === "bigint") {
214
+ return `${value.toString()}n`;
203
215
  } else {
204
216
  if (isDate(value)) {
205
217
  return `new Date(${quote(value.toISOString())})`;
@@ -403,8 +415,8 @@ function brand2(decoder) {
403
415
  _register2.add(decoder);
404
416
  return decoder;
405
417
  }
406
- function isDecoder(thing) {
407
- return _register2.has(thing);
418
+ function isDecoder(value) {
419
+ return _register2.has(value);
408
420
  }
409
421
 
410
422
  // src/arrays.ts
@@ -510,7 +522,7 @@ function difference(xs, ys) {
510
522
 
511
523
  // src/objects.ts
512
524
  var pojo = define(
513
- (blob, ok2, err2) => isPojo(blob) ? ok2(blob) : err2("Must be an object")
525
+ (blob, ok2, err2) => isPlainObject(blob) ? ok2(blob) : err2("Must be an object")
514
526
  );
515
527
  function object(decoders) {
516
528
  const knownKeys = new Set(Object.keys(decoders));
@@ -669,7 +681,6 @@ function nullable(decoder, defaultValue) {
669
681
  const rv = either(null_, decoder);
670
682
  return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
671
683
  }
672
- var maybe = nullish;
673
684
  function nullish(decoder, defaultValue) {
674
685
  const rv = either(nullish_, decoder);
675
686
  return arguments.length >= 2 ? rv.transform((value) => _nullishCoalesce(value, () => ( lazyval(defaultValue)))) : rv;
@@ -688,9 +699,8 @@ function never(msg) {
688
699
  return define((_, __, err2) => err2(msg));
689
700
  }
690
701
  var fail = never;
691
- var hardcoded = always;
692
702
  var unknown = define((blob, ok2, _) => ok2(blob));
693
- var mixed = unknown;
703
+ var anything = unknown;
694
704
 
695
705
  // src/booleans.ts
696
706
  var boolean = define((blob, ok2, err2) => {
@@ -707,13 +717,13 @@ function record(fst, snd) {
707
717
  const errors = /* @__PURE__ */ new Map();
708
718
  for (const key of Object.keys(input)) {
709
719
  const value = input[key];
710
- const keyResult = _optionalChain([keyDecoder, 'optionalAccess', _2 => _2.decode, 'call', _3 => _3(key)]);
711
- if (_optionalChain([keyResult, 'optionalAccess', _4 => _4.ok]) === false) {
720
+ const keyResult = _optionalChain([keyDecoder, 'optionalAccess', _4 => _4.decode, 'call', _5 => _5(key)]);
721
+ if (_optionalChain([keyResult, 'optionalAccess', _6 => _6.ok]) === false) {
712
722
  return err2(
713
723
  public_annotate(input, `Invalid key ${quote(key)}: ${formatShort(keyResult.error)}`)
714
724
  );
715
725
  }
716
- const k = _nullishCoalesce(_optionalChain([keyResult, 'optionalAccess', _5 => _5.value]), () => ( key));
726
+ const k = _nullishCoalesce(_optionalChain([keyResult, 'optionalAccess', _7 => _7.value]), () => ( key));
717
727
  const result = valueDecoder.decode(value);
718
728
  if (result.ok) {
719
729
  if (errors.size === 0) {
@@ -731,11 +741,9 @@ function record(fst, snd) {
731
741
  }
732
742
  });
733
743
  }
734
- var dict = record;
735
744
  function setFromArray(decoder) {
736
745
  return array(decoder).transform((items) => new Set(items));
737
746
  }
738
- var set = setFromArray;
739
747
  function mapping(decoder) {
740
748
  return record(decoder).transform((obj) => new Map(Object.entries(obj)));
741
749
  }
@@ -823,7 +831,7 @@ var dateString = regex(
823
831
  iso8601_re,
824
832
  "Must be ISO8601 format"
825
833
  ).refine(
826
- (value) => !isNaN(new Date(value).getTime()),
834
+ (value) => !Number.isNaN(new Date(value).getTime()),
827
835
  "Must be valid date/time value"
828
836
  );
829
837
  var iso8601 = dateString.transform((value) => new Date(value));
@@ -935,4 +943,6 @@ var json = either(
935
943
 
936
944
 
937
945
 
938
- exports.always = always; exports.anyNumber = anyNumber; exports.array = array; exports.bigint = bigint; exports.boolean = boolean; exports.constant = constant; exports.date = date; exports.dateString = dateString; exports.datelike = datelike; exports.decimal = decimal; exports.define = define; exports.dict = dict; exports.either = either; exports.email = email; exports.endsWith = endsWith; exports.enum_ = enum_; exports.err = err; exports.exact = exact; exports.fail = fail; exports.formatInline = formatInline; exports.formatShort = formatShort; exports.hardcoded = hardcoded; exports.hexadecimal = hexadecimal; exports.httpsUrl = httpsUrl; exports.identifier = identifier; exports.inexact = inexact; exports.instanceOf = instanceOf; exports.integer = integer; exports.iso8601 = iso8601; exports.json = json; exports.jsonArray = jsonArray; exports.jsonObject = jsonObject; exports.lazy = lazy; exports.mapping = mapping; exports.maybe = maybe; exports.mixed = mixed; exports.nanoid = nanoid; exports.never = never; exports.nonEmptyArray = nonEmptyArray; exports.nonEmptyString = nonEmptyString; exports.null_ = null_; exports.nullable = nullable; exports.nullish = nullish; exports.number = number; exports.numeric = numeric; exports.object = object; exports.ok = ok; exports.oneOf = oneOf; exports.optional = optional; exports.poja = poja; exports.pojo = pojo; exports.positiveInteger = positiveInteger; exports.positiveNumber = positiveNumber; exports.prep = prep; exports.record = record; exports.regex = regex; exports.select = select; exports.set = set; exports.setFromArray = setFromArray; exports.startsWith = startsWith; exports.string = string; exports.taggedUnion = taggedUnion; exports.truthy = truthy; exports.tuple = tuple; exports.undefined_ = undefined_; exports.unknown = unknown; exports.url = url; exports.uuid = uuid; exports.uuidv1 = uuidv1; exports.uuidv4 = uuidv4;
946
+
947
+ exports._annotate = public_annotate; exports.always = always; exports.anyNumber = anyNumber; exports.anything = anything; exports.array = array; exports.bigint = bigint; exports.boolean = boolean; exports.constant = constant; exports.date = date; exports.dateString = dateString; exports.datelike = datelike; exports.decimal = decimal; exports.define = define; exports.either = either; exports.email = email; exports.endsWith = endsWith; exports.enum_ = enum_; exports.err = err; exports.exact = exact; exports.fail = fail; exports.formatInline = formatInline; exports.formatShort = formatShort; exports.hexadecimal = hexadecimal; exports.httpsUrl = httpsUrl; exports.identifier = identifier; exports.inexact = inexact; exports.instanceOf = instanceOf; exports.integer = integer; exports.isDate = isDate; exports.isDecoder = isDecoder; exports.isPlainObject = isPlainObject; exports.isPromiseLike = isPromiseLike; exports.iso8601 = iso8601; exports.json = json; exports.jsonArray = jsonArray; exports.jsonObject = jsonObject; exports.lazy = lazy; exports.mapping = mapping; exports.nanoid = nanoid; exports.never = never; exports.nonEmptyArray = nonEmptyArray; exports.nonEmptyString = nonEmptyString; exports.null_ = null_; exports.nullable = nullable; exports.nullish = nullish; exports.number = number; exports.numeric = numeric; exports.object = object; exports.ok = ok; exports.oneOf = oneOf; exports.optional = optional; exports.poja = poja; exports.pojo = pojo; exports.positiveInteger = positiveInteger; exports.positiveNumber = positiveNumber; exports.prep = prep; exports.record = record; exports.regex = regex; exports.select = select; exports.setFromArray = setFromArray; exports.startsWith = startsWith; exports.string = string; exports.taggedUnion = taggedUnion; exports.truthy = truthy; exports.tuple = tuple; exports.undefined_ = undefined_; exports.unknown = unknown; exports.url = url; exports.uuid = uuid; exports.uuidv1 = uuidv1; exports.uuidv4 = uuidv4;
948
+ // istanbul ignore else -- @preserve
package/dist/index.d.cts CHANGED
@@ -19,6 +19,7 @@ interface OpaqueAnnotation {
19
19
  readonly text?: string;
20
20
  }
21
21
  type Annotation = ObjectAnnotation | ArrayAnnotation | ScalarAnnotation | OpaqueAnnotation;
22
+ declare function public_annotate(value: unknown, text?: string): Annotation;
22
23
 
23
24
  /**
24
25
  * Result <value> <error>
@@ -208,6 +209,10 @@ type DecoderType<D extends Decoder<any>> = D extends Decoder<infer T> ? T : neve
208
209
  * effects! You'll need to _return_ those values.
209
210
  */
210
211
  declare function define<T>(fn: AcceptanceFn<T>): Decoder<T>;
212
+ /**
213
+ * Returns whether the given value is a Decoder instance.
214
+ */
215
+ declare function isDecoder(value: unknown): value is Decoder<unknown>;
211
216
 
212
217
  type Formatter = (err: Annotation) => string | Error;
213
218
  declare function formatInline(ann: Annotation): string;
@@ -264,12 +269,6 @@ declare function optional<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V
264
269
  declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
265
270
  declare function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
266
271
  declare function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
267
- /**
268
- * @deprecated Will get removed in a future version.
269
- *
270
- * Alias of `nullish()`.
271
- */
272
- declare const maybe: typeof nullish;
273
272
  /**
274
273
  * Accepts whatever the given decoder accepts, or `null`, or `undefined`.
275
274
  *
@@ -300,12 +299,6 @@ declare function never(msg: string): Decoder<never>;
300
299
  * Alias of `never()`.
301
300
  */
302
301
  declare const fail: typeof never;
303
- /**
304
- * Alias of `always()`.
305
- *
306
- * @deprecated Will get removed in a future version.
307
- */
308
- declare const hardcoded: typeof always;
309
302
  /**
310
303
  * Accepts anything and returns it unchanged.
311
304
  *
@@ -316,10 +309,8 @@ declare const hardcoded: typeof always;
316
309
  declare const unknown: Decoder<unknown>;
317
310
  /**
318
311
  * Alias of `unknown`.
319
- *
320
- * @deprecated Will get removed in a future version.
321
312
  */
322
- declare const mixed: Decoder<unknown>;
313
+ declare const anything: Decoder<unknown>;
323
314
 
324
315
  /**
325
316
  * Accepts and returns booleans.
@@ -341,24 +332,11 @@ declare function record<V>(valueDecoder: Decoder<V>): Decoder<Record<string, V>>
341
332
  * strings.
342
333
  */
343
334
  declare function record<K extends string, V>(keyDecoder: Decoder<K>, valueDecoder: Decoder<V>): Decoder<Record<K, V>>;
344
- /**
345
- * @deprecated Will get removed in a future version.
346
- *
347
- * Alias of `record()`.
348
- */
349
- declare const dict: typeof record;
350
335
  /**
351
336
  * Similar to `array()`, but returns the result as an [ES6
352
337
  * Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
353
338
  */
354
339
  declare function setFromArray<T>(decoder: Decoder<T>): Decoder<Set<T>>;
355
- /**
356
- * Renamed to `setFromArray` to make room for a future `set()` decoder that
357
- * works differently.
358
- *
359
- * @deprecated This decoder will change behavior in a future version.
360
- */
361
- declare const set: typeof setFromArray;
362
340
  /**
363
341
  * Similar to `record()`, but returns the result as a `Map<string, T>` (an [ES6
364
342
  * Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
@@ -668,4 +646,18 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>>(field:
668
646
  */
669
647
  declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
670
648
 
671
- export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, dateString, datelike, decimal, define, dict, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
649
+ /**
650
+ * Returns whether the given value is a Date object.
651
+ * NOTE: Invalid dates are not considered dates by this check.
652
+ */
653
+ declare function isDate(value: unknown): value is Date;
654
+ /**
655
+ * Returns whether the given value is a Promise-like, i.e. has a `then` method.
656
+ */
657
+ declare function isPromiseLike(value: unknown): value is PromiseLike<unknown>;
658
+ /**
659
+ * Returns whether the given value is a plain old JS object (POJO).
660
+ */
661
+ declare function isPlainObject(value: unknown): value is Record<string, unknown>;
662
+
663
+ export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, public_annotate as _annotate, always, anyNumber, anything, array, bigint, boolean, constant, date, dateString, datelike, decimal, define, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, isDate, isDecoder, isPlainObject, isPromiseLike, iso8601, json, jsonArray, jsonObject, lazy, mapping, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ interface OpaqueAnnotation {
19
19
  readonly text?: string;
20
20
  }
21
21
  type Annotation = ObjectAnnotation | ArrayAnnotation | ScalarAnnotation | OpaqueAnnotation;
22
+ declare function public_annotate(value: unknown, text?: string): Annotation;
22
23
 
23
24
  /**
24
25
  * Result <value> <error>
@@ -208,6 +209,10 @@ type DecoderType<D extends Decoder<any>> = D extends Decoder<infer T> ? T : neve
208
209
  * effects! You'll need to _return_ those values.
209
210
  */
210
211
  declare function define<T>(fn: AcceptanceFn<T>): Decoder<T>;
212
+ /**
213
+ * Returns whether the given value is a Decoder instance.
214
+ */
215
+ declare function isDecoder(value: unknown): value is Decoder<unknown>;
211
216
 
212
217
  type Formatter = (err: Annotation) => string | Error;
213
218
  declare function formatInline(ann: Annotation): string;
@@ -264,12 +269,6 @@ declare function optional<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V
264
269
  declare function nullable<T>(decoder: Decoder<T>): Decoder<T | null>;
265
270
  declare function nullable<T, C extends Scalar>(decoder: Decoder<T>, defaultValue: (() => C) | C): Decoder<NonNullable<T> | C>;
266
271
  declare function nullable<T, V>(decoder: Decoder<T>, defaultValue: (() => V) | V): Decoder<NonNullable<T> | V>;
267
- /**
268
- * @deprecated Will get removed in a future version.
269
- *
270
- * Alias of `nullish()`.
271
- */
272
- declare const maybe: typeof nullish;
273
272
  /**
274
273
  * Accepts whatever the given decoder accepts, or `null`, or `undefined`.
275
274
  *
@@ -300,12 +299,6 @@ declare function never(msg: string): Decoder<never>;
300
299
  * Alias of `never()`.
301
300
  */
302
301
  declare const fail: typeof never;
303
- /**
304
- * Alias of `always()`.
305
- *
306
- * @deprecated Will get removed in a future version.
307
- */
308
- declare const hardcoded: typeof always;
309
302
  /**
310
303
  * Accepts anything and returns it unchanged.
311
304
  *
@@ -316,10 +309,8 @@ declare const hardcoded: typeof always;
316
309
  declare const unknown: Decoder<unknown>;
317
310
  /**
318
311
  * Alias of `unknown`.
319
- *
320
- * @deprecated Will get removed in a future version.
321
312
  */
322
- declare const mixed: Decoder<unknown>;
313
+ declare const anything: Decoder<unknown>;
323
314
 
324
315
  /**
325
316
  * Accepts and returns booleans.
@@ -341,24 +332,11 @@ declare function record<V>(valueDecoder: Decoder<V>): Decoder<Record<string, V>>
341
332
  * strings.
342
333
  */
343
334
  declare function record<K extends string, V>(keyDecoder: Decoder<K>, valueDecoder: Decoder<V>): Decoder<Record<K, V>>;
344
- /**
345
- * @deprecated Will get removed in a future version.
346
- *
347
- * Alias of `record()`.
348
- */
349
- declare const dict: typeof record;
350
335
  /**
351
336
  * Similar to `array()`, but returns the result as an [ES6
352
337
  * Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).
353
338
  */
354
339
  declare function setFromArray<T>(decoder: Decoder<T>): Decoder<Set<T>>;
355
- /**
356
- * Renamed to `setFromArray` to make room for a future `set()` decoder that
357
- * works differently.
358
- *
359
- * @deprecated This decoder will change behavior in a future version.
360
- */
361
- declare const set: typeof setFromArray;
362
340
  /**
363
341
  * Similar to `record()`, but returns the result as a `Map<string, T>` (an [ES6
364
342
  * Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map))
@@ -668,4 +646,18 @@ declare function taggedUnion<O extends Record<string, Decoder<unknown>>>(field:
668
646
  */
669
647
  declare function select<T, D extends Decoder<unknown>>(scout: Decoder<T>, selectFn: (result: T) => D): Decoder<DecoderType<D>>;
670
648
 
671
- export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, always, anyNumber, array, bigint, boolean, constant, date, dateString, datelike, decimal, define, dict, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hardcoded, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, iso8601, json, jsonArray, jsonObject, lazy, mapping, maybe, mixed, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, set, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
649
+ /**
650
+ * Returns whether the given value is a Date object.
651
+ * NOTE: Invalid dates are not considered dates by this check.
652
+ */
653
+ declare function isDate(value: unknown): value is Date;
654
+ /**
655
+ * Returns whether the given value is a Promise-like, i.e. has a `then` method.
656
+ */
657
+ declare function isPromiseLike(value: unknown): value is PromiseLike<unknown>;
658
+ /**
659
+ * Returns whether the given value is a plain old JS object (POJO).
660
+ */
661
+ declare function isPlainObject(value: unknown): value is Record<string, unknown>;
662
+
663
+ export { type DecodeResult, type Decoder, type DecoderType, type Err, type Formatter, type JSONArray, type JSONObject, type JSONValue, type Ok, type Result, type Scalar, type SizeOptions, public_annotate as _annotate, always, anyNumber, anything, array, bigint, boolean, constant, date, dateString, datelike, decimal, define, either, email, endsWith, enum_, err, exact, fail, formatInline, formatShort, hexadecimal, httpsUrl, identifier, inexact, instanceOf, integer, isDate, isDecoder, isPlainObject, isPromiseLike, iso8601, json, jsonArray, jsonObject, lazy, mapping, nanoid, never, nonEmptyArray, nonEmptyString, null_, nullable, nullish, number, numeric, object, ok, oneOf, optional, poja, pojo, positiveInteger, positiveNumber, prep, record, regex, select, setFromArray, startsWith, string, taggedUnion, truthy, tuple, undefined_, unknown, url, uuid, uuidv1, uuidv4 };
package/dist/index.js CHANGED
@@ -11,8 +11,11 @@ function isBigInt(value) {
11
11
  function isDate(value) {
12
12
  return !!value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
13
13
  }
14
- function isPojo(value) {
15
- return value !== null && value !== void 0 && typeof value === "object" && // This still seems to be the only reliable way to determine whether
14
+ function isPromiseLike(value) {
15
+ return typeof value === "object" && value !== null && "then" in value && typeof value.then === "function";
16
+ }
17
+ function isPlainObject(value) {
18
+ return value !== null && typeof value === "object" && // This still seems to be the only reliable way to determine whether
16
19
  // something is a pojo... ¯\_(ツ)_/¯
17
20
  Object.prototype.toString.call(value) === "[object Object]";
18
21
  }
@@ -68,7 +71,7 @@ function annotateObject(obj, text, seen) {
68
71
  return makeObjectAnn(fields, text);
69
72
  }
70
73
  function annotate(value, text, seen) {
71
- if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value.getMonth === "function") {
74
+ if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "symbol" || typeof value === "bigint" || typeof value.getMonth === "function") {
72
75
  return makeScalarAnn(value, text);
73
76
  }
74
77
  if (isAnnotation(value)) {
@@ -81,7 +84,7 @@ function annotate(value, text, seen) {
81
84
  return annotateArray(value, text, seen);
82
85
  }
83
86
  }
84
- if (isPojo(value)) {
87
+ if (isPlainObject(value)) {
85
88
  if (seen.has(value)) {
86
89
  return makeOpaqueAnn("<circular ref>", text);
87
90
  } else {
@@ -91,7 +94,14 @@ function annotate(value, text, seen) {
91
94
  if (typeof value === "function") {
92
95
  return makeOpaqueAnn("<function>", text);
93
96
  }
94
- return makeOpaqueAnn("???", text);
97
+ if (isPromiseLike(value)) {
98
+ return makeOpaqueAnn("<Promise>", text);
99
+ }
100
+ if (value?.constructor?.name) {
101
+ return makeOpaqueAnn(`<${value.constructor.name}>`, text);
102
+ } else {
103
+ return makeOpaqueAnn("???", text);
104
+ }
95
105
  }
96
106
  function public_annotate(value, text) {
97
107
  return annotate(value, text, /* @__PURE__ */ new WeakSet());
@@ -200,6 +210,8 @@ function serializeValue(value) {
200
210
  return "null";
201
211
  } else if (value === void 0) {
202
212
  return "undefined";
213
+ } else if (typeof value === "bigint") {
214
+ return `${value.toString()}n`;
203
215
  } else {
204
216
  if (isDate(value)) {
205
217
  return `new Date(${quote(value.toISOString())})`;
@@ -403,8 +415,8 @@ function brand2(decoder) {
403
415
  _register2.add(decoder);
404
416
  return decoder;
405
417
  }
406
- function isDecoder(thing) {
407
- return _register2.has(thing);
418
+ function isDecoder(value) {
419
+ return _register2.has(value);
408
420
  }
409
421
 
410
422
  // src/arrays.ts
@@ -510,7 +522,7 @@ function difference(xs, ys) {
510
522
 
511
523
  // src/objects.ts
512
524
  var pojo = define(
513
- (blob, ok2, err2) => isPojo(blob) ? ok2(blob) : err2("Must be an object")
525
+ (blob, ok2, err2) => isPlainObject(blob) ? ok2(blob) : err2("Must be an object")
514
526
  );
515
527
  function object(decoders) {
516
528
  const knownKeys = new Set(Object.keys(decoders));
@@ -669,7 +681,6 @@ function nullable(decoder, defaultValue) {
669
681
  const rv = either(null_, decoder);
670
682
  return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
671
683
  }
672
- var maybe = nullish;
673
684
  function nullish(decoder, defaultValue) {
674
685
  const rv = either(nullish_, decoder);
675
686
  return arguments.length >= 2 ? rv.transform((value) => value ?? lazyval(defaultValue)) : rv;
@@ -688,9 +699,8 @@ function never(msg) {
688
699
  return define((_, __, err2) => err2(msg));
689
700
  }
690
701
  var fail = never;
691
- var hardcoded = always;
692
702
  var unknown = define((blob, ok2, _) => ok2(blob));
693
- var mixed = unknown;
703
+ var anything = unknown;
694
704
 
695
705
  // src/booleans.ts
696
706
  var boolean = define((blob, ok2, err2) => {
@@ -731,11 +741,9 @@ function record(fst, snd) {
731
741
  }
732
742
  });
733
743
  }
734
- var dict = record;
735
744
  function setFromArray(decoder) {
736
745
  return array(decoder).transform((items) => new Set(items));
737
746
  }
738
- var set = setFromArray;
739
747
  function mapping(decoder) {
740
748
  return record(decoder).transform((obj) => new Map(Object.entries(obj)));
741
749
  }
@@ -823,7 +831,7 @@ var dateString = regex(
823
831
  iso8601_re,
824
832
  "Must be ISO8601 format"
825
833
  ).refine(
826
- (value) => !isNaN(new Date(value).getTime()),
834
+ (value) => !Number.isNaN(new Date(value).getTime()),
827
835
  "Must be valid date/time value"
828
836
  );
829
837
  var iso8601 = dateString.transform((value) => new Date(value));
@@ -865,8 +873,10 @@ var json = either(
865
873
  jsonArray
866
874
  ).describe("Must be valid JSON value");
867
875
  export {
876
+ public_annotate as _annotate,
868
877
  always,
869
878
  anyNumber,
879
+ anything,
870
880
  array,
871
881
  bigint,
872
882
  boolean,
@@ -876,7 +886,6 @@ export {
876
886
  datelike,
877
887
  decimal,
878
888
  define,
879
- dict,
880
889
  either,
881
890
  email,
882
891
  endsWith,
@@ -886,21 +895,22 @@ export {
886
895
  fail,
887
896
  formatInline,
888
897
  formatShort,
889
- hardcoded,
890
898
  hexadecimal,
891
899
  httpsUrl,
892
900
  identifier,
893
901
  inexact,
894
902
  instanceOf,
895
903
  integer,
904
+ isDate,
905
+ isDecoder,
906
+ isPlainObject,
907
+ isPromiseLike,
896
908
  iso8601,
897
909
  json,
898
910
  jsonArray,
899
911
  jsonObject,
900
912
  lazy,
901
913
  mapping,
902
- maybe,
903
- mixed,
904
914
  nanoid,
905
915
  never,
906
916
  nonEmptyArray,
@@ -922,7 +932,6 @@ export {
922
932
  record,
923
933
  regex,
924
934
  select,
925
- set,
926
935
  setFromArray,
927
936
  startsWith,
928
937
  string,
@@ -936,3 +945,4 @@ export {
936
945
  uuidv1,
937
946
  uuidv4
938
947
  };
948
+ // istanbul ignore else -- @preserve
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decoders",
3
- "version": "2.7.5",
3
+ "version": "2.8.0-1",
4
4
  "description": "Elegant and battle-tested validation library for type-safe input data for TypeScript",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,6 +45,7 @@
45
45
  "test:completeness": "./bin/check.sh",
46
46
  "test:typescript": "tsc --noEmit",
47
47
  "test:types": "npm run build && tsd --typings ./dist/index.d.ts",
48
+ "test:watch": "vitest --coverage",
48
49
  "release": "npm run test && npm run lint && npm run lint:docs && npm run build && npm run lint:package && release-it"
49
50
  },
50
51
  "keywords": [
@@ -60,27 +61,27 @@
60
61
  "verify"
61
62
  ],
62
63
  "devDependencies": {
63
- "@arethetypeswrong/cli": "^0.17.4",
64
- "@eslint/js": "^9.23.0",
64
+ "@arethetypeswrong/cli": "^0.18.2",
65
+ "@eslint/js": "^9.35.0",
65
66
  "@release-it/keep-a-changelog": "^7.0.0",
66
67
  "@standard-schema/spec": "^1.0.0",
67
- "@vitest/coverage-istanbul": "^3.0.9",
68
- "eslint": "^9.23.0",
69
- "eslint-plugin-import": "^2.31.0",
68
+ "@vitest/coverage-istanbul": "^3.2.4",
69
+ "eslint": "^9.35.0",
70
+ "eslint-plugin-import": "^2.32.0",
70
71
  "eslint-plugin-simple-import-sort": "^12.1.1",
71
- "fast-check": "^4.0.0",
72
- "itertools": "^2.4.1",
73
- "pkg-pr-new": "^0.0.41",
74
- "prettier": "^3.5.3",
75
- "publint": "^0.3.9",
76
- "release-it": "^19.0.4",
77
- "ts-morph": "^25.0.1",
78
- "tsd": "^0.31.2",
79
- "tsup": "^8.4.0",
80
- "typescript": "^5.8.2",
81
- "typescript-eslint": "^8.28.0",
72
+ "fast-check": "^4.3.0",
73
+ "itertools": "^2.5.0",
74
+ "pkg-pr-new": "^0.0.60",
75
+ "prettier": "^3.6.2",
76
+ "publint": "^0.3.13",
77
+ "release-it": "^19.0.5",
78
+ "ts-morph": "^27.0.0",
79
+ "tsd": "^0.33.0",
80
+ "tsup": "^8.5.0",
81
+ "typescript": "^5.9.2",
82
+ "typescript-eslint": "^8.44.0",
82
83
  "vite-tsconfig-paths": "^5.1.4",
83
- "vitest": "^3.0.9"
84
+ "vitest": "^3.2.4"
84
85
  },
85
86
  "githubUrl": "https://github.com/nvie/decoders",
86
87
  "sideEffects": false