jazz-tools 0.18.18 → 0.18.20
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/.turbo/turbo-build.log +45 -45
- package/CHANGELOG.md +27 -0
- package/dist/better-auth/auth/client.d.ts.map +1 -1
- package/dist/better-auth/auth/client.js +3 -2
- package/dist/better-auth/auth/client.js.map +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/{chunk-FHRKDKDY.js → chunk-TVHI2UMO.js} +49 -2
- package/dist/chunk-TVHI2UMO.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/react-core/hooks.d.ts.map +1 -1
- package/dist/react-core/index.js +2 -2
- package/dist/react-core/index.js.map +1 -1
- package/dist/testing.js +1 -1
- package/dist/tools/coValues/coList.d.ts.map +1 -1
- package/dist/tools/coValues/coMap.d.ts +2 -2
- package/dist/tools/coValues/coMap.d.ts.map +1 -1
- package/dist/tools/coValues/coPlainText.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts +1 -1
- package/dist/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts +1 -1
- package/dist/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.d.ts.map +1 -1
- package/dist/tools/implementation/zodSchema/zodReExport.d.ts +1 -1
- package/dist/tools/implementation/zodSchema/zodReExport.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/better-auth/auth/client.ts +3 -2
- package/src/better-auth/auth/tests/client.test.ts +22 -0
- package/src/browser/auth/PasskeyAuth.ts +2 -2
- package/src/react-core/hooks.ts +3 -2
- package/src/react-core/tests/useInboxSender.test.ts +37 -3
- package/src/tools/coValues/coList.ts +11 -0
- package/src/tools/coValues/coMap.ts +5 -5
- package/src/tools/coValues/coPlainText.ts +9 -0
- package/src/tools/implementation/zodSchema/runtimeConverters/schemaFieldToCoFieldDef.ts +47 -2
- package/src/tools/implementation/zodSchema/typeConverters/TypeOfZodSchema.ts +9 -4
- package/src/tools/implementation/zodSchema/zodReExport.ts +1 -0
- package/src/tools/subscribe/index.ts +1 -1
- package/src/tools/tests/coList.test.ts +34 -0
- package/src/tools/tests/coMap.test.ts +26 -2
- package/src/tools/tests/coPlainText.test.ts +25 -1
- package/src/tools/tests/subscribe.test.ts +41 -0
- package/src/tools/tests/zod.test.ts +131 -0
- package/dist/chunk-FHRKDKDY.js.map +0 -1
- package/jazz-tools-0.18.6.tgz +0 -0
@@ -739,9 +739,20 @@ export class CoListJazzApi<L extends CoList> extends CoValueJazzApi<L> {
|
|
739
739
|
: undefined;
|
740
740
|
|
741
741
|
const patches = [...calcPatch(current, result, comparator)];
|
742
|
+
|
743
|
+
if (patches.length === 0) {
|
744
|
+
return this.coList;
|
745
|
+
}
|
746
|
+
|
747
|
+
// Turns off updates in the middle of applyDiff to improve the performance
|
748
|
+
this.raw.core.pauseNotifyUpdate();
|
749
|
+
|
742
750
|
for (const [from, to, insert] of patches.reverse()) {
|
743
751
|
this.splice(from, to - from, ...insert);
|
744
752
|
}
|
753
|
+
|
754
|
+
this.raw.core.resumeNotifyUpdate();
|
755
|
+
|
745
756
|
return this.coList;
|
746
757
|
}
|
747
758
|
|
@@ -34,6 +34,7 @@ import {
|
|
34
34
|
CoValueBase,
|
35
35
|
CoValueJazzApi,
|
36
36
|
ItemsSym,
|
37
|
+
NotNull,
|
37
38
|
Ref,
|
38
39
|
RegisteredSchemas,
|
39
40
|
SchemaInit,
|
@@ -760,11 +761,10 @@ class CoMapJazzApi<M extends CoMap> extends CoValueJazzApi<M> {
|
|
760
761
|
? Key
|
761
762
|
: never]?: RefIfCoValue<M[Key]>;
|
762
763
|
} & {
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
: never]: RefIfCoValue<M[Key]>;
|
764
|
+
// Non-loaded CoValue refs (i.e. refs with type CoValue | null) are still required refs
|
765
|
+
[Key in CoKeys<M> as NotNull<M[Key]> extends CoValue
|
766
|
+
? Key
|
767
|
+
: never]: RefIfCoValue<M[Key]>;
|
768
768
|
}
|
769
769
|
> {
|
770
770
|
return makeRefs<CoKeys<this>>(
|
@@ -246,6 +246,13 @@ export class CoTextJazzApi<T extends CoPlainText> extends CoValueJazzApi<T> {
|
|
246
246
|
// Calculate the diff on grapheme arrays
|
247
247
|
const patches = [...calcPatch(currentGraphemes, otherGraphemes)];
|
248
248
|
|
249
|
+
if (patches.length === 0) {
|
250
|
+
return;
|
251
|
+
}
|
252
|
+
|
253
|
+
// Turns off updates in the middle of applyDiff to improve the performance
|
254
|
+
this.raw.core.pauseNotifyUpdate();
|
255
|
+
|
249
256
|
// Apply patches in reverse order to avoid index shifting issues
|
250
257
|
for (const [from, to, insert] of patches.reverse()) {
|
251
258
|
if (to > from) {
|
@@ -256,6 +263,8 @@ export class CoTextJazzApi<T extends CoPlainText> extends CoValueJazzApi<T> {
|
|
256
263
|
this.coText.insertBefore(from, this.raw.fromGraphemes(insert));
|
257
264
|
}
|
258
265
|
}
|
266
|
+
|
267
|
+
this.raw.core.resumeNotifyUpdate();
|
259
268
|
}
|
260
269
|
|
261
270
|
/**
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import type { JsonValue } from "cojson";
|
1
2
|
import { CoValueClass, isCoValueClass } from "../../../internal.js";
|
2
3
|
import { coField } from "../../schema.js";
|
3
4
|
import { CoreCoValueSchema } from "../schemaTypes/CoValueSchema.js";
|
@@ -32,11 +33,31 @@ export type SchemaField =
|
|
32
33
|
| z.core.$ZodLazy<z.core.$ZodType>
|
33
34
|
| z.core.$ZodTemplateLiteral<any>
|
34
35
|
| z.core.$ZodLiteral<any>
|
35
|
-
| z.core.$ZodCatch<z.core.$ZodType>
|
36
36
|
| z.core.$ZodEnum<any>
|
37
|
+
| z.core.$ZodCodec<z.core.$ZodType, z.core.$ZodType>
|
37
38
|
| z.core.$ZodDefault<z.core.$ZodType>
|
38
39
|
| z.core.$ZodCatch<z.core.$ZodType>;
|
39
40
|
|
41
|
+
function makeCodecCoField(
|
42
|
+
codec: z.core.$ZodCodec<z.core.$ZodType, z.core.$ZodType>,
|
43
|
+
) {
|
44
|
+
return coField.optional.encoded({
|
45
|
+
encode: (value: any) => {
|
46
|
+
if (value === undefined) return undefined as unknown as JsonValue;
|
47
|
+
if (value === null) return null;
|
48
|
+
return codec._zod.def.reverseTransform(value, {
|
49
|
+
value,
|
50
|
+
issues: [],
|
51
|
+
}) as JsonValue;
|
52
|
+
},
|
53
|
+
decode: (value) => {
|
54
|
+
if (value === null) return null;
|
55
|
+
if (value === undefined) return undefined;
|
56
|
+
return codec._zod.def.transform(value, { value, issues: [] });
|
57
|
+
},
|
58
|
+
});
|
59
|
+
}
|
60
|
+
|
40
61
|
export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
41
62
|
if (isCoValueClass(schema)) {
|
42
63
|
return coField.ref(schema);
|
@@ -54,7 +75,7 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
54
75
|
zodSchemaDef.type === "optional" ||
|
55
76
|
zodSchemaDef.type === "nullable"
|
56
77
|
) {
|
57
|
-
const inner = zodSchemaDef.innerType as
|
78
|
+
const inner = zodSchemaDef.innerType as SchemaField;
|
58
79
|
const coFieldDef: any = schemaFieldToCoFieldDef(inner);
|
59
80
|
if (
|
60
81
|
zodSchemaDef.type === "nullable" &&
|
@@ -137,6 +158,30 @@ export function schemaFieldToCoFieldDef(schema: SchemaField) {
|
|
137
158
|
"z.union()/z.discriminatedUnion() of collaborative types is not supported. Use co.discriminatedUnion() instead.",
|
138
159
|
);
|
139
160
|
}
|
161
|
+
} else if (zodSchemaDef.type === "pipe") {
|
162
|
+
const isCodec =
|
163
|
+
zodSchemaDef.transform !== undefined &&
|
164
|
+
zodSchemaDef.reverseTransform !== undefined;
|
165
|
+
|
166
|
+
if (!isCodec) {
|
167
|
+
throw new Error(
|
168
|
+
"z.pipe() is not supported. Only z.codec() is supported.",
|
169
|
+
);
|
170
|
+
}
|
171
|
+
|
172
|
+
try {
|
173
|
+
schemaFieldToCoFieldDef(zodSchemaDef.in as SchemaField);
|
174
|
+
} catch (error) {
|
175
|
+
if (error instanceof Error) {
|
176
|
+
error.message = `z.codec() is only supported if the input schema is already supported. ${error.message}`;
|
177
|
+
}
|
178
|
+
|
179
|
+
throw error;
|
180
|
+
}
|
181
|
+
|
182
|
+
return makeCodecCoField(
|
183
|
+
schema as z.core.$ZodCodec<z.core.$ZodType, z.core.$ZodType>,
|
184
|
+
);
|
140
185
|
} else {
|
141
186
|
throw new Error(
|
142
187
|
`Unsupported zod type: ${(schema._zod?.def as any)?.type || JSON.stringify(schema)}`,
|
@@ -71,8 +71,13 @@ export type TypeOfZodSchema<S extends z.core.$ZodType> =
|
|
71
71
|
infer Default extends z.core.$ZodType
|
72
72
|
>
|
73
73
|
? TypeOfZodSchema<Default>
|
74
|
-
: S extends z.core.$
|
75
|
-
|
74
|
+
: S extends z.core.$ZodCodec<
|
75
|
+
any,
|
76
|
+
infer Out extends z.core.$ZodType
|
76
77
|
>
|
77
|
-
?
|
78
|
-
:
|
78
|
+
? Out["_zod"]["output"]
|
79
|
+
: S extends z.core.$ZodCatch<
|
80
|
+
infer Catch extends z.core.$ZodType
|
81
|
+
>
|
82
|
+
? TypeOfZodSchema<Catch>
|
83
|
+
: never;
|
@@ -18,7 +18,7 @@ export function getSubscriptionScope<D extends CoValue>(value: D) {
|
|
18
18
|
});
|
19
19
|
|
20
20
|
Object.defineProperty(value.$jazz, "_subscriptionScope", {
|
21
|
-
value:
|
21
|
+
value: newSubscriptionScope,
|
22
22
|
writable: false,
|
23
23
|
enumerable: false,
|
24
24
|
configurable: false,
|
@@ -680,6 +680,40 @@ describe("CoList applyDiff operations", async () => {
|
|
680
680
|
list.$jazz.applyDiff(["e", "c", "new", "y", "x"]);
|
681
681
|
expect(list.$jazz.raw.asArray()).toEqual(["e", "c", "new", "y", "x"]);
|
682
682
|
});
|
683
|
+
|
684
|
+
test("applyDiff should emit a single update", () => {
|
685
|
+
const TestMap = co.map({
|
686
|
+
type: z.string(),
|
687
|
+
});
|
688
|
+
|
689
|
+
const TestList = co.list(TestMap);
|
690
|
+
|
691
|
+
const bread = TestMap.create({ type: "bread" }, me);
|
692
|
+
const butter = TestMap.create({ type: "butter" }, me);
|
693
|
+
const onion = TestMap.create({ type: "onion" }, me);
|
694
|
+
|
695
|
+
const list = TestList.create([bread, butter, onion], me);
|
696
|
+
|
697
|
+
const updateFn = vi.fn();
|
698
|
+
|
699
|
+
const unsubscribe = TestList.subscribe(
|
700
|
+
list.$jazz.id,
|
701
|
+
{
|
702
|
+
resolve: {
|
703
|
+
$each: true,
|
704
|
+
},
|
705
|
+
},
|
706
|
+
updateFn,
|
707
|
+
);
|
708
|
+
|
709
|
+
updateFn.mockClear();
|
710
|
+
|
711
|
+
list.$jazz.applyDiff([bread]);
|
712
|
+
|
713
|
+
expect(updateFn).toHaveBeenCalledTimes(1);
|
714
|
+
|
715
|
+
unsubscribe();
|
716
|
+
});
|
683
717
|
});
|
684
718
|
|
685
719
|
describe("CoList resolution", async () => {
|
@@ -1150,6 +1150,30 @@ describe("CoMap resolution", async () => {
|
|
1150
1150
|
});
|
1151
1151
|
});
|
1152
1152
|
|
1153
|
+
test("obtaining coMap refs", async () => {
|
1154
|
+
const Dog = co.map({
|
1155
|
+
name: z.string().optional(),
|
1156
|
+
breed: z.string(),
|
1157
|
+
owner: co.plainText(),
|
1158
|
+
get parent() {
|
1159
|
+
return co.optional(Dog);
|
1160
|
+
},
|
1161
|
+
});
|
1162
|
+
|
1163
|
+
const dog = Dog.create({
|
1164
|
+
name: "Rex",
|
1165
|
+
breed: "Labrador",
|
1166
|
+
owner: "John",
|
1167
|
+
parent: { name: "Fido", breed: "Labrador", owner: "Jane" },
|
1168
|
+
});
|
1169
|
+
|
1170
|
+
const refs = dog.$jazz.refs;
|
1171
|
+
|
1172
|
+
expect(Object.keys(refs)).toEqual(["owner", "parent"]);
|
1173
|
+
expect(refs.owner.id).toEqual(dog.owner.$jazz.id);
|
1174
|
+
expect(refs.parent?.id).toEqual(dog.parent!.$jazz.id);
|
1175
|
+
});
|
1176
|
+
|
1153
1177
|
test("accessing the value refs", async () => {
|
1154
1178
|
const Dog = co.map({
|
1155
1179
|
name: z.string(),
|
@@ -1181,9 +1205,9 @@ describe("CoMap resolution", async () => {
|
|
1181
1205
|
|
1182
1206
|
assert(loadedPerson);
|
1183
1207
|
|
1184
|
-
expect(loadedPerson.$jazz.refs.dog
|
1208
|
+
expect(loadedPerson.$jazz.refs.dog.id).toBe(person.dog.$jazz.id);
|
1185
1209
|
|
1186
|
-
const dog = await loadedPerson.$jazz.refs.dog
|
1210
|
+
const dog = await loadedPerson.$jazz.refs.dog.load();
|
1187
1211
|
|
1188
1212
|
assert(dog);
|
1189
1213
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { WasmCrypto } from "cojson/crypto/WasmCrypto";
|
2
2
|
import { Channel } from "queueueue";
|
3
|
-
import { describe, expect, test } from "vitest";
|
3
|
+
import { describe, expect, test, vi } from "vitest";
|
4
4
|
import {
|
5
5
|
Account,
|
6
6
|
cojsonInternals,
|
@@ -94,6 +94,30 @@ describe("CoPlainText", () => {
|
|
94
94
|
text.$jazz.applyDiff(`😊👋 안녕!`);
|
95
95
|
expect(text.toString()).toEqual(`😊👋 안녕!`);
|
96
96
|
});
|
97
|
+
|
98
|
+
test("applyDiff should emit a single update", () => {
|
99
|
+
const Text = co.plainText();
|
100
|
+
|
101
|
+
const text = Text.create(`😊`, { owner: me });
|
102
|
+
|
103
|
+
const updateFn = vi.fn();
|
104
|
+
|
105
|
+
const unsubscribe = Text.subscribe(
|
106
|
+
text.$jazz.id,
|
107
|
+
{
|
108
|
+
loadAs: me,
|
109
|
+
},
|
110
|
+
updateFn,
|
111
|
+
);
|
112
|
+
|
113
|
+
updateFn.mockClear();
|
114
|
+
|
115
|
+
text.$jazz.applyDiff(`😊👋 안녕!`);
|
116
|
+
|
117
|
+
expect(updateFn).toHaveBeenCalledTimes(1);
|
118
|
+
|
119
|
+
unsubscribe();
|
120
|
+
});
|
97
121
|
});
|
98
122
|
|
99
123
|
describe("Properties", () => {
|
@@ -20,6 +20,7 @@ import {
|
|
20
20
|
setupJazzTestSync,
|
21
21
|
} from "../testing.js";
|
22
22
|
import { setupAccount, waitFor } from "./utils.js";
|
23
|
+
import { getSubscriptionScope } from "../subscribe/index.js";
|
23
24
|
|
24
25
|
cojsonInternals.setCoValueLoadingRetryDelay(300);
|
25
26
|
|
@@ -1278,3 +1279,43 @@ describe("subscribeToCoValue", () => {
|
|
1278
1279
|
expect(result.data[chunks]).toBe("new entry");
|
1279
1280
|
});
|
1280
1281
|
});
|
1282
|
+
|
1283
|
+
describe("getSubscriptionScope", () => {
|
1284
|
+
const Person = co.map({
|
1285
|
+
name: z.string(),
|
1286
|
+
});
|
1287
|
+
let person: co.output<typeof Person>;
|
1288
|
+
|
1289
|
+
beforeEach(async () => {
|
1290
|
+
await createJazzTestAccount({
|
1291
|
+
isCurrentActiveAccount: true,
|
1292
|
+
creationProps: { name: "Hermes Puggington" },
|
1293
|
+
});
|
1294
|
+
|
1295
|
+
person = Person.create({ name: "John" });
|
1296
|
+
});
|
1297
|
+
|
1298
|
+
describe("when the coValue doesn't have a subscription scope", () => {
|
1299
|
+
it("creates a new subscription scope", () => {
|
1300
|
+
expect(person.$jazz._subscriptionScope).toBeUndefined();
|
1301
|
+
const subscriptionScope = getSubscriptionScope(person);
|
1302
|
+
expect(subscriptionScope).toBeDefined();
|
1303
|
+
});
|
1304
|
+
|
1305
|
+
it("updates the subscription scope in the coValue", () => {
|
1306
|
+
const subscriptionScope = getSubscriptionScope(person);
|
1307
|
+
expect(person.$jazz._subscriptionScope).toBeDefined();
|
1308
|
+
expect(person.$jazz._subscriptionScope).toBe(subscriptionScope);
|
1309
|
+
});
|
1310
|
+
});
|
1311
|
+
|
1312
|
+
describe("when the coValue already has a subscription scope", () => {
|
1313
|
+
it("returns that subscription scope", async () => {
|
1314
|
+
const loadedPerson = await Person.load(person.$jazz.id);
|
1315
|
+
assert(loadedPerson);
|
1316
|
+
const subscriptionScope = loadedPerson.$jazz._subscriptionScope;
|
1317
|
+
expect(subscriptionScope).toBeDefined();
|
1318
|
+
expect(getSubscriptionScope(loadedPerson)).toBe(subscriptionScope);
|
1319
|
+
});
|
1320
|
+
});
|
1321
|
+
});
|
@@ -511,6 +511,137 @@ describe("co.map and Zod schema compatibility", () => {
|
|
511
511
|
expect(map.readonly).toEqual({ name: "John" });
|
512
512
|
});
|
513
513
|
});
|
514
|
+
|
515
|
+
describe("Codec types", () => {
|
516
|
+
class DateRange {
|
517
|
+
constructor(
|
518
|
+
public start: Date,
|
519
|
+
public end: Date,
|
520
|
+
) {}
|
521
|
+
|
522
|
+
isDateInRange(date: Date) {
|
523
|
+
return date >= this.start && date <= this.end;
|
524
|
+
}
|
525
|
+
}
|
526
|
+
|
527
|
+
const dateRangeCodec = z.codec(
|
528
|
+
z.tuple([z.string(), z.string()]),
|
529
|
+
z.z.instanceof(DateRange),
|
530
|
+
{
|
531
|
+
encode: (value) =>
|
532
|
+
[value.start.toISOString(), value.end.toISOString()] as [
|
533
|
+
string,
|
534
|
+
string,
|
535
|
+
],
|
536
|
+
decode: ([start, end]) => {
|
537
|
+
return new DateRange(new Date(start), new Date(end));
|
538
|
+
},
|
539
|
+
},
|
540
|
+
);
|
541
|
+
|
542
|
+
it("should handle codec field", async () => {
|
543
|
+
const schema = co.map({
|
544
|
+
range: dateRangeCodec,
|
545
|
+
});
|
546
|
+
|
547
|
+
const map = schema.create({
|
548
|
+
range: new DateRange(new Date("2025-01-01"), new Date("2025-01-31")),
|
549
|
+
});
|
550
|
+
|
551
|
+
expect(map.range.isDateInRange(new Date("2025-01-15"))).toEqual(true);
|
552
|
+
});
|
553
|
+
|
554
|
+
it("should handle codec field with RegExp", async () => {
|
555
|
+
const schema = co.map({
|
556
|
+
regexp: z.codec(z.string(), z.z.instanceof(RegExp), {
|
557
|
+
encode: (value) => value.toString(),
|
558
|
+
decode: (value) => {
|
559
|
+
const [, pattern, flags] = value.match(/^\/(.*)\/([a-z]*)$/i)!;
|
560
|
+
if (!pattern) throw new Error("Invalid RegExp string");
|
561
|
+
return new RegExp(pattern, flags);
|
562
|
+
},
|
563
|
+
}),
|
564
|
+
});
|
565
|
+
|
566
|
+
const map = schema.create({
|
567
|
+
regexp: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
|
568
|
+
});
|
569
|
+
|
570
|
+
expect(map.regexp.test("2001-01-31")).toEqual(true);
|
571
|
+
});
|
572
|
+
|
573
|
+
it("should handle optional codec field", async () => {
|
574
|
+
const schema = co.map({
|
575
|
+
range: dateRangeCodec.optional(),
|
576
|
+
});
|
577
|
+
const map = schema.create({});
|
578
|
+
|
579
|
+
expect(map.range).toBeUndefined();
|
580
|
+
expect(map.$jazz.has("range")).toEqual(false);
|
581
|
+
});
|
582
|
+
|
583
|
+
it("should handle nullable codec field", async () => {
|
584
|
+
const schema = co.map({
|
585
|
+
range: dateRangeCodec.nullable(),
|
586
|
+
});
|
587
|
+
const map = schema.create({ range: null });
|
588
|
+
|
589
|
+
expect(map.range).toBeNull();
|
590
|
+
|
591
|
+
map.$jazz.set(
|
592
|
+
"range",
|
593
|
+
new DateRange(new Date("2025-01-01"), new Date("2025-01-31")),
|
594
|
+
);
|
595
|
+
expect(map.range?.isDateInRange(new Date("2025-01-15"))).toEqual(true);
|
596
|
+
});
|
597
|
+
|
598
|
+
it("should handle nullish codec field", async () => {
|
599
|
+
const schema = co.map({
|
600
|
+
range: dateRangeCodec.nullish(),
|
601
|
+
});
|
602
|
+
|
603
|
+
const map = schema.create({});
|
604
|
+
expect(map.range).toBeUndefined();
|
605
|
+
expect(map.$jazz.has("range")).toEqual(false);
|
606
|
+
|
607
|
+
map.$jazz.set("range", undefined);
|
608
|
+
expect(map.range).toBeUndefined();
|
609
|
+
expect(map.$jazz.has("range")).toEqual(true);
|
610
|
+
|
611
|
+
map.$jazz.set("range", null);
|
612
|
+
expect(map.range).toBeNull();
|
613
|
+
|
614
|
+
map.$jazz.set(
|
615
|
+
"range",
|
616
|
+
new DateRange(new Date("2025-01-01"), new Date("2025-01-31")),
|
617
|
+
);
|
618
|
+
expect(map.range?.isDateInRange(new Date("2025-01-15"))).toEqual(true);
|
619
|
+
});
|
620
|
+
|
621
|
+
it("should not handle codec field with unsupported inner field", async () => {
|
622
|
+
const schema = co.map({
|
623
|
+
record: z.codec(
|
624
|
+
z.z.map(z.string(), z.string()),
|
625
|
+
z.z.record(z.string(), z.string()),
|
626
|
+
{
|
627
|
+
encode: (value) => new Map(Object.entries(value)),
|
628
|
+
decode: (value) => Object.fromEntries(value.entries()),
|
629
|
+
},
|
630
|
+
),
|
631
|
+
});
|
632
|
+
|
633
|
+
expect(() =>
|
634
|
+
schema.create({
|
635
|
+
record: {
|
636
|
+
key1: "value1",
|
637
|
+
key2: "value2",
|
638
|
+
},
|
639
|
+
}),
|
640
|
+
).toThrow(
|
641
|
+
"z.codec() is only supported if the input schema is already supported. Unsupported zod type: map",
|
642
|
+
);
|
643
|
+
});
|
644
|
+
});
|
514
645
|
});
|
515
646
|
|
516
647
|
describe("z.object() and CoValue schema compatibility", () => {
|