Skip to content

Commit

Permalink
added zod
Browse files Browse the repository at this point in the history
  • Loading branch information
davish committed Apr 2, 2023
1 parent e432f99 commit 2f5da6f
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 2 deletions.
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"obsidian-daily-notes-interface": "^0.9.4",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"rrule": "^2.7.2"
"rrule": "^2.7.2",
"zod": "^3.21.4"
}
}
83 changes: 83 additions & 0 deletions src/types/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { z, ZodError } from "zod";
import { DateTime, Duration } from "luxon";

const parsedDate = () =>
z.string().transform((val) => DateTime.fromFormat(val, "yyyy-MM-dd"));
const parsedTime = () =>
z.string().transform((val, ctx) => {
let parsed = DateTime.fromFormat(val, "h:mm a");
if (parsed.invalidReason) {
parsed = DateTime.fromFormat(val, "HH:mm");
}

if (parsed.invalidReason) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: parsed.invalidReason,
});
return z.NEVER;
}

return Duration.fromISOTime(
parsed.toISOTime({
includeOffset: false,
includePrefix: false,
})
);
});

const TimeSchema = z.discriminatedUnion("allDay", [
z.object({ allDay: z.literal(true) }),
z.object({
allDay: z.literal(false).optional(),
startTime: parsedTime(),
endTime: parsedTime(),
}),
]);

const CommonSchema = z.object({ title: z.string(), id: z.string().optional() });

const EventSchema = z.discriminatedUnion("type", [
z
.object({
type: z.literal("single").default("single"),
date: parsedDate(),
endDate: parsedDate().optional(),
completed: z.date().or(z.literal(false)).or(z.literal(null)),
})
.merge(CommonSchema),
z
.object({
type: z.literal("recurring"),
daysOfWeek: z.array(z.enum(["U", "M", "T", "W", "R", "F", "S"])),
startRecur: parsedDate().optional(),
endRecur: parsedDate().optional(),
})
.merge(CommonSchema),
z
.object({
type: z.literal("rrule"),
startDate: parsedDate(),
rrule: z.string(),
skipDates: z.array(parsedDate()),
})
.merge(CommonSchema),
]);

type EventType = z.infer<typeof EventSchema>;
type TimeType = z.infer<typeof TimeSchema>;

export type OFCEvent = EventType & TimeType;

export function parseEvent(obj: any): OFCEvent | null {
try {
const timeInfo = TimeSchema.parse(obj);
const eventInfo = EventSchema.parse(obj);
return { ...eventInfo, ...timeInfo };
} catch (e) {
if (e instanceof ZodError) {
console.debug("Parsing failed with errors", e.errors);
}
return null;
}
}

0 comments on commit 2f5da6f

Please sign in to comment.