Skip to content

Commit

Permalink
Add support for deserializing string dates
Browse files Browse the repository at this point in the history
  • Loading branch information
EddieAbbondanzio committed Sep 18, 2022
1 parent b5f8ec1 commit cd74f85
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
12 changes: 2 additions & 10 deletions src/main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Config } from "../shared/domain/config";
import { APP_STATE_MIGRATIONS } from "./migrations/appState";
import p from "path";
import { MissingDataDirectoryError } from "../shared/errors";
import { DATE_OR_STRING_SCHEMA } from "../shared/domain";

export const APP_STATE_PATH = "ui.json";

Expand Down Expand Up @@ -53,16 +54,7 @@ export const APP_STATE_SCHEMA = z
z.object({
noteId: z.string(),
// Intentionally omitted noteContent
lastActive: z.preprocess((arg) => {
// If loaded from JSON dates will be a string
if (typeof arg === "string") {
return parseJSON(arg);
}
// But if it was already in memory they'll be a date.
else if (arg instanceof Date) {
return arg;
}
}, z.date().optional()),
lastActive: DATE_OR_STRING_SCHEMA.optional(),
})
)
.default([]),
Expand Down
4 changes: 3 additions & 1 deletion src/main/migrations/appState/1_initialDefinition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { parseJSON } from "date-fns";
import { z } from "zod";
import { DATE_OR_STRING_SCHEMA } from "../../../shared/domain";
import {
DEFAULT_NOTE_SORTING_ALGORITHM,
NoteSort,
Expand Down Expand Up @@ -30,7 +32,7 @@ export const appStateSchemaV1 = z.object({
z.object({
noteId: z.string(),
// Intentionally omitted noteContent
lastActive: z.date().optional(),
lastActive: DATE_OR_STRING_SCHEMA.optional(),
})
),
tabsScroll: z.number().default(0),
Expand Down
5 changes: 5 additions & 0 deletions src/shared/domain/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parseJSON } from "date-fns";
import { customAlphabet } from "nanoid";
import { z } from "zod";

Expand All @@ -9,6 +10,10 @@ export const uuid = customAlphabet(ID_ALPHABET, ID_LENGTH);
export const UUID_REGEX = /[a-zA-Z0-9]{10}$/;

export const UUID_SCHEMA = z.string().refine((val) => UUID_REGEX.test(val));
export const DATE_OR_STRING_SCHEMA = z.union([
z.date(),
z.string().transform((v) => parseJSON(v)),
]);

export interface Resource {
id: string;
Expand Down
7 changes: 4 additions & 3 deletions src/shared/domain/note.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { UUID_SCHEMA, Resource, uuid } from ".";
import { UUID_SCHEMA, Resource, uuid, DATE_OR_STRING_SCHEMA } from ".";
import { isBlank } from "../utils";
import { isEmpty, orderBy } from "lodash";
import { z } from "zod";
import { parseJSON } from "date-fns";

export interface Note extends Resource {
name: string;
Expand Down Expand Up @@ -113,8 +114,8 @@ export const NOTE_SCHEMA = z.object({
.min(1, "Name must be at least 1 char long")
.max(64, "Name must be 64 chars or less."),
flags: z.number().optional(),
dateCreated: z.date(),
dateUpdated: z.date().optional(),
dateCreated: DATE_OR_STRING_SCHEMA,
dateUpdated: DATE_OR_STRING_SCHEMA.optional(),
sort: z.nativeEnum(NoteSort).optional(),
});

Expand Down
18 changes: 16 additions & 2 deletions test/shared/domain/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { UUID_SCHEMA } from "../../../src/shared/domain";
import { isEqual, parseJSON } from "date-fns";
import { DATE_OR_STRING_SCHEMA, UUID_SCHEMA } from "../../../src/shared/domain";

test("uuidSchema", async () => {
test("UUID_SCHEMA", async () => {
const uuid = "d3ZU8GmTG3";
expect(await UUID_SCHEMA.parseAsync(uuid)).toBe("d3ZU8GmTG3");
});

test("DATE_OR_STRING_SCHEMA", async () => {
// In the past we've had some deserialize bugs pop up because JSON stores dates
// as strings. This test is just to help prevent regressions.

const date = new Date("2020-01-01T20:37:21.765Z")
const parsed = await DATE_OR_STRING_SCHEMA.parseAsync(date);
expect(isEqual(date, parsed)).toBe(true);

const serializedDate = "2022-09-09T20:37:21.765Z";
const parsedSerializedDate = parseJSON(serializedDate);
expect(isEqual(parsedSerializedDate, parsedSerializedDate)).toBe(true);
}

0 comments on commit cd74f85

Please sign in to comment.