decoders 2.12.0 → 2.12.2

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
@@ -371,7 +371,6 @@ ${formatted}`);
371
371
  return formatted;
372
372
  }
373
373
  }
374
- var _standard = /* @__PURE__ */ new WeakMap();
375
374
  var DecoderImpl = class {
376
375
  /**
377
376
  * Verifies the untrusted/unknown input and either accepts or rejects it.
@@ -395,6 +394,10 @@ var DecoderImpl = class {
395
394
  * error message.
396
395
  */
397
396
 
397
+ /**
398
+ * Memoized `~standard` props, built on first access.
399
+ */
400
+ #standard;
398
401
  constructor(fn) {
399
402
  const decode = (blob) => {
400
403
  const makeFlexErr = (msg) => err(isAnnotation(msg) ? msg : public_annotate(blob, msg));
@@ -512,10 +515,8 @@ var DecoderImpl = class {
512
515
  * The Standard Schema interface for this decoder.
513
516
  */
514
517
  get "~standard"() {
515
- const memo = _standard.get(this);
516
- if (memo !== void 0) return memo;
517
518
  const decode = this.decode;
518
- const props = {
519
+ return this.#standard ??= {
519
520
  version: 1,
520
521
  vendor: "decoders",
521
522
  validate: (blob) => {
@@ -528,8 +529,6 @@ var DecoderImpl = class {
528
529
  }
529
530
  }
530
531
  };
531
- _standard.set(this, props);
532
- return props;
533
532
  }
534
533
  };
535
534
  Object.defineProperty(DecoderImpl, "name", { value: "Decoder" });
@@ -671,18 +670,6 @@ function tuple(...decoders) {
671
670
  });
672
671
  }
673
672
 
674
- // src/lib/set-methods.ts
675
- // @__NO_SIDE_EFFECTS__
676
- function difference(xs, ys) {
677
- const result = /* @__PURE__ */ new Set();
678
- for (const x of xs) {
679
- if (!ys.has(x)) {
680
- result.add(x);
681
- }
682
- }
683
- return result;
684
- }
685
-
686
673
  // src/objects.ts
687
674
  // @__NO_SIDE_EFFECTS__
688
675
  function rejectUnsafeKey(decoders) {
@@ -704,13 +691,12 @@ var pojo = define(
704
691
  );
705
692
  // @__NO_SIDE_EFFECTS__
706
693
  function buildObject(decoders) {
707
- const knownKeys = new Set(Object.keys(decoders));
694
+ const knownKeys = Object.keys(decoders);
708
695
  return pojo.chain((plainObj, ok2, err2) => {
709
- const actualKeys = new Set(Object.keys(plainObj));
710
- const missingKeys = difference(knownKeys, actualKeys);
711
696
  const record2 = {};
712
697
  let errors = null;
713
- for (const key of Object.keys(decoders)) {
698
+ let missingKeys = null;
699
+ for (const key of knownKeys) {
714
700
  const decoder = decoders[key];
715
701
  const rawValue = plainObj[key];
716
702
  const result = decoder.decode(rawValue);
@@ -719,25 +705,23 @@ function buildObject(decoders) {
719
705
  if (value !== void 0) {
720
706
  record2[key] = value;
721
707
  }
722
- missingKeys.delete(key);
723
708
  } else {
724
709
  const ann = result.error;
725
710
  if (rawValue === void 0) {
726
- missingKeys.add(key);
711
+ (missingKeys ??= []).push(key);
727
712
  } else {
728
- errors ??= /* @__PURE__ */ new Map();
729
- errors.set(key, ann);
713
+ (errors ??= /* @__PURE__ */ new Map()).set(key, ann);
730
714
  }
731
715
  }
732
716
  }
733
- if (errors || missingKeys.size > 0) {
717
+ if (errors || missingKeys) {
734
718
  let objAnn = public_annotateObject(plainObj);
735
719
  if (errors) {
736
720
  objAnn = merge(objAnn, errors);
737
721
  }
738
- if (missingKeys.size > 0) {
739
- const errMsg = Array.from(missingKeys).map(quote).join(", ");
740
- const pluralized = missingKeys.size > 1 ? "keys" : "key";
722
+ if (missingKeys) {
723
+ const errMsg = missingKeys.map(quote).join(", ");
724
+ const pluralized = missingKeys.length > 1 ? "keys" : "key";
741
725
  objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
742
726
  }
743
727
  return err2(objAnn);
@@ -754,41 +738,50 @@ function object(decoders) {
754
738
  function exact(decoders) {
755
739
  /* @__PURE__ */ rejectUnsafeKey(decoders);
756
740
  const allowedKeys = new Set(Object.keys(decoders));
757
- const checked = pojo.chain((plainObj, ok2, err2) => {
758
- const actualKeys = new Set(Object.keys(plainObj));
759
- if (actualKeys.has("__proto__")) {
760
- return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
741
+ const objDecoder = /* @__PURE__ */ buildObject(decoders);
742
+ return pojo.chain((plainObj, _ok, err2) => {
743
+ let extraKeys = null;
744
+ for (const key of Object.keys(plainObj)) {
745
+ if (key === "__proto__") {
746
+ return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
747
+ }
748
+ if (!allowedKeys.has(key)) {
749
+ (extraKeys ??= []).push(key);
750
+ }
751
+ }
752
+ if (extraKeys) {
753
+ return err2(`Unexpected extra keys: ${extraKeys.map(quote).join(", ")}`);
761
754
  }
762
- const extraKeys = difference(actualKeys, allowedKeys);
763
- return extraKeys.size > 0 ? err2(`Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}`) : ok2(plainObj);
755
+ return objDecoder.decode(plainObj);
764
756
  });
765
- return checked.pipe(/* @__PURE__ */ buildObject(decoders));
766
757
  }
767
758
  // @__NO_SIDE_EFFECTS__
768
759
  function inexact(decoders) {
769
760
  /* @__PURE__ */ rejectUnsafeKey(decoders);
761
+ const safekeys = new Set(Object.keys(decoders));
762
+ const safeDecoder = /* @__PURE__ */ buildObject(decoders);
770
763
  return pojo.chain(
771
- (plainObj, _ok, err2) => {
764
+ (plainObj, ok2, err2) => {
772
765
  const allkeys = new Set(Object.keys(plainObj));
773
766
  if (allkeys.has("__proto__")) {
774
767
  return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
775
768
  }
776
- return (/* @__PURE__ */ buildObject(decoders)).transform((safepart) => {
777
- const safekeys = new Set(Object.keys(decoders));
778
- for (const k of safekeys) allkeys.add(k);
779
- const rv = {};
780
- for (const k of allkeys) {
781
- if (safekeys.has(k)) {
782
- const value = safepart[k];
783
- if (value !== void 0) {
784
- rv[k] = value;
785
- }
786
- } else {
787
- rv[k] = plainObj[k];
769
+ const result = safeDecoder.decode(plainObj);
770
+ if (!result.ok) return result;
771
+ const safepart = result.value;
772
+ for (const k of safekeys) allkeys.add(k);
773
+ const rv = {};
774
+ for (const k of allkeys) {
775
+ if (safekeys.has(k)) {
776
+ const value = safepart[k];
777
+ if (value !== void 0) {
778
+ rv[k] = value;
788
779
  }
780
+ } else {
781
+ rv[k] = plainObj[k];
789
782
  }
790
- return rv;
791
- });
783
+ }
784
+ return ok2(rv);
792
785
  }
793
786
  );
794
787
  }
package/dist/index.js CHANGED
@@ -371,7 +371,6 @@ ${formatted}`);
371
371
  return formatted;
