mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
디렉터리 관련 TanStack Query 코드 리팩토링
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
import { get, writable, type Writable } from "svelte/store";
|
||||
import { callGetApi } from "$lib/hooks";
|
||||
import {
|
||||
getDirectoryInfos as getDirectoryInfosFromIndexedDB,
|
||||
getDirectoryInfo as getDirectoryInfoFromIndexedDB,
|
||||
storeDirectoryInfo,
|
||||
deleteDirectoryInfo,
|
||||
getFileInfos as getFileInfosFromIndexedDB,
|
||||
getFileInfo as getFileInfoFromIndexedDB,
|
||||
storeFileInfo,
|
||||
deleteFileInfo,
|
||||
@@ -14,35 +9,15 @@ import {
|
||||
storeCategoryInfo,
|
||||
updateCategoryInfo as updateCategoryInfoInIndexedDB,
|
||||
deleteCategoryInfo,
|
||||
type DirectoryId,
|
||||
type CategoryId,
|
||||
} from "$lib/indexedDB";
|
||||
import { unwrapDataKey, decryptString } from "$lib/modules/crypto";
|
||||
import type {
|
||||
CategoryInfoResponse,
|
||||
CategoryFileListResponse,
|
||||
DirectoryInfoResponse,
|
||||
FileInfoResponse,
|
||||
} from "$lib/server/schemas";
|
||||
|
||||
export type DirectoryInfo =
|
||||
| {
|
||||
id: "root";
|
||||
dataKey?: undefined;
|
||||
dataKeyVersion?: undefined;
|
||||
name?: undefined;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
}
|
||||
| {
|
||||
id: number;
|
||||
dataKey?: CryptoKey;
|
||||
dataKeyVersion?: Date;
|
||||
name: string;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
};
|
||||
|
||||
export interface FileInfo {
|
||||
id: number;
|
||||
dataKey?: CryptoKey;
|
||||
@@ -75,92 +50,9 @@ export type CategoryInfo =
|
||||
isFileRecursive: boolean;
|
||||
};
|
||||
|
||||
const directoryInfoStore = new Map<DirectoryId, Writable<DirectoryInfo | null>>();
|
||||
const fileInfoStore = new Map<number, Writable<FileInfo | null>>();
|
||||
const categoryInfoStore = new Map<CategoryId, Writable<CategoryInfo | null>>();
|
||||
|
||||
const fetchDirectoryInfoFromIndexedDB = async (
|
||||
id: DirectoryId,
|
||||
info: Writable<DirectoryInfo | null>,
|
||||
) => {
|
||||
if (get(info)) return;
|
||||
|
||||
const [directory, subDirectories, files] = await Promise.all([
|
||||
id !== "root" ? getDirectoryInfoFromIndexedDB(id) : undefined,
|
||||
getDirectoryInfosFromIndexedDB(id),
|
||||
getFileInfosFromIndexedDB(id),
|
||||
]);
|
||||
const subDirectoryIds = subDirectories.map(({ id }) => id);
|
||||
const fileIds = files.map(({ id }) => id);
|
||||
|
||||
if (id === "root") {
|
||||
info.set({ id, subDirectoryIds, fileIds });
|
||||
} else {
|
||||
if (!directory) return;
|
||||
info.set({ id, name: directory.name, subDirectoryIds, fileIds });
|
||||
}
|
||||
};
|
||||
|
||||
const fetchDirectoryInfoFromServer = async (
|
||||
id: DirectoryId,
|
||||
info: Writable<DirectoryInfo | null>,
|
||||
masterKey: CryptoKey,
|
||||
) => {
|
||||
const res = await callGetApi(`/api/directory/${id}`);
|
||||
if (res.status === 404) {
|
||||
info.set(null);
|
||||
await deleteDirectoryInfo(id as number);
|
||||
return;
|
||||
} else if (!res.ok) {
|
||||
throw new Error("Failed to fetch directory information");
|
||||
}
|
||||
|
||||
const {
|
||||
metadata,
|
||||
subDirectories: subDirectoryIds,
|
||||
files: fileIds,
|
||||
}: DirectoryInfoResponse = await res.json();
|
||||
|
||||
if (id === "root") {
|
||||
info.set({ id, subDirectoryIds, fileIds });
|
||||
} else {
|
||||
const { dataKey } = await unwrapDataKey(metadata!.dek, masterKey);
|
||||
const name = await decryptString(metadata!.name, metadata!.nameIv, dataKey);
|
||||
|
||||
info.set({
|
||||
id,
|
||||
dataKey,
|
||||
dataKeyVersion: new Date(metadata!.dekVersion),
|
||||
name,
|
||||
subDirectoryIds,
|
||||
fileIds,
|
||||
});
|
||||
await storeDirectoryInfo({ id, parentId: metadata!.parent, name });
|
||||
}
|
||||
};
|
||||
|
||||
const fetchDirectoryInfo = async (
|
||||
id: DirectoryId,
|
||||
info: Writable<DirectoryInfo | null>,
|
||||
masterKey: CryptoKey,
|
||||
) => {
|
||||
await fetchDirectoryInfoFromIndexedDB(id, info);
|
||||
await fetchDirectoryInfoFromServer(id, info, masterKey);
|
||||
};
|
||||
|
||||
export const getDirectoryInfo = (id: DirectoryId, masterKey: CryptoKey) => {
|
||||
// TODO: MEK rotation
|
||||
|
||||
let info = directoryInfoStore.get(id);
|
||||
if (!info) {
|
||||
info = writable(null);
|
||||
directoryInfoStore.set(id, info);
|
||||
}
|
||||
|
||||
fetchDirectoryInfo(id, info, masterKey); // Intended
|
||||
return info;
|
||||
};
|
||||
|
||||
const fetchFileInfoFromIndexedDB = async (id: number, info: Writable<FileInfo | null>) => {
|
||||
if (get(info)) return;
|
||||
|
||||
|
||||
@@ -26,15 +26,33 @@ import {
|
||||
encryptString,
|
||||
decryptString,
|
||||
} from "$lib/modules/crypto";
|
||||
import type { DirectoryInfo } from "$lib/modules/filesystem";
|
||||
import type {
|
||||
DirectoryInfoResponse,
|
||||
DirectoryDeleteResponse,
|
||||
DirectoryRenameRequest,
|
||||
DirectoryCreateRequest,
|
||||
DirectoryCreateResponse,
|
||||
DirectoryInfoResponse,
|
||||
DirectoryRenameRequest,
|
||||
} from "$lib/server/schemas";
|
||||
import type { MasterKey } from "$lib/stores";
|
||||
|
||||
export type DirectoryInfo =
|
||||
| {
|
||||
id: "root";
|
||||
dataKey?: undefined;
|
||||
dataKeyVersion?: undefined;
|
||||
name?: undefined;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
}
|
||||
| {
|
||||
id: number;
|
||||
dataKey?: CryptoKey;
|
||||
dataKeyVersion?: Date;
|
||||
name: string;
|
||||
subDirectoryIds: number[];
|
||||
fileIds: number[];
|
||||
};
|
||||
|
||||
const initializedDirectoryIds = new Set<DirectoryId>();
|
||||
let temporaryIdCounter = -1;
|
||||
|
||||
@@ -99,15 +117,10 @@ export const getDirectoryInfo = (id: DirectoryId, masterKey: CryptoKey) => {
|
||||
|
||||
export type DirectoryInfoStore = ReturnType<typeof getDirectoryInfo>;
|
||||
|
||||
export const useDirectoryCreate = (parentId: DirectoryId) => {
|
||||
export const useDirectoryCreation = (parentId: DirectoryId, masterKey: MasterKey) => {
|
||||
const queryClient = useQueryClient();
|
||||
return createMutation<
|
||||
{ id: number; dataKey: CryptoKey; dataKeyVersion: Date },
|
||||
Error,
|
||||
{ name: string; masterKey: MasterKey },
|
||||
{ prevParentInfo: DirectoryInfo | undefined; tempId: number }
|
||||
>({
|
||||
mutationFn: async ({ name, masterKey }) => {
|
||||
return createMutation<void, Error, { name: string }, { tempId: number }>({
|
||||
mutationFn: async ({ name }) => {
|
||||
const { dataKey, dataKeyVersion } = await generateDataKey();
|
||||
const nameEncrypted = await encryptString(name, dataKey);
|
||||
|
||||
@@ -119,30 +132,9 @@ export const useDirectoryCreate = (parentId: DirectoryId) => {
|
||||
name: nameEncrypted.ciphertext,
|
||||
nameIv: nameEncrypted.iv,
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed to create directory");
|
||||
|
||||
const { directory: id }: DirectoryCreateResponse = await res.json();
|
||||
return { id, dataKey, dataKeyVersion };
|
||||
},
|
||||
onMutate: async ({ name }) => {
|
||||
await queryClient.cancelQueries({ queryKey: ["directory", parentId] });
|
||||
|
||||
const prevParentInfo = queryClient.getQueryData<DirectoryInfo>(["directory", parentId]);
|
||||
const tempId = temporaryIdCounter--;
|
||||
if (prevParentInfo) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], {
|
||||
...prevParentInfo,
|
||||
subDirectoryIds: [...prevParentInfo.subDirectoryIds, tempId],
|
||||
});
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", tempId], {
|
||||
id: tempId,
|
||||
name,
|
||||
subDirectoryIds: [],
|
||||
fileIds: [],
|
||||
});
|
||||
}
|
||||
|
||||
return { prevParentInfo, tempId };
|
||||
},
|
||||
onSuccess: async ({ id, dataKey, dataKeyVersion }, { name }) => {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", id], {
|
||||
id,
|
||||
name,
|
||||
@@ -153,13 +145,38 @@ export const useDirectoryCreate = (parentId: DirectoryId) => {
|
||||
});
|
||||
await storeDirectoryInfo({ id, parentId, name });
|
||||
},
|
||||
onError: (error, { name }, context) => {
|
||||
if (context?.prevParentInfo) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], context.prevParentInfo);
|
||||
}
|
||||
console.error(`Failed to create directory "${name}" in parent ${parentId}:`, error);
|
||||
onMutate: async ({ name }) => {
|
||||
const tempId = temporaryIdCounter--;
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", tempId], {
|
||||
id: tempId,
|
||||
name,
|
||||
subDirectoryIds: [],
|
||||
fileIds: [],
|
||||
});
|
||||
|
||||
await queryClient.cancelQueries({ queryKey: ["directory", parentId] });
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], (prevParentInfo) => {
|
||||
if (!prevParentInfo) return undefined;
|
||||
return {
|
||||
...prevParentInfo,
|
||||
subDirectoryIds: [...prevParentInfo.subDirectoryIds, tempId],
|
||||
};
|
||||
});
|
||||
|
||||
return { tempId };
|
||||
},
|
||||
onSettled: (id) => {
|
||||
onError: (_error, _variables, context) => {
|
||||
if (context) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], (prevParentInfo) => {
|
||||
if (!prevParentInfo) return undefined;
|
||||
return {
|
||||
...prevParentInfo,
|
||||
subDirectoryIds: prevParentInfo.subDirectoryIds.filter((id) => id !== context.tempId),
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["directory", parentId] });
|
||||
},
|
||||
});
|
||||
@@ -176,15 +193,18 @@ export const useDirectoryRename = () => {
|
||||
dataKeyVersion: Date;
|
||||
newName: string;
|
||||
},
|
||||
{ prevInfo: (DirectoryInfo & { id: number }) | undefined }
|
||||
{ oldName: string | undefined }
|
||||
>({
|
||||
mutationFn: async ({ id, dataKey, dataKeyVersion, newName }) => {
|
||||
const newNameEncrypted = await encryptString(newName, dataKey);
|
||||
await callPostApi<DirectoryRenameRequest>(`/api/directory/${id}/rename`, {
|
||||
const res = await callPostApi<DirectoryRenameRequest>(`/api/directory/${id}/rename`, {
|
||||
dekVersion: dataKeyVersion.toISOString(),
|
||||
name: newNameEncrypted.ciphertext,
|
||||
nameIv: newNameEncrypted.iv,
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed to rename directory");
|
||||
|
||||
await updateDirectoryInfo(id, { name: newName });
|
||||
},
|
||||
onMutate: async ({ id, newName }) => {
|
||||
await queryClient.cancelQueries({ queryKey: ["directory", id] });
|
||||
@@ -195,61 +215,62 @@ export const useDirectoryRename = () => {
|
||||
...prevInfo,
|
||||
name: newName,
|
||||
});
|
||||
await updateDirectoryInfo(id, { name: newName });
|
||||
}
|
||||
|
||||
return { prevInfo };
|
||||
return { oldName: prevInfo?.name };
|
||||
},
|
||||
onSuccess: async (data, { id, newName }) => {
|
||||
await updateDirectoryInfo(id, { name: newName });
|
||||
},
|
||||
onError: (error, { id }, context) => {
|
||||
if (context?.prevInfo) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", id], context.prevInfo);
|
||||
onError: (_error, { id }, context) => {
|
||||
if (context?.oldName) {
|
||||
queryClient.setQueryData<DirectoryInfo & { id: number }>(["directory", id], (prevInfo) => {
|
||||
if (!prevInfo) return undefined;
|
||||
return { ...prevInfo, name: context.oldName! };
|
||||
});
|
||||
}
|
||||
console.error("Failed to rename directory:", error);
|
||||
},
|
||||
onSettled: (data, error, { id }) => {
|
||||
onSettled: (_data, _error, { id }) => {
|
||||
queryClient.invalidateQueries({ queryKey: ["directory", id] });
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useDirectoryDelete = (parentId: DirectoryId) => {
|
||||
export const useDirectoryDeletion = (parentId: DirectoryId) => {
|
||||
const queryClient = useQueryClient();
|
||||
return createMutation<
|
||||
void,
|
||||
Error,
|
||||
{ id: number },
|
||||
{ prevInfo: (DirectoryInfo & { id: number }) | undefined }
|
||||
>({
|
||||
return createMutation<{ deletedFiles: number[] }, Error, { id: number }, {}>({
|
||||
mutationFn: async ({ id }) => {
|
||||
await callPostApi(`/api/directory/${id}/delete`);
|
||||
const res = await callPostApi(`/api/directory/${id}/delete`);
|
||||
if (!res.ok) throw new Error("Failed to delete directory");
|
||||
|
||||
const { deletedDirectories, deletedFiles }: DirectoryDeleteResponse = await res.json();
|
||||
await Promise.all([
|
||||
...deletedDirectories.map(deleteDirectoryInfo),
|
||||
...deletedFiles.map(deleteFileInfo),
|
||||
]);
|
||||
|
||||
return { deletedFiles };
|
||||
},
|
||||
onMutate: async ({ id }) => {
|
||||
await queryClient.cancelQueries({ queryKey: ["directory", parentId] });
|
||||
|
||||
const prevParentInfo = queryClient.getQueryData<DirectoryInfo>(["directory", parentId]);
|
||||
if (prevParentInfo) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], (prevParentInfo) => {
|
||||
if (!prevParentInfo) return undefined;
|
||||
return {
|
||||
...prevParentInfo,
|
||||
subDirectoryIds: prevParentInfo.subDirectoryIds.filter((subId) => subId !== id),
|
||||
};
|
||||
});
|
||||
return {};
|
||||
},
|
||||
onError: (_error, { id }, context) => {
|
||||
if (context) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], (prevParentInfo) => {
|
||||
if (!prevParentInfo) return undefined;
|
||||
return {
|
||||
...prevParentInfo,
|
||||
subDirectoryIds: [...prevParentInfo.subDirectoryIds, id],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const prevInfo = queryClient.getQueryData<DirectoryInfo & { id: number }>(["directory", id]);
|
||||
return { prevInfo };
|
||||
},
|
||||
onSuccess: async (data, { id }) => {
|
||||
await deleteDirectoryInfo(id);
|
||||
},
|
||||
onError: (error, { id }, context) => {
|
||||
if (context?.prevInfo) {
|
||||
queryClient.setQueryData<DirectoryInfo>(["directory", parentId], context?.prevInfo);
|
||||
}
|
||||
console.error("Failed to delete directory:", error);
|
||||
},
|
||||
onSettled: (data, error, { id }) => {
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["directory", parentId] });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -181,7 +181,10 @@ export const unregisterDirectory = async (userId: number, directoryId: number) =
|
||||
};
|
||||
const unregisterDirectoryRecursively = async (
|
||||
directoryId: number,
|
||||
): Promise<{ id: number; path: string; thumbnailPath: string | null }[]> => {
|
||||
): Promise<{
|
||||
subDirectories: { id: number }[];
|
||||
files: { id: number; path: string; thumbnailPath: string | null }[];
|
||||
}> => {
|
||||
const files = await unregisterFiles(directoryId);
|
||||
const subDirectories = await trx
|
||||
.selectFrom("directory")
|
||||
@@ -189,7 +192,7 @@ export const unregisterDirectory = async (userId: number, directoryId: number) =
|
||||
.where("parent_id", "=", directoryId)
|
||||
.where("user_id", "=", userId)
|
||||
.execute();
|
||||
const subDirectoryFilePaths = await Promise.all(
|
||||
const subDirectoryEntries = await Promise.all(
|
||||
subDirectories.map(async ({ id }) => await unregisterDirectoryRecursively(id)),
|
||||
);
|
||||
|
||||
@@ -201,7 +204,12 @@ export const unregisterDirectory = async (userId: number, directoryId: number) =
|
||||
if (deleteRes.numDeletedRows === 0n) {
|
||||
throw new IntegrityError("Directory not found");
|
||||
}
|
||||
return files.concat(...subDirectoryFilePaths);
|
||||
return {
|
||||
subDirectories: subDirectoryEntries
|
||||
.flatMap(({ subDirectories }) => subDirectories)
|
||||
.concat(subDirectories),
|
||||
files: subDirectoryEntries.flatMap(({ files }) => files).concat(files),
|
||||
};
|
||||
};
|
||||
return await unregisterDirectoryRecursively(directoryId);
|
||||
});
|
||||
|
||||
@@ -19,6 +19,7 @@ export const directoryInfoResponse = z.object({
|
||||
export type DirectoryInfoResponse = z.output<typeof directoryInfoResponse>;
|
||||
|
||||
export const directoryDeleteResponse = z.object({
|
||||
deletedDirectories: z.number().int().positive().array(),
|
||||
deletedFiles: z.number().int().positive().array(),
|
||||
});
|
||||
export type DirectoryDeleteResponse = z.output<typeof directoryDeleteResponse>;
|
||||
|
||||
@@ -42,8 +42,9 @@ const safeUnlink = async (path: string | null) => {
|
||||
|
||||
export const deleteDirectory = async (userId: number, directoryId: number) => {
|
||||
try {
|
||||
const files = await unregisterDirectory(userId, directoryId);
|
||||
const { subDirectories, files } = await unregisterDirectory(userId, directoryId);
|
||||
return {
|
||||
directories: [...subDirectories.map(({ id }) => id), directoryId],
|
||||
files: files.map(({ id, path, thumbnailPath }) => {
|
||||
safeUnlink(path); // Intended
|
||||
safeUnlink(thumbnailPath); // Intended
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import type { Writable } from "svelte/store";
|
||||
import { goto } from "$app/navigation";
|
||||
import { FloatingButton } from "$lib/components/atoms";
|
||||
import { TopBar } from "$lib/components/molecules";
|
||||
import { type DirectoryInfo } from "$lib/modules/filesystem";
|
||||
import { deleteFileCache, deleteFileThumbnailCache } from "$lib/modules/file";
|
||||
import {
|
||||
getDirectoryInfo,
|
||||
useDirectoryCreate,
|
||||
useDirectoryCreation,
|
||||
useDirectoryRename,
|
||||
useDirectoryDelete,
|
||||
useDirectoryDeletion,
|
||||
} from "$lib/modules/filesystem2";
|
||||
import { masterKeyStore, hmacSecretStore } from "$lib/stores";
|
||||
import DirectoryCreateModal from "./DirectoryCreateModal.svelte";
|
||||
@@ -35,9 +34,9 @@
|
||||
let context = createContext();
|
||||
|
||||
let info = $derived(getDirectoryInfo(data.id, $masterKeyStore?.get(1)?.key!));
|
||||
let requestDirectoryCreation = $derived(useDirectoryCreate(data.id));
|
||||
let requestDirectoryCreation = $derived(useDirectoryCreation(data.id, $masterKeyStore?.get(1)!));
|
||||
let requestDirectoryRename = useDirectoryRename();
|
||||
let requestDirectoryDeletion = $derived(useDirectoryDelete(data.id));
|
||||
let requestDirectoryDeletion = $derived(useDirectoryDeletion(data.id));
|
||||
|
||||
let fileInput: HTMLInputElement | undefined = $state();
|
||||
let duplicatedFile: File | undefined = $state();
|
||||
@@ -135,10 +134,7 @@
|
||||
<DirectoryCreateModal
|
||||
bind:isOpen={isDirectoryCreateModalOpen}
|
||||
onCreateClick={async (name) => {
|
||||
$requestDirectoryCreation.mutate({
|
||||
name,
|
||||
masterKey: $masterKeyStore?.get(1)!,
|
||||
});
|
||||
$requestDirectoryCreation.mutate({ name });
|
||||
return true; // TODO
|
||||
}}
|
||||
/>
|
||||
@@ -190,9 +186,16 @@
|
||||
bind:isOpen={isEntryDeleteModalOpen}
|
||||
onDeleteClick={async () => {
|
||||
if (context.selectedEntry!.type === "directory") {
|
||||
$requestDirectoryDeletion.mutate({
|
||||
const res = await $requestDirectoryDeletion.mutateAsync({
|
||||
id: context.selectedEntry!.id,
|
||||
});
|
||||
if (!res) return false;
|
||||
await Promise.all(
|
||||
res.deletedFiles.flatMap((fileId) => [
|
||||
deleteFileCache(fileId),
|
||||
deleteFileThumbnailCache(fileId),
|
||||
]),
|
||||
);
|
||||
return true; // TODO
|
||||
} else {
|
||||
if (await requestEntryDeletion(context.selectedEntry!)) {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { untrack } from "svelte";
|
||||
import { get, type Readable, type Writable } from "svelte/store";
|
||||
import { getFileInfo, type DirectoryInfo, type FileInfo } from "$lib/modules/filesystem";
|
||||
import { getDirectoryInfo, type DirectoryInfoStore } from "$lib/modules/filesystem2";
|
||||
import { get, type Writable } from "svelte/store";
|
||||
import { getFileInfo, type FileInfo } from "$lib/modules/filesystem";
|
||||
import {
|
||||
getDirectoryInfo,
|
||||
type DirectoryInfo,
|
||||
type DirectoryInfoStore,
|
||||
} from "$lib/modules/filesystem2";
|
||||
import { SortBy, sortEntries } from "$lib/modules/util";
|
||||
import {
|
||||
fileUploadStatusStore,
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { Writable } from "svelte/store";
|
||||
import { ActionEntryButton } from "$lib/components/atoms";
|
||||
import { DirectoryEntryLabel } from "$lib/components/molecules";
|
||||
import type { DirectoryInfo } from "$lib/modules/filesystem";
|
||||
import type { DirectoryInfoStore } from "$lib/modules/filesystem2";
|
||||
import type { DirectoryInfo, DirectoryInfoStore } from "$lib/modules/filesystem2";
|
||||
import type { SelectedEntry } from "../service.svelte";
|
||||
|
||||
import IconMoreVert from "~icons/material-symbols/more-vert";
|
||||
|
||||
@@ -16,8 +16,11 @@ export const POST: RequestHandler = async ({ locals, params }) => {
|
||||
if (!zodRes.success) error(400, "Invalid path parameters");
|
||||
const { id } = zodRes.data;
|
||||
|
||||
const { files } = await deleteDirectory(userId, id);
|
||||
const { directories, files } = await deleteDirectory(userId, id);
|
||||
return json(
|
||||
directoryDeleteResponse.parse({ deletedFiles: files } satisfies DirectoryDeleteResponse),
|
||||
directoryDeleteResponse.parse({
|
||||
deletedDirectories: directories,
|
||||
deletedFiles: files,
|
||||
} satisfies DirectoryDeleteResponse),
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user