mirror of
https://github.com/get-drexa/drive.git
synced 2025-11-30 21:41:39 +00:00
refactor: migrate to vite and restructure repo
Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
@@ -1,89 +1,24 @@
|
||||
import { v } from "convex/values"
|
||||
import type { Doc, Id } from "../_generated/dataModel"
|
||||
import type {
|
||||
AuthenticatedMutationCtx,
|
||||
AuthenticatedQueryCtx,
|
||||
import {
|
||||
type AuthenticatedMutationCtx,
|
||||
type AuthenticatedQueryCtx,
|
||||
authorizedGet,
|
||||
} from "../functions"
|
||||
import { authorizedGet } from "../functions"
|
||||
import * as Err from "../shared/error"
|
||||
import type {
|
||||
DirectoryHandle,
|
||||
FileHandle,
|
||||
FileSystemHandle,
|
||||
} from "../shared/filesystem"
|
||||
import {
|
||||
FileType,
|
||||
newDirectoryHandle,
|
||||
newFileHandle,
|
||||
} from "../shared/filesystem"
|
||||
import * as Directories from "./directories"
|
||||
import * as Err from "./error"
|
||||
import * as Files from "./files"
|
||||
|
||||
export enum FileType {
|
||||
File = "File",
|
||||
Directory = "Directory",
|
||||
}
|
||||
|
||||
export type Directory = {
|
||||
kind: FileType.Directory
|
||||
doc: Doc<"directories">
|
||||
}
|
||||
export type File = {
|
||||
kind: FileType.File
|
||||
doc: Doc<"files">
|
||||
}
|
||||
export type FileSystemItem = Directory | File
|
||||
|
||||
export type DirectoryPathComponent = {
|
||||
handle: DirectoryHandle
|
||||
name: string
|
||||
}
|
||||
|
||||
export type FilePathComponent = {
|
||||
handle: FileHandle
|
||||
name: string
|
||||
}
|
||||
export type PathComponent = FilePathComponent | DirectoryPathComponent
|
||||
export type DirectoryPath = [
|
||||
DirectoryPathComponent,
|
||||
...DirectoryPathComponent[],
|
||||
]
|
||||
export type FilePath = [...DirectoryPathComponent[], PathComponent]
|
||||
export type ReverseFilePath = [PathComponent, ...DirectoryPathComponent[]]
|
||||
|
||||
export type DirectoryHandle = {
|
||||
kind: FileType.Directory
|
||||
id: Id<"directories">
|
||||
}
|
||||
export type FileHandle = {
|
||||
kind: FileType.File
|
||||
id: Id<"files">
|
||||
}
|
||||
export type FileSystemHandle = DirectoryHandle | FileHandle
|
||||
|
||||
export type DeleteResult = {
|
||||
deleted: {
|
||||
files: number
|
||||
directories: number
|
||||
}
|
||||
errors: Err.ApplicationErrorData[]
|
||||
}
|
||||
|
||||
export function newFileSystemHandle(item: FileSystemItem): FileSystemHandle {
|
||||
console.log("item", item)
|
||||
switch (item.kind) {
|
||||
case FileType.File:
|
||||
return { kind: item.kind, id: item.doc._id }
|
||||
case FileType.Directory:
|
||||
return { kind: item.kind, id: item.doc._id }
|
||||
}
|
||||
}
|
||||
|
||||
export function isSameHandle(
|
||||
handle1: FileSystemHandle,
|
||||
handle2: FileSystemHandle,
|
||||
): boolean {
|
||||
return handle1.kind === handle2.kind && handle1.id === handle2.id
|
||||
}
|
||||
|
||||
export function newDirectoryHandle(id: Id<"directories">): DirectoryHandle {
|
||||
return { kind: FileType.Directory, id }
|
||||
}
|
||||
|
||||
export function newFileHandle(id: Id<"files">): FileHandle {
|
||||
return { kind: FileType.File, id }
|
||||
}
|
||||
|
||||
export const VDirectoryHandle = v.object({
|
||||
kind: v.literal(FileType.Directory),
|
||||
id: v.id("directories"),
|
||||
@@ -95,7 +30,7 @@ export const VFileHandle = v.object({
|
||||
export const VFileSystemHandle = v.union(VFileHandle, VDirectoryHandle)
|
||||
|
||||
export async function queryRootDirectory(
|
||||
ctx: AuthenticatedQueryCtx,
|
||||
ctx: AuthenticatedQueryCtx | AuthenticatedMutationCtx,
|
||||
): Promise<Doc<"directories"> | null> {
|
||||
return await ctx.db
|
||||
.query("directories")
|
||||
@@ -134,24 +69,19 @@ async function collectAllHandlesRecursively(
|
||||
const fileHandles: FileHandle[] = []
|
||||
const directoryHandles: DirectoryHandle[] = []
|
||||
|
||||
// Process each handle to collect files and directories
|
||||
for (const handle of handles) {
|
||||
// Use a queue to process items iteratively instead of recursively
|
||||
const queue: FileSystemHandle[] = [handle]
|
||||
|
||||
while (queue.length > 0) {
|
||||
const currentHandle = queue.shift()!
|
||||
|
||||
// Add current item to appropriate collection
|
||||
if (currentHandle.kind === FileType.File) {
|
||||
fileHandles.push(currentHandle)
|
||||
} else {
|
||||
directoryHandles.push(currentHandle)
|
||||
}
|
||||
|
||||
// If it's a directory, collect all children and add them to the queue
|
||||
if (currentHandle.kind === FileType.Directory) {
|
||||
// Get all child directories that are in trash (deletedAt >= 0)
|
||||
const childDirectories = await ctx.db
|
||||
.query("directories")
|
||||
.withIndex("byParentId", (q) =>
|
||||
@@ -162,7 +92,6 @@ async function collectAllHandlesRecursively(
|
||||
)
|
||||
.collect()
|
||||
|
||||
// Get all child files that are in trash (deletedAt >= 0)
|
||||
const childFiles = await ctx.db
|
||||
.query("files")
|
||||
.withIndex("byDirectoryId", (q) =>
|
||||
@@ -173,16 +102,12 @@ async function collectAllHandlesRecursively(
|
||||
)
|
||||
.collect()
|
||||
|
||||
// Add child directories to queue for processing
|
||||
for (const childDir of childDirectories) {
|
||||
const childHandle = newDirectoryHandle(childDir._id)
|
||||
queue.push(childHandle)
|
||||
queue.push(newDirectoryHandle(childDir._id))
|
||||
}
|
||||
|
||||
// Add child files to file handles collection
|
||||
for (const childFile of childFiles) {
|
||||
const childFileHandle = newFileHandle(childFile._id)
|
||||
fileHandles.push(childFileHandle)
|
||||
fileHandles.push(newFileHandle(childFile._id))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,17 +124,14 @@ export async function restoreItems(
|
||||
ctx: AuthenticatedMutationCtx,
|
||||
{ handles }: { handles: FileSystemHandle[] },
|
||||
) {
|
||||
// Collect all items to restore (including nested items)
|
||||
const { fileHandles, directoryHandles } =
|
||||
await collectAllHandlesRecursively(ctx, { handles })
|
||||
|
||||
// Restore files and directories by unsetting deletedAt
|
||||
const [filesResult, directoriesResult] = await Promise.all([
|
||||
Files.restore(ctx, { items: fileHandles }),
|
||||
Directories.restore(ctx, { items: directoryHandles }),
|
||||
])
|
||||
|
||||
// Combine results, handling null responses
|
||||
return {
|
||||
restored: {
|
||||
files: filesResult?.restored || 0,
|
||||
@@ -225,20 +147,15 @@ export async function restoreItems(
|
||||
export async function deleteItemsPermanently(
|
||||
ctx: AuthenticatedMutationCtx,
|
||||
{ handles }: { handles: FileSystemHandle[] },
|
||||
): Promise<DeleteResult> {
|
||||
// Collect all items to delete (including nested items)
|
||||
const {
|
||||
fileHandles: fileHandlesToDelete,
|
||||
directoryHandles: directoryHandlesToDelete,
|
||||
} = await collectAllHandlesRecursively(ctx, { handles })
|
||||
) {
|
||||
const { fileHandles, directoryHandles } =
|
||||
await collectAllHandlesRecursively(ctx, { handles })
|
||||
|
||||
// Delete files and directories using their respective models
|
||||
const [filesResult, directoriesResult] = await Promise.all([
|
||||
Files.deletePermanently(ctx, { items: fileHandlesToDelete }),
|
||||
Directories.deletePermanently(ctx, { items: directoryHandlesToDelete }),
|
||||
Files.deletePermanently(ctx, { items: fileHandles }),
|
||||
Directories.deletePermanently(ctx, { items: directoryHandles }),
|
||||
])
|
||||
|
||||
// Combine results, handling null responses
|
||||
return {
|
||||
deleted: {
|
||||
files: filesResult?.deleted || 0,
|
||||
@@ -251,9 +168,7 @@ export async function deleteItemsPermanently(
|
||||
}
|
||||
}
|
||||
|
||||
export async function emptyTrash(
|
||||
ctx: AuthenticatedMutationCtx,
|
||||
): Promise<DeleteResult> {
|
||||
export async function emptyTrash(ctx: AuthenticatedMutationCtx) {
|
||||
const rootDir = await queryRootDirectory(ctx)
|
||||
if (!rootDir) {
|
||||
throw Err.create(Err.Code.NotFound, "user root directory not found")
|
||||
|
||||
Reference in New Issue
Block a user