372
372
  }
373
373
  }
374
- var _standard = /* @__PURE__ */ new WeakMap();
375
374
  var DecoderImpl = class {
376
375
  /**
377
376
  * Verifies the untrusted/unknown input and either accepts or rejects it.
@@ -395,6 +394,10 @@ var DecoderImpl = class {
395
394
  * error message.
396
395
  */
397
396
  value;
397
+ /**
398
+ * Memoized `~standard` props, built on first access.
399
+ */
400
+ #standard;
398
401
  constructor(fn) {
399
402
  const decode = (blob) => {
400
403
  const makeFlexErr = (msg) => err(isAnnotation(msg) ? msg : public_annotate(blob, msg));
@@ -512,10 +515,8 @@ var DecoderImpl = class {
512
515
  * The Standard Schema interface for this decoder.
513
516
  */
514
517
  get "~standard"() {
515
- const memo = _standard.get(this);
516
- if (memo !== void 0) return memo;
517
518
  const decode = this.decode;
518
- const props = {
519
+ return this.#standard ??= {
519
520
  version: 1,
520
521
  vendor: "decoders",
521
522
  validate: (blob) => {
@@ -528,8 +529,6 @@ var DecoderImpl = class {
528
529
  }
529
530
  }
530
531
  };
531
- _standard.set(this, props);
532
- return props;
533
532
  }
534
533
  };
535
534
  Object.defineProperty(DecoderImpl, "name", { value: "Decoder" });
@@ -671,18 +670,6 @@ function tuple(...decoders) {
671
670
  });
672
671
  }
673
672
 
674
- // src/lib/set-methods.ts
675
- // @__NO_SIDE_EFFECTS__
676
- function difference(xs, ys) {
677
- const result = /* @__PURE__ */ new Set();
678
- for (const x of xs) {
679
- if (!ys.has(x)) {
680
- result.add(x);
681
- }
682
- }
683
- return result;
684
- }
685
-
686
673
  // src/objects.ts
687
674
  // @__NO_SIDE_EFFECTS__
688
675
  function rejectUnsafeKey(decoders) {
@@ -704,13 +691,12 @@ var pojo = define(
704
691
  );
705
692
  // @__NO_SIDE_EFFECTS__
706
693
  function buildObject(decoders) {
707
- const knownKeys = new Set(Object.keys(decoders));
694
+ const knownKeys = Object.keys(decoders);
708
695
  return pojo.chain((plainObj, ok2, err2) => {
709
- const actualKeys = new Set(Object.keys(plainObj));
710
- const missingKeys = difference(knownKeys, actualKeys);
711
696
  const record2 = {};
712
697
  let errors = null;
713
- for (const key of Object.keys(decoders)) {
698
+ let missingKeys = null;
699
+ for (const key of knownKeys) {
714
700
  const decoder = decoders[key];
715
701
  const rawValue = plainObj[key];
716
702
  const result = decoder.decode(rawValue);
@@ -719,25 +705,23 @@ function buildObject(decoders) {
719
705
  if (value !== void 0) {
720
706
  record2[key] = value;
721
707
  }
722
- missingKeys.delete(key);
723
708
  } else {
724
709
  const ann = result.error;
725
710
  if (rawValue === void 0) {
726
- missingKeys.add(key);
711
+ (missingKeys ??= []).push(key);
727
712
  } else {
728
- errors ??= /* @__PURE__ */ new Map();
729
- errors.set(key, ann);
713
+ (errors ??= /* @__PURE__ */ new Map()).set(key, ann);
730
714
  }
731
715
  }
732
716
  }
733
- if (errors || missingKeys.size > 0) {
717
+ if (errors || missingKeys) {
734
718
  let objAnn = public_annotateObject(plainObj);
735
719
  if (errors) {
736
720
  objAnn = merge(objAnn, errors);
737
721
  }
738
- if (missingKeys.size > 0) {
739
- const errMsg = Array.from(missingKeys).map(quote).join(", ");
740
- const pluralized = missingKeys.size > 1 ? "keys" : "key";
722
+ if (missingKeys) {
723
+ const errMsg = missingKeys.map(quote).join(", ");
724
+ const pluralized = missingKeys.length > 1 ? "keys" : "key";
741
725
  objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
742
726
  }
743
727
  return err2(objAnn);
@@ -754,41 +738,50 @@ function object(decoders) {
754
738
  function exact(decoders) {
755
739
  /* @__PURE__ */ rejectUnsafeKey(decoders);
756
740
  const allowedKeys = new Set(Object.keys(decoders));
757
- const checked = pojo.chain((plainObj, ok2, err2) => {
758
- const actualKeys = new Set(Object.keys(plainObj));
759
- if (actualKeys.has("__proto__")) {
760
- return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
741
+ const objDecoder = /* @__PURE__ */ buildObject(decoders);
742
+ return pojo.chain((plainObj, _ok, err2) => {
743
+ let extraKeys = null;
744
+ for (const key of Object.keys(plainObj)) {
745
+ if (key === "__proto__") {
746
+ return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
747
+ }
748
+ if (!allowedKeys.has(key)) {
749
+ (extraKeys ??= []).push(key);
750
+ }
751
+ }
752
+ if (extraKeys) {
753
+ return err2(`Unexpected extra keys: ${extraKeys.map(quote).join(", ")}`);
761
754
  }
762
- const extraKeys = difference(actualKeys, allowedKeys);
763
- return extraKeys.size > 0 ? err2(`Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}`) : ok2(plainObj);
755
+ return objDecoder.decode(plainObj);
764
756
  });
765
- return checked.pipe(/* @__PURE__ */ buildObject(decoders));
766
757
  }
767
758
  // @__NO_SIDE_EFFECTS__
768
759
  function inexact(decoders) {
769
760
  /* @__PURE__ */ rejectUnsafeKey(decoders);
761
+ const safekeys = new Set(Object.keys(decoders));
762
+ const safeDecoder = /* @__PURE__ */ buildObject(decoders);
770
763
  return pojo.chain(
771
- (plainObj, _ok, err2) => {
764
+ (plainObj, ok2, err2) => {
772
765
  const allkeys = new Set(Object.keys(plainObj));
773
766
  if (allkeys.has("__proto__")) {
774
767
  return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
775
768
  }
776
- return (/* @__PURE__ */ buildObject(decoders)).transform((safepart) => {
777
- const safekeys = new Set(Object.keys(decoders));
778
- for (const k of safekeys) allkeys.add(k);
779
- const rv = {};
780
- for (const k of allkeys) {
781
- if (safekeys.has(k)) {
782
- const value = safepart[k];
783
- if (value !== void 0) {
784
- rv[k] = value;
785
- }
786
- } else {
787
- rv[k] = plainObj[k];
769
+ const result = safeDecoder.decode(plainObj);
770
+ if (!result.ok) return result;
771
+ const safepart = result.value;
772
+ for (const k of safekeys) allkeys.add(k);
773
+ const rv = {};
774
+ for (const k of allkeys) {
775
+ if (safekeys.has(k)) {
776
+ const value = safepart[k];
777
+ if (value !== void 0) {
778
+ rv[k] = value;
788
779
  }
780
+ } else {
781
+ rv[k] = plainObj[k];
789
782
  }
790
- return rv;
791
- });
783
+ }
784
+ return ok2(rv);
792
785
  }
793
786
  );
794
787
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decoders",
3
- "version": "2.12.0",
3
+ "version": "2.12.2",
4
4
  "description": "Elegant and battle-tested validation library for type-safe input data for TypeScript",
5
5
  "license": "MIT",
6
6
  "repository": {