Zod 4 마이그레이션

This commit is contained in:
static
2025-12-25 22:53:51 +09:00
parent 6d95059450
commit b92b4a0b1b
13 changed files with 655 additions and 853 deletions

View File

@@ -17,52 +17,52 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/compat": "^1.4.1", "@eslint/compat": "^1.4.1",
"@iconify-json/material-symbols": "^1.2.44", "@iconify-json/material-symbols": "^1.2.50",
"@sveltejs/adapter-node": "^5.4.0", "@sveltejs/adapter-node": "^5.4.0",
"@sveltejs/kit": "^2.48.4", "@sveltejs/kit": "^2.49.2",
"@sveltejs/vite-plugin-svelte": "^6.2.1", "@sveltejs/vite-plugin-svelte": "^6.2.1",
"@trpc/client": "^11.7.1", "@trpc/client": "^11.8.1",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
"@types/ms": "^0.7.34", "@types/ms": "^0.7.34",
"@types/node-schedule": "^2.1.8", "@types/node-schedule": "^2.1.8",
"@types/pg": "^8.15.6", "@types/pg": "^8.16.0",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.23",
"axios": "^1.13.1", "axios": "^1.13.2",
"dexie": "^4.2.1", "dexie": "^4.2.1",
"eslint": "^9.39.0", "eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.13.0", "eslint-plugin-svelte": "^3.13.1",
"eslint-plugin-tailwindcss": "^3.18.2", "eslint-plugin-tailwindcss": "^3.18.2",
"exifreader": "^4.32.0", "exifreader": "^4.33.1",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"globals": "^16.5.0", "globals": "^16.5.0",
"heic2any": "^0.0.4", "heic2any": "^0.0.4",
"kysely-ctl": "^0.19.0", "kysely-ctl": "^0.19.0",
"lru-cache": "^11.2.2", "lru-cache": "^11.2.4",
"mime": "^4.1.0", "mime": "^4.1.0",
"p-limit": "^7.2.0", "p-limit": "^7.2.0",
"prettier": "^3.6.2", "prettier": "^3.7.4",
"prettier-plugin-svelte": "^3.4.0", "prettier-plugin-svelte": "^3.4.1",
"prettier-plugin-tailwindcss": "^0.7.1", "prettier-plugin-tailwindcss": "^0.7.2",
"svelte": "^5.43.2", "svelte": "^5.46.1",
"svelte-check": "^4.3.3", "svelte-check": "^4.3.5",
"tailwindcss": "^3.4.18", "tailwindcss": "^3.4.19",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.46.2", "typescript-eslint": "^8.50.1",
"unplugin-icons": "^22.5.0", "unplugin-icons": "^22.5.0",
"vite": "^7.1.12" "vite": "^7.3.0"
}, },
"dependencies": { "dependencies": {
"@fastify/busboy": "^3.2.0", "@fastify/busboy": "^3.2.0",
"@trpc/server": "^11.7.1", "@trpc/server": "^11.8.1",
"argon2": "^0.44.0", "argon2": "^0.44.0",
"kysely": "^0.28.8", "kysely": "^0.28.9",
"ms": "^2.1.3", "ms": "^2.1.3",
"node-schedule": "^2.1.1", "node-schedule": "^2.1.1",
"pg": "^8.16.3", "pg": "^8.16.3",
"superjson": "^2.2.6", "superjson": "^2.2.6",
"uuid": "^13.0.0", "uuid": "^13.0.0",
"zod": "^3.25.76" "zod": "^4.2.1"
}, },
"engines": { "engines": {
"node": "^22.0.0", "node": "^22.0.0",

1334
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,14 +5,14 @@ import type { ClientKeys } from "$lib/stores";
const serializedClientKeysSchema = z.intersection( const serializedClientKeysSchema = z.intersection(
z.object({ z.object({
generator: z.literal("ArkVault"), generator: z.literal("ArkVault"),
exportedAt: z.string().datetime(), exportedAt: z.iso.datetime(),
}), }),
z.object({ z.object({
version: z.literal(1), version: z.literal(1),
encryptKey: z.string().base64().nonempty(), encryptKey: z.base64().nonempty(),
decryptKey: z.string().base64().nonempty(), decryptKey: z.base64().nonempty(),
signKey: z.string().base64().nonempty(), signKey: z.base64().nonempty(),
verifyKey: z.string().base64().nonempty(), verifyKey: z.base64().nonempty(),
}), }),
); );

View File

@@ -7,26 +7,26 @@ export const passwordChangeRequest = z.object({
export type PasswordChangeRequest = z.input<typeof passwordChangeRequest>; export type PasswordChangeRequest = z.input<typeof passwordChangeRequest>;
export const loginRequest = z.object({ export const loginRequest = z.object({
email: z.string().email(), email: z.email(),
password: z.string().trim().nonempty(), password: z.string().trim().nonempty(),
}); });
export type LoginRequest = z.input<typeof loginRequest>; export type LoginRequest = z.input<typeof loginRequest>;
export const sessionUpgradeRequest = z.object({ export const sessionUpgradeRequest = z.object({
encPubKey: z.string().base64().nonempty(), encPubKey: z.base64().nonempty(),
sigPubKey: z.string().base64().nonempty(), sigPubKey: z.base64().nonempty(),
}); });
export type SessionUpgradeRequest = z.input<typeof sessionUpgradeRequest>; export type SessionUpgradeRequest = z.input<typeof sessionUpgradeRequest>;
export const sessionUpgradeResponse = z.object({ export const sessionUpgradeResponse = z.object({
id: z.number().int().positive(), id: z.int().positive(),
challenge: z.string().base64().nonempty(), challenge: z.base64().nonempty(),
}); });
export type SessionUpgradeResponse = z.output<typeof sessionUpgradeResponse>; export type SessionUpgradeResponse = z.output<typeof sessionUpgradeResponse>;
export const sessionUpgradeVerifyRequest = z.object({ export const sessionUpgradeVerifyRequest = z.object({
id: z.number().int().positive(), id: z.int().positive(),
answerSig: z.string().base64().nonempty(), answerSig: z.base64().nonempty(),
force: z.boolean().default(false), force: z.boolean().default(false),
}); });
export type SessionUpgradeVerifyRequest = z.input<typeof sessionUpgradeVerifyRequest>; export type SessionUpgradeVerifyRequest = z.input<typeof sessionUpgradeVerifyRequest>;

View File

@@ -1,3 +1,3 @@
import { z } from "zod"; import { z } from "zod";
export const categoryIdSchema = z.union([z.literal("root"), z.number().int().positive()]); export const categoryIdSchema = z.union([z.literal("root"), z.int().positive()]);

View File

@@ -1,3 +1,3 @@
import { z } from "zod"; import { z } from "zod";
export const directoryIdSchema = z.union([z.literal("root"), z.number().int().positive()]); export const directoryIdSchema = z.union([z.literal("root"), z.int().positive()]);

View File

@@ -3,34 +3,34 @@ import { z } from "zod";
import { directoryIdSchema } from "./directory"; import { directoryIdSchema } from "./directory";
export const fileThumbnailUploadRequest = z.object({ export const fileThumbnailUploadRequest = z.object({
dekVersion: z.string().datetime(), dekVersion: z.iso.datetime(),
contentIv: z.string().base64().nonempty(), contentIv: z.base64().nonempty(),
}); });
export type FileThumbnailUploadRequest = z.input<typeof fileThumbnailUploadRequest>; export type FileThumbnailUploadRequest = z.input<typeof fileThumbnailUploadRequest>;
export const fileUploadRequest = z.object({ export const fileUploadRequest = z.object({
parent: directoryIdSchema, parent: directoryIdSchema,
mekVersion: z.number().int().positive(), mekVersion: z.int().positive(),
dek: z.string().base64().nonempty(), dek: z.base64().nonempty(),
dekVersion: z.string().datetime(), dekVersion: z.iso.datetime(),
hskVersion: z.number().int().positive(), hskVersion: z.int().positive(),
contentHmac: z.string().base64().nonempty(), contentHmac: z.base64().nonempty(),
contentType: z contentType: z
.string() .string()
.trim() .trim()
.nonempty() .nonempty()
.refine((value) => mime.getExtension(value) !== null), // MIME type .refine((value) => mime.getExtension(value) !== null), // MIME type
contentIv: z.string().base64().nonempty(), contentIv: z.base64().nonempty(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
createdAt: z.string().base64().nonempty().optional(), createdAt: z.base64().nonempty().optional(),
createdAtIv: z.string().base64().nonempty().optional(), createdAtIv: z.base64().nonempty().optional(),
lastModifiedAt: z.string().base64().nonempty(), lastModifiedAt: z.base64().nonempty(),
lastModifiedAtIv: z.string().base64().nonempty(), lastModifiedAtIv: z.base64().nonempty(),
}); });
export type FileUploadRequest = z.input<typeof fileUploadRequest>; export type FileUploadRequest = z.input<typeof fileUploadRequest>;
export const fileUploadResponse = z.object({ export const fileUploadResponse = z.object({
file: z.number().int().positive(), file: z.int().positive(),
}); });
export type FileUploadResponse = z.output<typeof fileUploadResponse>; export type FileUploadResponse = z.output<typeof fileUploadResponse>;

View File

@@ -38,11 +38,11 @@ const categoryRouter = router({
.input( .input(
z.object({ z.object({
parent: categoryIdSchema, parent: categoryIdSchema,
mekVersion: z.number().int().positive(), mekVersion: z.int().positive(),
dek: z.string().base64().nonempty(), dek: z.base64().nonempty(),
dekVersion: z.date(), dekVersion: z.date(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -72,10 +72,10 @@ const categoryRouter = router({
rename: roleProcedure["activeClient"] rename: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
dekVersion: z.date(), dekVersion: z.date(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -99,7 +99,7 @@ const categoryRouter = router({
delete: roleProcedure["activeClient"] delete: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -116,7 +116,7 @@ const categoryRouter = router({
files: roleProcedure["activeClient"] files: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
recurse: z.boolean().default(false), recurse: z.boolean().default(false),
}), }),
) )
@@ -137,8 +137,8 @@ const categoryRouter = router({
addFile: roleProcedure["activeClient"] addFile: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
file: z.number().int().positive(), file: z.int().positive(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -165,8 +165,8 @@ const categoryRouter = router({
removeFile: roleProcedure["activeClient"] removeFile: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
file: z.number().int().positive(), file: z.int().positive(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {

View File

@@ -26,8 +26,8 @@ const clientRouter = router({
register: roleProcedure["notClient"] register: roleProcedure["notClient"]
.input( .input(
z.object({ z.object({
encPubKey: z.string().base64().nonempty(), encPubKey: z.base64().nonempty(),
sigPubKey: z.string().base64().nonempty(), sigPubKey: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -66,8 +66,8 @@ const clientRouter = router({
verify: roleProcedure["notClient"] verify: roleProcedure["notClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
answerSig: z.string().base64().nonempty(), answerSig: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {

View File

@@ -41,11 +41,11 @@ const directoryRouter = router({
.input( .input(
z.object({ z.object({
parent: directoryIdSchema, parent: directoryIdSchema,
mekVersion: z.number().int().positive(), mekVersion: z.int().positive(),
dek: z.string().base64().nonempty(), dek: z.base64().nonempty(),
dekVersion: z.date(), dekVersion: z.date(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -75,10 +75,10 @@ const directoryRouter = router({
rename: roleProcedure["activeClient"] rename: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
dekVersion: z.date(), dekVersion: z.date(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -102,7 +102,7 @@ const directoryRouter = router({
delete: roleProcedure["activeClient"] delete: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {

View File

@@ -8,7 +8,7 @@ const fileRouter = router({
get: roleProcedure["activeClient"] get: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
}), }),
) )
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
@@ -42,8 +42,8 @@ const fileRouter = router({
listByHash: roleProcedure["activeClient"] listByHash: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
hskVersion: z.number().int().positive(), hskVersion: z.int().positive(),
contentHmac: z.string().base64().nonempty(), contentHmac: z.base64().nonempty(),
}), }),
) )
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
@@ -61,10 +61,10 @@ const fileRouter = router({
rename: roleProcedure["activeClient"] rename: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
dekVersion: z.date(), dekVersion: z.date(),
name: z.string().base64().nonempty(), name: z.base64().nonempty(),
nameIv: z.string().base64().nonempty(), nameIv: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -88,7 +88,7 @@ const fileRouter = router({
delete: roleProcedure["activeClient"] delete: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
@@ -107,7 +107,7 @@ const fileRouter = router({
thumbnail: roleProcedure["activeClient"] thumbnail: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
id: z.number().int().positive(), id: z.int().positive(),
}), }),
) )
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {

View File

@@ -17,8 +17,8 @@ const hskRouter = router({
registerInitial: roleProcedure["activeClient"] registerInitial: roleProcedure["activeClient"]
.input( .input(
z.object({ z.object({
mekVersion: z.number().int().positive(), mekVersion: z.int().positive(),
hsk: z.string().base64().nonempty(), hsk: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {

View File

@@ -37,8 +37,8 @@ const mekRouter = router({
registerInitial: roleProcedure["pendingClient"] registerInitial: roleProcedure["pendingClient"]
.input( .input(
z.object({ z.object({
mek: z.string().base64().nonempty(), mek: z.base64().nonempty(),
mekSig: z.string().base64().nonempty(), mekSig: z.base64().nonempty(),
}), }),
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {