decoders 2.12.1 → 2.12.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.
- package/dist/index.cjs +64 -60
- package/dist/index.js +64 -60
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/lib/utils.ts
|
|
2
|
+
var MAX_ERRORS = 3;
|
|
2
3
|
// @__NO_SIDE_EFFECTS__
|
|
3
4
|
function qty(n, unit) {
|
|
4
5
|
return n === 1 ? `${n} ${unit}` : `${n} ${unit}s`;
|
|
@@ -220,8 +221,12 @@ function serializeArray(annotation, prefix) {
|
|
|
220
221
|
return "[]";
|
|
221
222
|
}
|
|
222
223
|
const result = [];
|
|
223
|
-
for (
|
|
224
|
-
const [ser, ann] = serializeAnnotation(
|
|
224
|
+
for (let i = 0; i < items.length; ++i) {
|
|
225
|
+
const [ser, ann] = serializeAnnotation(
|
|
226
|
+
items[i],
|
|
227
|
+
`${prefix}${INDENT}`,
|
|
228
|
+
`(at index ${i})`
|
|
229
|
+
);
|
|
225
230
|
result.push(`${prefix}${INDENT}${ser},`);
|
|
226
231
|
if (ann !== void 0) {
|
|
227
232
|
result.push(indent(ann, `${prefix}${INDENT}`));
|
|
@@ -267,7 +272,7 @@ function serializeValue(value) {
|
|
|
267
272
|
}
|
|
268
273
|
}
|
|
269
274
|
}
|
|
270
|
-
function serializeAnnotation(ann, prefix = "") {
|
|
275
|
+
function serializeAnnotation(ann, prefix = "", location) {
|
|
271
276
|
let serialized;
|
|
272
277
|
if (ann.type === "array") {
|
|
273
278
|
serialized = serializeArray(ann, prefix);
|
|
@@ -283,7 +288,8 @@ function serializeAnnotation(ann, prefix = "") {
|
|
|
283
288
|
const text = ann.text;
|
|
284
289
|
if (text !== void 0) {
|
|
285
290
|
const sep = "^".repeat(isMultiline(serialized) ? 1 : serialized.length);
|
|
286
|
-
|
|
291
|
+
const annotation = isMultiline(text) ? [location ? `${sep} ${location}` : sep, text].join("\n") : [sep, text, location].filter(Boolean).join(" ");
|
|
292
|
+
return [serialized, annotation];
|
|
287
293
|
} else {
|
|
288
294
|
return [serialized, void 0];
|
|
289
295
|
}
|
|
@@ -623,24 +629,25 @@ function array(decoder, options) {
|
|
|
623
629
|
const base = options !== void 0 ? sized(poja, options) : poja;
|
|
624
630
|
return base.chain((inputs, ok2, err2) => {
|
|
625
631
|
const results = [];
|
|
632
|
+
let clone = null;
|
|
633
|
+
let errorCount = 0;
|
|
626
634
|
for (let i = 0; i < inputs.length; ++i) {
|
|
627
635
|
const blob = inputs[i];
|
|
628
636
|
const result = decodeFn(blob);
|
|
629
637
|
if (result.ok) {
|
|
630
|
-
|
|
638
|
+
if (clone === null) {
|
|
639
|
+
results.push(result.value);
|
|
640
|
+
}
|
|
631
641
|
} else {
|
|
632
642
|
results.length = 0;
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
public_annotate(ann, ann.text ? `${ann.text} (at index ${i})` : `index ${i}`)
|
|
639
|
-
);
|
|
640
|
-
return err2(public_annotate(clone));
|
|
643
|
+
clone ??= inputs.slice();
|
|
644
|
+
clone[i] = result.error;
|
|
645
|
+
if (++errorCount >= MAX_ERRORS) {
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
641
648
|
}
|
|
642
649
|
}
|
|
643
|
-
return ok2(results);
|
|
650
|
+
return clone !== null ? err2(public_annotate(clone)) : ok2(results);
|
|
644
651
|
});
|
|
645
652
|
}
|
|
646
653
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -670,18 +677,6 @@ function tuple(...decoders) {
|
|
|
670
677
|
});
|
|
671
678
|
}
|
|
672
679
|
|
|
673
|
-
// src/lib/set-methods.ts
|
|
674
|
-
// @__NO_SIDE_EFFECTS__
|
|
675
|
-
function difference(xs, ys) {
|
|
676
|
-
const result = /* @__PURE__ */ new Set();
|
|
677
|
-
for (const x of xs) {
|
|
678
|
-
if (!ys.has(x)) {
|
|
679
|
-
result.add(x);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
return result;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
680
|
// src/objects.ts
|
|
686
681
|
// @__NO_SIDE_EFFECTS__
|
|
687
682
|
function rejectUnsafeKey(decoders) {
|
|
@@ -703,13 +698,12 @@ var pojo = define(
|
|
|
703
698
|
);
|
|
704
699
|
// @__NO_SIDE_EFFECTS__
|
|
705
700
|
function buildObject(decoders) {
|
|
706
|
-
const knownKeys =
|
|
701
|
+
const knownKeys = Object.keys(decoders);
|
|
707
702
|
return pojo.chain((plainObj, ok2, err2) => {
|
|
708
|
-
const actualKeys = new Set(Object.keys(plainObj));
|
|
709
|
-
const missingKeys = difference(knownKeys, actualKeys);
|
|
710
703
|
const record2 = {};
|
|
711
704
|
let errors = null;
|
|
712
|
-
|
|
705
|
+
let missingKeys = null;
|
|
706
|
+
for (const key of knownKeys) {
|
|
713
707
|
const decoder = decoders[key];
|
|
714
708
|
const rawValue = plainObj[key];
|
|
715
709
|
const result = decoder.decode(rawValue);
|
|
@@ -718,25 +712,23 @@ function buildObject(decoders) {
|
|
|
718
712
|
if (value !== void 0) {
|
|
719
713
|
record2[key] = value;
|
|
720
714
|
}
|
|
721
|
-
missingKeys.delete(key);
|
|
722
715
|
} else {
|
|
723
716
|
const ann = result.error;
|
|
724
717
|
if (rawValue === void 0) {
|
|
725
|
-
missingKeys.
|
|
718
|
+
(missingKeys ??= []).push(key);
|
|
726
719
|
} else {
|
|
727
|
-
errors ??= /* @__PURE__ */ new Map();
|
|
728
|
-
errors.set(key, ann);
|
|
720
|
+
(errors ??= /* @__PURE__ */ new Map()).set(key, ann);
|
|
729
721
|
}
|
|
730
722
|
}
|
|
731
723
|
}
|
|
732
|
-
if (errors || missingKeys
|
|
724
|
+
if (errors || missingKeys) {
|
|
733
725
|
let objAnn = public_annotateObject(plainObj);
|
|
734
726
|
if (errors) {
|
|
735
727
|
objAnn = merge(objAnn, errors);
|
|
736
728
|
}
|
|
737
|
-
if (missingKeys
|
|
738
|
-
const errMsg =
|
|
739
|
-
const pluralized = missingKeys.
|
|
729
|
+
if (missingKeys) {
|
|
730
|
+
const errMsg = missingKeys.map(quote).join(", ");
|
|
731
|
+
const pluralized = missingKeys.length > 1 ? "keys" : "key";
|
|
740
732
|
objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
|
|
741
733
|
}
|
|
742
734
|
return err2(objAnn);
|
|
@@ -753,41 +745,50 @@ function object(decoders) {
|
|
|
753
745
|
function exact(decoders) {
|
|
754
746
|
/* @__PURE__ */ rejectUnsafeKey(decoders);
|
|
755
747
|
const allowedKeys = new Set(Object.keys(decoders));
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
748
|
+
const objDecoder = /* @__PURE__ */ buildObject(decoders);
|
|
749
|
+
return pojo.chain((plainObj, _ok, err2) => {
|
|
750
|
+
let extraKeys = null;
|
|
751
|
+
for (const key of Object.keys(plainObj)) {
|
|
752
|
+
if (key === "__proto__") {
|
|
753
|
+
return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
|
|
754
|
+
}
|
|
755
|
+
if (!allowedKeys.has(key)) {
|
|
756
|
+
(extraKeys ??= []).push(key);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (extraKeys) {
|
|
760
|
+
return err2(`Unexpected extra keys: ${extraKeys.map(quote).join(", ")}`);
|
|
760
761
|
}
|
|
761
|
-
|
|
762
|
-
return extraKeys.size > 0 ? err2(`Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}`) : ok2(plainObj);
|
|
762
|
+
return objDecoder.decode(plainObj);
|
|
763
763
|
});
|
|
764
|
-
return checked.pipe(/* @__PURE__ */ buildObject(decoders));
|
|
765
764
|
}
|
|
766
765
|
// @__NO_SIDE_EFFECTS__
|
|
767
766
|
function inexact(decoders) {
|
|
768
767
|
/* @__PURE__ */ rejectUnsafeKey(decoders);
|
|
768
|
+
const safekeys = new Set(Object.keys(decoders));
|
|
769
|
+
const safeDecoder = /* @__PURE__ */ buildObject(decoders);
|
|
769
770
|
return pojo.chain(
|
|
770
|
-
(plainObj,
|
|
771
|
+
(plainObj, ok2, err2) => {
|
|
771
772
|
const allkeys = new Set(Object.keys(plainObj));
|
|
772
773
|
if (allkeys.has("__proto__")) {
|
|
773
774
|
return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
|
|
774
775
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
} else {
|
|
786
|
-
rv[k] = plainObj[k];
|
|
776
|
+
const result = safeDecoder.decode(plainObj);
|
|
777
|
+
if (!result.ok) return result;
|
|
778
|
+
const safepart = result.value;
|
|
779
|
+
for (const k of safekeys) allkeys.add(k);
|
|
780
|
+
const rv = {};
|
|
781
|
+
for (const k of allkeys) {
|
|
782
|
+
if (safekeys.has(k)) {
|
|
783
|
+
const value = safepart[k];
|
|
784
|
+
if (value !== void 0) {
|
|
785
|
+
rv[k] = value;
|
|
787
786
|
}
|
|
787
|
+
} else {
|
|
788
|
+
rv[k] = plainObj[k];
|
|
788
789
|
}
|
|
789
|
-
|
|
790
|
-
|
|
790
|
+
}
|
|
791
|
+
return ok2(rv);
|
|
791
792
|
}
|
|
792
793
|
);
|
|
793
794
|
}
|
|
@@ -945,6 +946,9 @@ function record(fst, snd) {
|
|
|
945
946
|
errors.set(key, result.error);
|
|
946
947
|
rv = {};
|
|
947
948
|
}
|
|
949
|
+
if (errors.size >= MAX_ERRORS) {
|
|
950
|
+
break;
|
|
951
|
+
}
|
|
948
952
|
}
|
|
949
953
|
if (errors.size > 0) {
|
|
950
954
|
return err2(merge(public_annotateObject(input), errors));
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/lib/utils.ts
|
|
2
|
+
var MAX_ERRORS = 3;
|
|
2
3
|
// @__NO_SIDE_EFFECTS__
|
|
3
4
|
function qty(n, unit) {
|
|
4
5
|
return n === 1 ? `${n} ${unit}` : `${n} ${unit}s`;
|
|
@@ -220,8 +221,12 @@ function serializeArray(annotation, prefix) {
|
|
|
220
221
|
return "[]";
|
|
221
222
|
}
|
|
222
223
|
const result = [];
|
|
223
|
-
for (
|
|
224
|
-
const [ser, ann] = serializeAnnotation(
|
|
224
|
+
for (let i = 0; i < items.length; ++i) {
|
|
225
|
+
const [ser, ann] = serializeAnnotation(
|
|
226
|
+
items[i],
|
|
227
|
+
`${prefix}${INDENT}`,
|
|
228
|
+
`(at index ${i})`
|
|
229
|
+
);
|
|
225
230
|
result.push(`${prefix}${INDENT}${ser},`);
|
|
226
231
|
if (ann !== void 0) {
|
|
227
232
|
result.push(indent(ann, `${prefix}${INDENT}`));
|
|
@@ -267,7 +272,7 @@ function serializeValue(value) {
|
|
|
267
272
|
}
|
|
268
273
|
}
|
|
269
274
|
}
|
|
270
|
-
function serializeAnnotation(ann, prefix = "") {
|
|
275
|
+
function serializeAnnotation(ann, prefix = "", location) {
|
|
271
276
|
let serialized;
|
|
272
277
|
if (ann.type === "array") {
|
|
273
278
|
serialized = serializeArray(ann, prefix);
|
|
@@ -283,7 +288,8 @@ function serializeAnnotation(ann, prefix = "") {
|
|
|
283
288
|
const text = ann.text;
|
|
284
289
|
if (text !== void 0) {
|
|
285
290
|
const sep = "^".repeat(isMultiline(serialized) ? 1 : serialized.length);
|
|
286
|
-
|
|
291
|
+
const annotation = isMultiline(text) ? [location ? `${sep} ${location}` : sep, text].join("\n") : [sep, text, location].filter(Boolean).join(" ");
|
|
292
|
+
return [serialized, annotation];
|
|
287
293
|
} else {
|
|
288
294
|
return [serialized, void 0];
|
|
289
295
|
}
|
|
@@ -623,24 +629,25 @@ function array(decoder, options) {
|
|
|
623
629
|
const base = options !== void 0 ? sized(poja, options) : poja;
|
|
624
630
|
return base.chain((inputs, ok2, err2) => {
|
|
625
631
|
const results = [];
|
|
632
|
+
let clone = null;
|
|
633
|
+
let errorCount = 0;
|
|
626
634
|
for (let i = 0; i < inputs.length; ++i) {
|
|
627
635
|
const blob = inputs[i];
|
|
628
636
|
const result = decodeFn(blob);
|
|
629
637
|
if (result.ok) {
|
|
630
|
-
|
|
638
|
+
if (clone === null) {
|
|
639
|
+
results.push(result.value);
|
|
640
|
+
}
|
|
631
641
|
} else {
|
|
632
642
|
results.length = 0;
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
public_annotate(ann, ann.text ? `${ann.text} (at index ${i})` : `index ${i}`)
|
|
639
|
-
);
|
|
640
|
-
return err2(public_annotate(clone));
|
|
643
|
+
clone ??= inputs.slice();
|
|
644
|
+
clone[i] = result.error;
|
|
645
|
+
if (++errorCount >= MAX_ERRORS) {
|
|
646
|
+
break;
|
|
647
|
+
}
|
|
641
648
|
}
|
|
642
649
|
}
|
|
643
|
-
return ok2(results);
|
|
650
|
+
return clone !== null ? err2(public_annotate(clone)) : ok2(results);
|
|
644
651
|
});
|
|
645
652
|
}
|
|
646
653
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -670,18 +677,6 @@ function tuple(...decoders) {
|
|
|
670
677
|
});
|
|
671
678
|
}
|
|
672
679
|
|
|
673
|
-
// src/lib/set-methods.ts
|
|
674
|
-
// @__NO_SIDE_EFFECTS__
|
|
675
|
-
function difference(xs, ys) {
|
|
676
|
-
const result = /* @__PURE__ */ new Set();
|
|
677
|
-
for (const x of xs) {
|
|
678
|
-
if (!ys.has(x)) {
|
|
679
|
-
result.add(x);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
return result;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
680
|
// src/objects.ts
|
|
686
681
|
// @__NO_SIDE_EFFECTS__
|
|
687
682
|
function rejectUnsafeKey(decoders) {
|
|
@@ -703,13 +698,12 @@ var pojo = define(
|
|
|
703
698
|
);
|
|
704
699
|
// @__NO_SIDE_EFFECTS__
|
|
705
700
|
function buildObject(decoders) {
|
|
706
|
-
const knownKeys =
|
|
701
|
+
const knownKeys = Object.keys(decoders);
|
|
707
702
|
return pojo.chain((plainObj, ok2, err2) => {
|
|
708
|
-
const actualKeys = new Set(Object.keys(plainObj));
|
|
709
|
-
const missingKeys = difference(knownKeys, actualKeys);
|
|
710
703
|
const record2 = {};
|
|
711
704
|
let errors = null;
|
|
712
|
-
|
|
705
|
+
let missingKeys = null;
|
|
706
|
+
for (const key of knownKeys) {
|
|
713
707
|
const decoder = decoders[key];
|
|
714
708
|
const rawValue = plainObj[key];
|
|
715
709
|
const result = decoder.decode(rawValue);
|
|
@@ -718,25 +712,23 @@ function buildObject(decoders) {
|
|
|
718
712
|
if (value !== void 0) {
|
|
719
713
|
record2[key] = value;
|
|
720
714
|
}
|
|
721
|
-
missingKeys.delete(key);
|
|
722
715
|
} else {
|
|
723
716
|
const ann = result.error;
|
|
724
717
|
if (rawValue === void 0) {
|
|
725
|
-
missingKeys.
|
|
718
|
+
(missingKeys ??= []).push(key);
|
|
726
719
|
} else {
|
|
727
|
-
errors ??= /* @__PURE__ */ new Map();
|
|
728
|
-
errors.set(key, ann);
|
|
720
|
+
(errors ??= /* @__PURE__ */ new Map()).set(key, ann);
|
|
729
721
|
}
|
|
730
722
|
}
|
|
731
723
|
}
|
|
732
|
-
if (errors || missingKeys
|
|
724
|
+
if (errors || missingKeys) {
|
|
733
725
|
let objAnn = public_annotateObject(plainObj);
|
|
734
726
|
if (errors) {
|
|
735
727
|
objAnn = merge(objAnn, errors);
|
|
736
728
|
}
|
|
737
|
-
if (missingKeys
|
|
738
|
-
const errMsg =
|
|
739
|
-
const pluralized = missingKeys.
|
|
729
|
+
if (missingKeys) {
|
|
730
|
+
const errMsg = missingKeys.map(quote).join(", ");
|
|
731
|
+
const pluralized = missingKeys.length > 1 ? "keys" : "key";
|
|
740
732
|
objAnn = updateText(objAnn, `Missing ${pluralized}: ${errMsg}`);
|
|
741
733
|
}
|
|
742
734
|
return err2(objAnn);
|
|
@@ -753,41 +745,50 @@ function object(decoders) {
|
|
|
753
745
|
function exact(decoders) {
|
|
754
746
|
/* @__PURE__ */ rejectUnsafeKey(decoders);
|
|
755
747
|
const allowedKeys = new Set(Object.keys(decoders));
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
748
|
+
const objDecoder = /* @__PURE__ */ buildObject(decoders);
|
|
749
|
+
return pojo.chain((plainObj, _ok, err2) => {
|
|
750
|
+
let extraKeys = null;
|
|
751
|
+
for (const key of Object.keys(plainObj)) {
|
|
752
|
+
if (key === "__proto__") {
|
|
753
|
+
return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
|
|
754
|
+
}
|
|
755
|
+
if (!allowedKeys.has(key)) {
|
|
756
|
+
(extraKeys ??= []).push(key);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (extraKeys) {
|
|
760
|
+
return err2(`Unexpected extra keys: ${extraKeys.map(quote).join(", ")}`);
|
|
760
761
|
}
|
|
761
|
-
|
|
762
|
-
return extraKeys.size > 0 ? err2(`Unexpected extra keys: ${Array.from(extraKeys).map(quote).join(", ")}`) : ok2(plainObj);
|
|
762
|
+
return objDecoder.decode(plainObj);
|
|
763
763
|
});
|
|
764
|
-
return checked.pipe(/* @__PURE__ */ buildObject(decoders));
|
|
765
764
|
}
|
|
766
765
|
// @__NO_SIDE_EFFECTS__
|
|
767
766
|
function inexact(decoders) {
|
|
768
767
|
/* @__PURE__ */ rejectUnsafeKey(decoders);
|
|
768
|
+
const safekeys = new Set(Object.keys(decoders));
|
|
769
|
+
const safeDecoder = /* @__PURE__ */ buildObject(decoders);
|
|
769
770
|
return pojo.chain(
|
|
770
|
-
(plainObj,
|
|
771
|
+
(plainObj, ok2, err2) => {
|
|
771
772
|
const allkeys = new Set(Object.keys(plainObj));
|
|
772
773
|
if (allkeys.has("__proto__")) {
|
|
773
774
|
return err2(/* @__PURE__ */ annotateUnsafeKey(plainObj));
|
|
774
775
|
}
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
} else {
|
|
786
|
-
rv[k] = plainObj[k];
|
|
776
|
+
const result = safeDecoder.decode(plainObj);
|
|
777
|
+
if (!result.ok) return result;
|
|
778
|
+
const safepart = result.value;
|
|
779
|
+
for (const k of safekeys) allkeys.add(k);
|
|
780
|
+
const rv = {};
|
|
781
|
+
for (const k of allkeys) {
|
|
782
|
+
if (safekeys.has(k)) {
|
|
783
|
+
const value = safepart[k];
|
|
784
|
+
if (value !== void 0) {
|
|
785
|
+
rv[k] = value;
|
|
787
786
|
}
|
|
787
|
+
} else {
|
|
788
|
+
rv[k] = plainObj[k];
|
|
788
789
|
}
|
|
789
|
-
|
|
790
|
-
|
|
790
|
+
}
|
|
791
|
+
return ok2(rv);
|
|
791
792
|
}
|
|
792
793
|
);
|
|
793
794
|
}
|
|
@@ -945,6 +946,9 @@ function record(fst, snd) {
|
|
|
945
946
|
errors.set(key, result.error);
|
|
946
947
|
rv = {};
|
|
947
948
|
}
|
|
949
|
+
if (errors.size >= MAX_ERRORS) {
|
|
950
|
+
break;
|
|
951
|
+
}
|
|
948
952
|
}
|
|
949
953
|
if (errors.size > 0) {
|
|
950
954
|
return err2(merge(public_annotateObject(input), errors));
|