jazz-tools 0.19.2 → 0.19.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.
@@ -1,5 +1,5 @@
1
1
  // src/inspector/register-custom-element.ts
2
2
  if (typeof window !== "undefined" && process.env.NODE_ENV === "development") {
3
- import("./custom-element-ABVPHX53.js");
3
+ import("./custom-element-3JAYHXWQ.js");
4
4
  }
5
5
  //# sourceMappingURL=register-custom-element.js.map
@@ -0,0 +1,3 @@
1
+ import { Role } from "cojson";
2
+ export declare function isWriter(role: Role | undefined): boolean;
3
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/inspector/utils/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,CAOxD"}
@@ -1 +1 @@
1
- {"version":3,"file":"co-map-view.d.ts","sourceRoot":"","sources":["../../../src/inspector/viewer/co-map-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAQnC,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,EAAE;IACD,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;CACzC,2CAeA"}
1
+ {"version":3,"file":"co-map-view.d.ts","sourceRoot":"","sources":["../../../src/inspector/viewer/co-map-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AASnC,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,EAAE;IACD,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;CACzC,2CAmBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"grid-view.d.ts","sourceRoot":"","sources":["../../../src/inspector/viewer/grid-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,UAAU,EAAa,MAAM,QAAQ,CAAC;AAI/C,OAAO,EAAE,QAAQ,EAAU,MAAM,YAAY,CAAC;AAmJ9C,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB,2CAgBA"}
1
+ {"version":3,"file":"grid-view.d.ts","sourceRoot":"","sources":["../../../src/inspector/viewer/grid-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,EAAE,UAAU,EAAa,MAAM,QAAQ,CAAC;AAI/C,OAAO,EAAE,QAAQ,EAAU,MAAM,YAAY,CAAC;AAoJ9C,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACxC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB,2CAgBA"}
package/dist/testing.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createAnonymousJazzContext,
8
8
  createJazzContext,
9
9
  randomSessionProvider
10
- } from "./chunk-NCNM6UDZ.js";
10
+ } from "./chunk-JPWM4CS2.js";
11
11
  import "./chunk-PZ5AY32C.js";
12
12
 
13
13
  // src/tools/testing.ts
@@ -1 +1 @@
1
- {"version":3,"file":"unionUtils.d.ts","sourceRoot":"","sources":["../../../../src/tools/implementation/zodSchema/unionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EAErB,KAAK,EACL,8BAA8B,EAE9B,2BAA2B,EAE3B,wBAAwB,EAEzB,MAAM,mBAAmB,CAAC;AAO3B,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,8BAA8B,CAAC,2BAA2B,CAAC,mCA6HpE;AAsBD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,qBAAqB,WAMtE"}
1
+ {"version":3,"file":"unionUtils.d.ts","sourceRoot":"","sources":["../../../../src/tools/implementation/zodSchema/unionUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EAErB,KAAK,EACL,8BAA8B,EAE9B,2BAA2B,EAE3B,wBAAwB,EAEzB,MAAM,mBAAmB,CAAC;AAO3B,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,8BAA8B,CAAC,2BAA2B,CAAC,mCA4HpE;AAsBD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,qBAAqB,WAMtE"}
package/package.json CHANGED
@@ -187,7 +187,7 @@
187
187
  },
188
188
  "type": "module",
189
189
  "license": "MIT",
190
- "version": "0.19.2",
190
+ "version": "0.19.3",
191
191
  "dependencies": {
192
192
  "@manuscripts/prosemirror-recreate-steps": "^0.1.4",
193
193
  "@scure/base": "1.2.1",
@@ -204,9 +204,9 @@
204
204
  "prosemirror-transform": "^1.9.0",
205
205
  "use-sync-external-store": "^1.5.0",
206
206
  "zod": "4.1.11",
207
- "cojson-storage-indexeddb": "0.19.2",
208
- "cojson-transport-ws": "0.19.2",
209
- "cojson": "0.19.2"
207
+ "cojson": "0.19.3",
208
+ "cojson-storage-indexeddb": "0.19.3",
209
+ "cojson-transport-ws": "0.19.3"
210
210
  },
211
211
  "devDependencies": {
212
212
  "@scure/bip39": "^1.3.0",
@@ -1,5 +1,5 @@
1
1
  // @vitest-environment happy-dom
2
- import { afterEach, beforeAll, describe, expect, it } from "vitest";
2
+ import { afterEach, assert, beforeAll, describe, expect, it } from "vitest";
3
3
  import { createJazzTestAccount, setupJazzTestSync } from "jazz-tools/testing";
4
4
  import { co, z } from "jazz-tools";
5
5
  import {
@@ -578,4 +578,312 @@ describe("CoMapView", async () => {
578
578
  });
579
579
  });
580
580
  });
581
+
582
+ describe("Permissions", () => {
583
+ it("should disable Add Property button for reader account", async () => {
584
+ const reader = await createJazzTestAccount();
585
+ const group = co.group().create({ owner: account });
586
+ group.addMember(reader, "reader");
587
+
588
+ const schema = co.map({
589
+ pet: z.string(),
590
+ });
591
+
592
+ const value = schema.create({ pet: "dog" }, group);
593
+
594
+ const valueOnReader = await schema.load(value.$jazz.id, {
595
+ loadAs: reader,
596
+ });
597
+ assert(valueOnReader.$isLoaded);
598
+ const data = valueOnReader.$jazz.raw.toJSON() as JsonObject;
599
+
600
+ render(
601
+ <CoMapView
602
+ coValue={valueOnReader.$jazz.raw}
603
+ data={data}
604
+ node={reader.$jazz.localNode}
605
+ onNavigate={() => {}}
606
+ />,
607
+ );
608
+
609
+ const addButton = screen.getByTitle("Add Property");
610
+ expect(addButton).toBeDefined();
611
+ expect((addButton as HTMLButtonElement).disabled).toBe(true);
612
+ });
613
+
614
+ it("should enable Add Property button for writer account", async () => {
615
+ const writer = await createJazzTestAccount();
616
+ const group = co.group().create({ owner: account });
617
+ group.addMember(writer, "writer");
618
+
619
+ const schema = co.map({
620
+ pet: z.string(),
621
+ });
622
+
623
+ const value = schema.create({ pet: "dog" }, group);
624
+
625
+ const valueOnWriter = await schema.load(value.$jazz.id, {
626
+ loadAs: writer,
627
+ });
628
+ assert(valueOnWriter.$isLoaded);
629
+ const data = valueOnWriter.$jazz.raw.toJSON() as JsonObject;
630
+
631
+ render(
632
+ <CoMapView
633
+ coValue={valueOnWriter.$jazz.raw}
634
+ data={data}
635
+ node={writer.$jazz.localNode}
636
+ onNavigate={() => {}}
637
+ />,
638
+ );
639
+
640
+ const addButton = screen.getByTitle("Add Property");
641
+ expect(addButton).toBeDefined();
642
+ expect((addButton as HTMLButtonElement).disabled).toBe(false);
643
+ });
644
+
645
+ it("should hide restore buttons for reader account when multiple timestamps exist", async () => {
646
+ const reader = await createJazzTestAccount();
647
+ const group = co.group().create({ owner: account });
648
+ group.addMember(reader, "reader");
649
+
650
+ const schema = co.map({
651
+ pet: z.string(),
652
+ });
653
+
654
+ const value = schema.create({ pet: "dog" }, group);
655
+ await sleep(2);
656
+ value.$jazz.set("pet", "cat");
657
+
658
+ const valueOnReader = await schema.load(value.$jazz.id, {
659
+ loadAs: reader,
660
+ });
661
+ assert(valueOnReader.$isLoaded);
662
+ const data = valueOnReader.$jazz.raw.toJSON() as JsonObject;
663
+
664
+ render(
665
+ <CoMapView
666
+ coValue={valueOnReader.$jazz.raw}
667
+ data={data}
668
+ node={reader.$jazz.localNode}
669
+ onNavigate={() => {}}
670
+ />,
671
+ );
672
+
673
+ const restoreButton = screen.getByTitle("Timeline");
674
+ fireEvent.click(restoreButton);
675
+
676
+ await waitFor(() => {
677
+ expect(screen.getByText("Select Timestamp")).toBeDefined();
678
+ });
679
+
680
+ expect(screen.queryByText("Restore")).toBeNull();
681
+ expect(screen.queryByRole("checkbox")).toBeNull();
682
+ });
683
+
684
+ it("should show restore buttons for writer account when multiple timestamps exist", async () => {
685
+ const writer = await createJazzTestAccount();
686
+ const group = co.group().create({ owner: account });
687
+ group.addMember(writer, "writer");
688
+
689
+ const schema = co.map({
690
+ pet: z.string(),
691
+ });
692
+
693
+ const value = schema.create({ pet: "dog" }, group);
694
+ await sleep(2);
695
+ value.$jazz.set("pet", "cat");
696
+
697
+ const valueOnWriter = await schema.load(value.$jazz.id, {
698
+ loadAs: writer,
699
+ });
700
+ assert(valueOnWriter.$isLoaded);
701
+ const data = valueOnWriter.$jazz.raw.toJSON() as JsonObject;
702
+
703
+ render(
704
+ <CoMapView
705
+ coValue={valueOnWriter.$jazz.raw}
706
+ data={data}
707
+ node={writer.$jazz.localNode}
708
+ onNavigate={() => {}}
709
+ />,
710
+ );
711
+
712
+ const restoreButton = screen.getByTitle("Timeline");
713
+ fireEvent.click(restoreButton);
714
+
715
+ await waitFor(() => {
716
+ expect(screen.getByText("Restore")).toBeDefined();
717
+ });
718
+
719
+ expect(screen.getByRole("checkbox")).toBeDefined();
720
+ });
721
+
722
+ it("should hide edit buttons in GridView for reader account", async () => {
723
+ const reader = await createJazzTestAccount();
724
+ const group = co.group().create({ owner: account });
725
+ group.addMember(reader, "reader");
726
+
727
+ const schema = co.map({
728
+ pet: z.string(),
729
+ age: z.number(),
730
+ });
731
+
732
+ const value = schema.create({ pet: "dog", age: 10 }, group);
733
+
734
+ const valueOnReader = await schema.load(value.$jazz.id, {
735
+ loadAs: reader,
736
+ });
737
+ assert(valueOnReader.$isLoaded);
738
+ const data = valueOnReader.$jazz.raw.toJSON() as JsonObject;
739
+
740
+ render(
741
+ <CoMapView
742
+ coValue={valueOnReader.$jazz.raw}
743
+ data={data}
744
+ node={reader.$jazz.localNode}
745
+ onNavigate={() => {}}
746
+ />,
747
+ );
748
+
749
+ expect(screen.getByText("pet")).toBeDefined();
750
+ expect(screen.getByText("age")).toBeDefined();
751
+
752
+ const editButtons = screen.queryAllByLabelText("Edit");
753
+ const deleteButtons = screen.queryAllByLabelText("Delete");
754
+
755
+ expect(editButtons).toHaveLength(0);
756
+ expect(deleteButtons).toHaveLength(0);
757
+ });
758
+
759
+ it("should show edit buttons in GridView for writer account", async () => {
760
+ const writer = await createJazzTestAccount();
761
+ const group = co.group().create({ owner: account });
762
+ group.addMember(writer, "writer");
763
+
764
+ const schema = co.map({
765
+ pet: z.string(),
766
+ age: z.number(),
767
+ });
768
+
769
+ const value = schema.create({ pet: "dog", age: 10 }, group);
770
+
771
+ const valueOnWriter = await schema.load(value.$jazz.id, {
772
+ loadAs: writer,
773
+ });
774
+ assert(valueOnWriter.$isLoaded);
775
+ const data = valueOnWriter.$jazz.raw.toJSON() as JsonObject;
776
+
777
+ render(
778
+ <CoMapView
779
+ coValue={valueOnWriter.$jazz.raw}
780
+ data={data}
781
+ node={writer.$jazz.localNode}
782
+ onNavigate={() => {}}
783
+ />,
784
+ );
785
+
786
+ expect(screen.getByText("pet")).toBeDefined();
787
+ expect(screen.getByText("age")).toBeDefined();
788
+
789
+ const editButtons = screen.queryAllByLabelText("Edit");
790
+ const deleteButtons = screen.queryAllByLabelText("Delete");
791
+
792
+ expect(editButtons.length).toBeGreaterThan(0);
793
+ expect(deleteButtons.length).toBeGreaterThan(0);
794
+ });
795
+
796
+ it("should enable Add Property button for admin account", async () => {
797
+ const admin = await createJazzTestAccount();
798
+ const group = co.group().create({ owner: account });
799
+ group.addMember(admin, "admin");
800
+
801
+ const schema = co.map({
802
+ pet: z.string(),
803
+ });
804
+
805
+ const value = schema.create({ pet: "dog" }, group);
806
+
807
+ const valueOnAdmin = await schema.load(value.$jazz.id, {
808
+ loadAs: admin,
809
+ });
810
+ assert(valueOnAdmin.$isLoaded);
811
+ const data = valueOnAdmin.$jazz.raw.toJSON() as JsonObject;
812
+
813
+ render(
814
+ <CoMapView
815
+ coValue={valueOnAdmin.$jazz.raw}
816
+ data={data}
817
+ node={admin.$jazz.localNode}
818
+ onNavigate={() => {}}
819
+ />,
820
+ );
821
+
822
+ const addButton = screen.getByTitle("Add Property");
823
+ expect(addButton).toBeDefined();
824
+ expect((addButton as HTMLButtonElement).disabled).toBe(false);
825
+ });
826
+
827
+ it("should enable Add Property button for manager account", async () => {
828
+ const manager = await createJazzTestAccount();
829
+ const group = co.group().create({ owner: account });
830
+ group.addMember(manager, "manager");
831
+
832
+ const schema = co.map({
833
+ pet: z.string(),
834
+ });
835
+
836
+ const value = schema.create({ pet: "dog" }, group);
837
+
838
+ const valueOnManager = await schema.load(value.$jazz.id, {
839
+ loadAs: manager,
840
+ });
841
+ assert(valueOnManager.$isLoaded);
842
+ const data = valueOnManager.$jazz.raw.toJSON() as JsonObject;
843
+
844
+ render(
845
+ <CoMapView
846
+ coValue={valueOnManager.$jazz.raw}
847
+ data={data}
848
+ node={manager.$jazz.localNode}
849
+ onNavigate={() => {}}
850
+ />,
851
+ );
852
+
853
+ const addButton = screen.getByTitle("Add Property");
854
+ expect(addButton).toBeDefined();
855
+ expect((addButton as HTMLButtonElement).disabled).toBe(false);
856
+ });
857
+
858
+ it("should enable Add Property button for writeOnly account", async () => {
859
+ const writeOnly = await createJazzTestAccount();
860
+ const group = co.group().create({ owner: account });
861
+ group.addMember(writeOnly, "writeOnly");
862
+
863
+ const schema = co.map({
864
+ pet: z.string(),
865
+ });
866
+
867
+ const value = schema.create({ pet: "dog" }, group);
868
+
869
+ const valueOnWriteOnly = await schema.load(value.$jazz.id, {
870
+ loadAs: writeOnly,
871
+ });
872
+ assert(valueOnWriteOnly.$isLoaded);
873
+ const data = valueOnWriteOnly.$jazz.raw.toJSON() as JsonObject;
874
+
875
+ render(
876
+ <CoMapView
877
+ coValue={valueOnWriteOnly.$jazz.raw}
878
+ data={data}
879
+ node={writeOnly.$jazz.localNode}
880
+ onNavigate={() => {}}
881
+ />,
882
+ );
883
+
884
+ const addButton = screen.getByTitle("Add Property");
885
+ expect(addButton).toBeDefined();
886
+ expect((addButton as HTMLButtonElement).disabled).toBe(false);
887
+ });
888
+ });
581
889
  });
