mirror of
https://github.com/kmc7468/arkvault.git
synced 2025-12-14 22:08:45 +00:00
디렉터리를 삭제하는 경우, 디렉터리 하위에 있던 파일의 캐시를 자동으로 삭제하도록 구현
This commit is contained in:
@@ -129,14 +129,15 @@ export const unregisterDirectory = async (userId: number, directoryId: number) =
|
||||
return await db.transaction(
|
||||
async (tx) => {
|
||||
const unregisterFiles = async (parentId: number) => {
|
||||
const files = await tx
|
||||
return await tx
|
||||
.delete(file)
|
||||
.where(and(eq(file.userId, userId), eq(file.parentId, parentId)))
|
||||
.returning({ path: file.path });
|
||||
return files.map(({ path }) => path);
|
||||
.returning({ id: file.id, path: file.path });
|
||||
};
|
||||
const unregisterDirectoryRecursively = async (directoryId: number): Promise<string[]> => {
|
||||
const filePaths = await unregisterFiles(directoryId);
|
||||
const unregisterDirectoryRecursively = async (
|
||||
directoryId: number,
|
||||
): Promise<{ id: number; path: string }[]> => {
|
||||
const files = await unregisterFiles(directoryId);
|
||||
const subDirectories = await tx
|
||||
.select({ id: directory.id })
|
||||
.from(directory)
|
||||
@@ -149,7 +150,7 @@ export const unregisterDirectory = async (userId: number, directoryId: number) =
|
||||
if (deleteRes.changes === 0) {
|
||||
throw new IntegrityError("Directory not found");
|
||||
}
|
||||
return filePaths.concat(...subDirectoryFilePaths);
|
||||
return files.concat(...subDirectoryFilePaths);
|
||||
};
|
||||
return await unregisterDirectoryRecursively(directoryId);
|
||||
},
|
||||
|
||||
@@ -15,6 +15,11 @@ export const directoryInfoResponse = z.object({
|
||||
});
|
||||
export type DirectoryInfoResponse = z.infer<typeof directoryInfoResponse>;
|
||||
|
||||
export const directoryDeleteResponse = z.object({
|
||||
deletedFiles: z.number().int().positive().array(),
|
||||
});
|
||||
export type DirectoryDeleteResponse = z.infer<typeof directoryDeleteResponse>;
|
||||
|
||||
export const directoryRenameRequest = z.object({
|
||||
dekVersion: z.string().datetime(),
|
||||
name: z.string().base64().nonempty(),
|
||||
|
||||
@@ -34,8 +34,13 @@ export const getDirectoryInformation = async (userId: number, directoryId: "root
|
||||
|
||||
export const deleteDirectory = async (userId: number, directoryId: number) => {
|
||||
try {
|
||||
const filePaths = await unregisterDirectory(userId, directoryId);
|
||||
filePaths.map((path) => unlink(path)); // Intended
|
||||
const files = await unregisterDirectory(userId, directoryId);
|
||||
return {
|
||||
files: files.map(({ id, path }) => {
|
||||
unlink(path); // Intended
|
||||
return id;
|
||||
}),
|
||||
};
|
||||
} catch (e) {
|
||||
if (e instanceof IntegrityError && e.message === "Directory not found") {
|
||||
error(404, "Invalid directory id");
|
||||
|
||||
@@ -29,7 +29,12 @@
|
||||
fileInfo: getFileInfo(index.fileId, $masterKeyStore?.get(1)?.key!),
|
||||
}))
|
||||
.sort((a, b) => a.index.lastRetrievedAt.getTime() - b.index.lastRetrievedAt.getTime());
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (fileCache) {
|
||||
fileCacheTotalSize = fileCache.reduce((acc, { index }) => acc + index.size, 0);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -39,7 +44,7 @@
|
||||
|
||||
<div class="flex h-full flex-col">
|
||||
<TopBar title="캐시" />
|
||||
{#if fileCache}
|
||||
{#if fileCache && fileCache.length > 0}
|
||||
<div class="space-y-4 pb-4">
|
||||
<div class="space-y-1 break-keep text-gray-800">
|
||||
<p>
|
||||
@@ -56,7 +61,13 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-grow items-center justify-center">
|
||||
<p class="text-gray-500">캐시 목록을 불러오고 있어요.</p>
|
||||
<p class="text-gray-500">
|
||||
{#if fileCache}
|
||||
캐시된 파일이 없어요.
|
||||
{:else}
|
||||
캐시 목록을 불러오고 있어요.
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ import type {
|
||||
HmacSecretListResponse,
|
||||
DuplicateFileScanRequest,
|
||||
DuplicateFileScanResponse,
|
||||
DirectoryDeleteResponse,
|
||||
} from "$lib/server/schemas";
|
||||
import { hmacSecretStore, type MasterKey, type HmacSecret } from "$lib/stores";
|
||||
|
||||
@@ -191,6 +192,15 @@ export const requestDirectoryEntryRename = async (
|
||||
};
|
||||
|
||||
export const requestDirectoryEntryDeletion = async (entry: SelectedDirectoryEntry) => {
|
||||
await callPostApi(`/api/${entry.type}/${entry.id}/delete`);
|
||||
const res = await callPostApi(`/api/${entry.type}/${entry.id}/delete`);
|
||||
if (!res.ok) return false;
|
||||
|
||||
if (entry.type === "directory") {
|
||||
const { deletedFiles }: DirectoryDeleteResponse = await res.json();
|
||||
await Promise.all(deletedFiles.map(deleteFileCache));
|
||||
return true;
|
||||
} else {
|
||||
await deleteFileCache(entry.id);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { error, text } from "@sveltejs/kit";
|
||||
import { error, json } from "@sveltejs/kit";
|
||||
import { z } from "zod";
|
||||
import { authorize } from "$lib/server/modules/auth";
|
||||
import { directoryDeleteResponse, type DirectoryDeleteResponse } from "$lib/server/schemas";
|
||||
import { deleteDirectory } from "$lib/server/services/directory";
|
||||
import type { RequestHandler } from "./$types";
|
||||
|
||||
@@ -15,6 +16,8 @@ export const POST: RequestHandler = async ({ locals, params }) => {
|
||||
if (!zodRes.success) error(400, "Invalid path parameters");
|
||||
const { id } = zodRes.data;
|
||||
|
||||
await deleteDirectory(userId, id);
|
||||
return text("Directory deleted", { headers: { "Content-Type": "text/plain" } });
|
||||
const { files } = await deleteDirectory(userId, id);
|
||||
return json(
|
||||
directoryDeleteResponse.parse({ deletedFiles: files } satisfies DirectoryDeleteResponse),
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user