Skip to content

Commit 4d8ad3c

Browse files
committed
added zod
1 parent 1919a33 commit 4d8ad3c

3 files changed

Lines changed: 100 additions & 2 deletions

File tree

package-lock.json

Lines changed: 15 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"obsidian-daily-notes-interface": "^0.9.4",
6666
"react": "^17.0.2",
6767
"react-dom": "^17.0.2",
68-
"rrule": "^2.7.2"
68+
"rrule": "^2.7.2",
69+
"zod": "^3.21.4"
6970
}
7071
}

src/types/schema.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { z, ZodError } from "zod";
2+
import { DateTime, Duration } from "luxon";
3+
4+
const parsedDate = () =>
5+
z.string().transform((val) => DateTime.fromFormat(val, "yyyy-MM-dd"));
6+
const parsedTime = () =>
7+
z.string().transform((val, ctx) => {
8+
let parsed = DateTime.fromFormat(val, "h:mm a");
9+
if (parsed.invalidReason) {
10+
parsed = DateTime.fromFormat(val, "HH:mm");
11+
}
12+
13+
if (parsed.invalidReason) {
14+
ctx.addIssue({
15+
code: z.ZodIssueCode.custom,
16+
message: parsed.invalidReason,
17+
});
18+
return z.NEVER;
19+
}
20+
21+
return Duration.fromISOTime(
22+
parsed.toISOTime({
23+
includeOffset: false,
24+
includePrefix: false,
25+
})
26+
);
27+
});
28+
29+
const TimeSchema = z.discriminatedUnion("allDay", [
30+
z.object({ allDay: z.literal(true) }),
31+
z.object({
32+
allDay: z.literal(false).optional(),
33+
startTime: parsedTime(),
34+
endTime: parsedTime(),
35+
}),
36+
]);
37+
38+
const CommonSchema = z.object({ title: z.string(), id: z.string().optional() });
39+
40+
const EventSchema = z.discriminatedUnion("type", [
41+
z
42+
.object({
43+
type: z.literal("single").default("single"),
44+
date: parsedDate(),
45+
endDate: parsedDate().optional(),
46+
completed: z.date().or(z.literal(false)).or(z.literal(null)),
47+
})
48+
.merge(CommonSchema),
49+
z
50+
.object({
51+
type: z.literal("recurring"),
52+
daysOfWeek: z.array(z.enum(["U", "M", "T", "W", "R", "F", "S"])),
53+
startRecur: parsedDate().optional(),
54+
endRecur: parsedDate().optional(),
55+
})
56+
.merge(CommonSchema),
57+
z
58+
.object({
59+
type: z.literal("rrule"),
60+
startDate: parsedDate(),
61+
rrule: z.string(),
62+
skipDates: z.array(parsedDate()),
63+
})
64+
.merge(CommonSchema),
65+
]);
66+
67+
type EventType = z.infer<typeof EventSchema>;
68+
type TimeType = z.infer<typeof TimeSchema>;
69+
70+
export type OFCEvent = EventType & TimeType;
71+
72+
export function parseEvent(obj: any): OFCEvent | null {
73+
try {
74+
const timeInfo = TimeSchema.parse(obj);
75+
const eventInfo = EventSchema.parse(obj);
76+
return { ...eventInfo, ...timeInfo };
77+
} catch (e) {
78+
if (e instanceof ZodError) {
79+
console.debug("Parsing failed with errors", e.errors);
80+
}
81+
return null;
82+
}
83+
}

0 commit comments

Comments
 (0)