@@ -0,0 +1,10 @@
1
+ import { Role } from "cojson";
2
+
3
+ export function isWriter(role: Role | undefined): boolean {
4
+ return (
5
+ role === "writer" ||
6
+ role === "admin" ||
7
+ role === "manager" ||
8
+ role === "writeOnly"
9
+ );
10
+ }
@@ -6,6 +6,7 @@ import { Button, Icon, Input, Modal } from "../ui";
6
6
  import { styled } from "goober";
7
7
  import { restoreCoMapToTimestamp } from "../utils/history";
8
8
  import { CoValueEditor } from "./co-value-editor.js";
9
+ import { isWriter } from "../utils/permissions";
9
10
 
10
11
  export function CoMapView({
11
12
  coValue,
@@ -27,7 +28,11 @@ export function CoMapView({
27
28
  coValue={coValue}
28
29
  />
29
30
  <div>
30
- <AddPropertyModal coValue={coValue} node={node} />{" "}
31
+ <AddPropertyModal
32
+ disabled={!isWriter(coValue.group.myRole())}
33
+ coValue={coValue}
34
+ node={node}
35
+ />{" "}
31
36
  <RestoreSnapshotModal coValue={coValue} />
32
37
  </div>
33
38
  </>
@@ -37,9 +42,11 @@ export function CoMapView({
37
42
  function AddPropertyModal({
38
43
  coValue,
39
44
  node,
45
+ disabled,
40
46
  }: {
41
47
  coValue: RawCoMap;
42
48
  node: LocalNode;
49
+ disabled: boolean;
43
50
  }) {
44
51
  const [isAddPropertyModalOpen, setIsAddPropertyModalOpen] = useState(false);
45
52
  const [propertyName, setPropertyName] = useState("");
@@ -59,9 +66,10 @@ function AddPropertyModal({
59
66
  <Button
60
67
  title="Add Property"
61
68
  variant="secondary"
69
+ disabled={disabled}
62
70
  onClick={openAddPropertyModal}
63
71
  >
64
- <Icon name="edit" />
72
+ <Icon name="add" />
65
73
  </Button>
66
74
 
67
75
  <Modal
@@ -132,6 +140,8 @@ function RestoreSnapshotModal({ coValue }: { coValue: RawCoMap }) {
132
140
  setIsRestoreModalOpen(false);
133
141
  };
134
142
 
143
+ const canRestore = isWriter(coValue.group.myRole());
144
+
135
145
  return (
136
146
  <>
137
147
  <Button title="Timeline" variant="secondary" onClick={openRestoreModal}>
@@ -146,7 +156,7 @@ function RestoreSnapshotModal({ coValue }: { coValue: RawCoMap }) {
146
156
  cancelText="Cancel"
147
157
  onConfirm={handleRestore}
148
158
  onCancel={handleClose}
149
- showButtons={timestamps.length > 1}
159
+ showButtons={timestamps.length > 1 && canRestore}
150
160
  >
151
161
  {timestamps.length > 1 && (
152
162
  <>
@@ -167,18 +177,20 @@ function RestoreSnapshotModal({ coValue }: { coValue: RawCoMap }) {
167
177
  </TimestampDisplay>
168
178
  </RangeContainer>
169
179
 
170
- <CheckboxContainer>
171
- <CheckboxInput
172
- type="checkbox"
173
- id="remove-unknown-properties"
174
- checked={removeUnknownProperties}
175
- onChange={(e) => setRemoveUnknownProperties(e.target.checked)}
176
- />
177
- <CheckboxLabel htmlFor="remove-unknown-properties">
178
- Remove unknown properties (properties that don't exist in the
179
- selected snapshot)
180
- </CheckboxLabel>
181
- </CheckboxContainer>
180
+ {canRestore && (
181
+ <CheckboxContainer>
182
+ <CheckboxInput
183
+ type="checkbox"
184
+ id="remove-unknown-properties"
185
+ checked={removeUnknownProperties}
186
+ onChange={(e) => setRemoveUnknownProperties(e.target.checked)}
187
+ />
188
+ <CheckboxLabel htmlFor="remove-unknown-properties">
189
+ Remove unknown properties (properties that don't exist in the
190
+ selected snapshot)
191
+ </CheckboxLabel>
192
+ </CheckboxContainer>
193
+ )}
182
194
  </>
183
195
  )}
184
196
 
@@ -12,6 +12,7 @@ import { Card, CardBody, CardHeader } from "../ui/card.js";
12
12
  import { Grid } from "../ui/grid.js";
13
13
  import { Icon } from "../ui/icon.js";
14
14
  import { Text } from "../ui/text.js";
15
+ import { isWriter } from "../utils/permissions.js";
15
16
 
16
17
  function GridItem({
17
18
  entry,
@@ -115,7 +116,7 @@ function GridItem({
115
116
  <Text strong>{key}</Text>
116
117
  )}
117
118
  </div>
118
- {coValue && (
119
+ {coValue && isWriter(coValue.group.myRole()) && (
119
120
  <ActionButtons>
120
121
  <EditButton
121
122
  onClick={handleEditClick}
@@ -115,7 +115,9 @@ function getTransactionChanges(
115
115
  if (tx.isValid === false && tx.tx.privacy === "private") {
116
116
  const readKey = coValue.core.getReadKey(tx.tx.keyUsed);
117
117
  if (!readKey) {
118
- throw new Error("Read key not found");
118
+ return [
119
+ `Unable to decrypt transaction: read key ${tx.tx.keyUsed} not found.`,
120
+ ];
119
121
  }
120
122
 
121
123
  return (
@@ -108,10 +108,9 @@ export function schemaUnionDiscriminatorFor(
108
108
  const coValueSchema = hydrateCoreCoValueSchema(option as any);
109
109
  const coValueClass = coValueSchema.getCoValueClass() as typeof CoMap;
110
110
 
111
- const dummyFieldNames = allNestedRefKeys
112
- .keys()
113
- .filter((key) => !optionDef.shape[key])
114
- .toArray();
111
+ const dummyFieldNames = Array.from(allNestedRefKeys).filter(
112
+ (key) => !optionDef.shape[key],
113
+ );
115
114
 
116
115
  if (dummyFieldNames.length === 0) {
117
116
  return coValueClass;