import { v } from "convex/values" import { authenticatedMutation, authenticatedQuery } from "./functions" import * as Directories from "./model/directories" import * as Err from "./model/error" import * as Files from "./model/files" import type { DirectoryHandle, FileHandle, FileSystemItem, } from "./model/filesystem" import { type FileSystemHandle, FileType, VDirectoryHandle, VFileSystemHandle, } from "./model/filesystem" export const moveItems = authenticatedMutation({ args: { targetDirectory: VDirectoryHandle, items: v.array(VFileSystemHandle), }, handler: async (ctx, { targetDirectory: targetDirectoryHandle, items }) => { const targetDirectory = await Directories.fetchHandle( ctx, targetDirectoryHandle, ) if (!targetDirectory) { throw Err.create( Err.Code.DirectoryNotFound, `Directory ${targetDirectoryHandle.id} not found`, ) } const directoryHandles: DirectoryHandle[] = [] const fileHandles: FileHandle[] = [] for (const item of items) { switch (item.kind) { case FileType.Directory: directoryHandles.push(item) break case FileType.File: fileHandles.push(item) break } } const [fileMoveResult, directoryMoveResult] = await Promise.all([ Files.move(ctx, { targetDirectory: targetDirectoryHandle, items: fileHandles, }), Directories.move(ctx, { targetDirectory: targetDirectoryHandle, sourceDirectories: directoryHandles, }), ]) return { moved: [...directoryMoveResult.moved, ...fileMoveResult.moved], errors: [...fileMoveResult.errors, ...directoryMoveResult.errors], } }, }) export const moveToTrash = authenticatedMutation({ args: { handles: v.array(VFileSystemHandle), }, handler: async (ctx, { handles }) => { // biome-ignore lint/suspicious/useIterableCallbackReturn: switch statement is exhaustive const promises = handles.map((handle) => { switch (handle.kind) { case FileType.File: return ctx.db .patch(handle.id, { deletedAt: Date.now(), }) .then(() => handle) case FileType.Directory: return Directories.moveToTrashRecursive(ctx, handle).then( () => handle, ) } }) const results = await Promise.allSettled(promises) const errors: Err.ApplicationErrorData[] = [] const okHandles: FileSystemHandle[] = [] for (const result of results) { switch (result.status) { case "fulfilled": okHandles.push(result.value) break case "rejected": errors.push(Err.createJson(Err.Code.Internal)) break } } return { deleted: okHandles, errors, } }, }) export const fetchDirectoryContent = authenticatedQuery({ args: { directoryId: v.optional(v.id("directories")), trashed: v.boolean(), }, handler: async ( ctx, { directoryId, trashed }, ): Promise => { return await Directories.fetchContent(ctx, { directoryId, trashed }) }, })