/api/category, /api/directory, /api/file 아래의 대부분의 Endpoint들을 tRPC로 마이그레이션

This commit is contained in:
static
2025-12-25 22:45:55 +09:00
parent a08ddf2c09
commit 6d95059450
45 changed files with 691 additions and 1097 deletions

View File

@@ -1,8 +1,7 @@
import { getContext, setContext } from "svelte";
import { callPostApi } from "$lib/hooks";
import { encryptString } from "$lib/modules/crypto";
import type { SelectedCategory } from "$lib/components/molecules";
import type { CategoryRenameRequest } from "$lib/server/schemas";
import { useTRPC } from "$trpc/client";
export { requestCategoryCreation, requestFileRemovalFromCategory } from "$lib/services/category";
@@ -18,17 +17,31 @@ export const useContext = () => {
};
export const requestCategoryRename = async (category: SelectedCategory, newName: string) => {
const trpc = useTRPC();
const newNameEncrypted = await encryptString(newName, category.dataKey);
const res = await callPostApi<CategoryRenameRequest>(`/api/category/${category.id}/rename`, {
dekVersion: category.dataKeyVersion.toISOString(),
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
return res.ok;
try {
await trpc.category.rename.mutate({
id: category.id,
dekVersion: category.dataKeyVersion,
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
return true;
} catch {
// TODO: Error Handling
return false;
}
};
export const requestCategoryDeletion = async (category: SelectedCategory) => {
const res = await callPostApi(`/api/category/${category.id}/delete`);
return res.ok;
const trpc = useTRPC();
try {
await trpc.category.delete.mutate({ id: category.id });
return true;
} catch {
// TODO: Error Handling
return false;
}
};

View File

@@ -1,5 +1,4 @@
import { getContext, setContext } from "svelte";
import { callPostApi } from "$lib/hooks";
import { storeHmacSecrets } from "$lib/indexedDB";
import { generateDataKey, wrapDataKey, unwrapHmacSecret, encryptString } from "$lib/modules/crypto";
import {
@@ -9,12 +8,6 @@ import {
deleteFileThumbnailCache,
uploadFile,
} from "$lib/modules/file";
import type {
DirectoryRenameRequest,
DirectoryCreateRequest,
FileRenameRequest,
DirectoryDeleteResponse,
} from "$lib/server/schemas";
import { hmacSecretStore, type MasterKey, type HmacSecret } from "$lib/stores";
import { useTRPC } from "$trpc/client";
@@ -68,18 +61,24 @@ export const requestDirectoryCreation = async (
parentId: "root" | number,
masterKey: MasterKey,
) => {
const trpc = useTRPC();
const { dataKey, dataKeyVersion } = await generateDataKey();
const nameEncrypted = await encryptString(name, dataKey);
const res = await callPostApi<DirectoryCreateRequest>("/api/directory/create", {
parent: parentId,
mekVersion: masterKey.version,
dek: await wrapDataKey(dataKey, masterKey.key),
dekVersion: dataKeyVersion.toISOString(),
name: nameEncrypted.ciphertext,
nameIv: nameEncrypted.iv,
});
return res.ok;
try {
await trpc.directory.create.mutate({
parent: parentId,
mekVersion: masterKey.version,
dek: await wrapDataKey(dataKey, masterKey.key),
dekVersion: dataKeyVersion,
name: nameEncrypted.ciphertext,
nameIv: nameEncrypted.iv,
});
return true;
} catch {
// TODO: Error Handling
return false;
}
};
export const requestFileUpload = async (
@@ -101,37 +100,51 @@ export const requestFileUpload = async (
};
export const requestEntryRename = async (entry: SelectedEntry, newName: string) => {
const trpc = useTRPC();
const newNameEncrypted = await encryptString(newName, entry.dataKey);
let res;
if (entry.type === "directory") {
res = await callPostApi<DirectoryRenameRequest>(`/api/directory/${entry.id}/rename`, {
dekVersion: entry.dataKeyVersion.toISOString(),
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
} else {
res = await callPostApi<FileRenameRequest>(`/api/file/${entry.id}/rename`, {
dekVersion: entry.dataKeyVersion.toISOString(),
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
try {
if (entry.type === "directory") {
await trpc.directory.rename.mutate({
id: entry.id,
dekVersion: entry.dataKeyVersion,
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
} else {
await trpc.file.rename.mutate({
id: entry.id,
dekVersion: entry.dataKeyVersion,
name: newNameEncrypted.ciphertext,
nameIv: newNameEncrypted.iv,
});
}
return true;
} catch {
// TODO: Error Handling
return false;
}
return res.ok;
};
export const requestEntryDeletion = async (entry: SelectedEntry) => {
const res = await callPostApi(`/api/${entry.type}/${entry.id}/delete`);
if (!res.ok) return false;
const trpc = useTRPC();
if (entry.type === "directory") {
const { deletedFiles }: DirectoryDeleteResponse = await res.json();
await Promise.all(
deletedFiles.flatMap((fileId) => [deleteFileCache(fileId), deleteFileThumbnailCache(fileId)]),
);
return true;
} else {
await Promise.all([deleteFileCache(entry.id), deleteFileThumbnailCache(entry.id)]);
try {
if (entry.type === "directory") {
const { deletedFiles } = await trpc.directory.delete.mutate({ id: entry.id });
await Promise.all(
deletedFiles.flatMap((fileId) => [
deleteFileCache(fileId),
deleteFileThumbnailCache(fileId),
]),
);
} else {
await trpc.file.delete.mutate({ id: entry.id });
await Promise.all([deleteFileCache(entry.id), deleteFileThumbnailCache(entry.id)]);
}
return true;
} catch {
// TODO: Error Handling
return false;
}
};

View File

@@ -6,7 +6,7 @@ export const load: PageLoad = async ({ fetch }) => {
const trpc = useTRPC(fetch);
try {
const { nickname } = await trpc.user.info.query();
const { nickname } = await trpc.user.get.query();
return { nickname };
} catch {
error(500, "Internal server error");