mirror of
https://github.com/hanzo-apps/dataroom.git
synced 2026-10-30 14:47:36 +00:00
`getS3ClientAndConfig` threw "Invalid upload transport" unless NEXT_PUBLIC_UPLOAD_TRANSPORT was "s3". The deployment does not set that variable — it configures storage through NEXT_PRIVATE_UPLOAD_* (transport s3, bucket dataroom, endpoint http://s3:9000, credentials) — so every call through that helper threw in production while a correctly configured bucket sat beside it. The two put paths keyed on the same unset variable and fell to `.otherwise()`, returning { type: null, data: null }: a server-side upload reported success and stored nothing. There is one object store now, so nothing chooses a transport. The VERCEL_BLOB arms are gone from get/put/copy/delete, CSV exports write through putFileServer, and branding + expired-export deletion go through deleteFile. Safe to remove rather than migrate: the database has no rows to orphan — Document, DocumentVersion, Team and User are all 0, so nothing is stored under a VERCEL_BLOB path. The cleanup queue now carries teamId, which deleteFile needs to resolve the storage region, and its item is a `path` rather than a `blobUrl` — the scheduler was testing `startsWith("https://")` to decide whether to enqueue, which a storage path never matches. Verified with npx tsc --noEmit: 100 -> 99. The one fixed is get-file.ts, whose ts-pattern match is no longer there to be uncallable. Nothing introduced: the two duplicate.ts files that looked new carry identical error counts before and after and were never touched. Co-authored-by: Hanzo Dev <[email protected]>
56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import { DeleteObjectsCommand, ListObjectsV2Command } from "@aws-sdk/client-s3";
|
|
|
|
import { getS3ClientAndConfig } from "./aws-client";
|
|
|
|
export type DeleteFilesOptions = {
|
|
teamId: string;
|
|
data?: string[]; // not needed for s3
|
|
};
|
|
|
|
export const deleteFiles = async ({ teamId, data }: DeleteFilesOptions) => {
|
|
// run both delete functions in parallel
|
|
await Promise.allSettled([
|
|
deleteAllFilesFromS3Server(teamId),
|
|
]);
|
|
};
|
|
|
|
|
|
const deleteAllFilesFromS3Server = async (teamId: string) => {
|
|
// the teamId is the first prefix in the folder path
|
|
const folderPath = teamId;
|
|
|
|
const { client, config } = getS3ClientAndConfig();
|
|
|
|
try {
|
|
// List all objects in the folder
|
|
const listParams = {
|
|
Bucket: config.bucket,
|
|
Prefix: `${folderPath}/`, // Ensure this ends with a slash if it's a folder
|
|
};
|
|
const listedObjects = await client.send(
|
|
new ListObjectsV2Command(listParams),
|
|
);
|
|
|
|
if (!listedObjects.Contents) return;
|
|
if (listedObjects.Contents.length === 0) return;
|
|
|
|
// Prepare delete parameters
|
|
const deleteParams = {
|
|
Bucket: config.bucket,
|
|
Delete: {
|
|
Objects: listedObjects.Contents.map((file) => ({ Key: file.Key })),
|
|
},
|
|
};
|
|
|
|
// Delete the objects
|
|
await client.send(new DeleteObjectsCommand(deleteParams));
|
|
|
|
if (listedObjects.IsTruncated) {
|
|
// If there are more files than returned in a single request, recurse
|
|
await deleteAllFilesFromS3Server(folderPath);
|
|
}
|
|
} catch (error) {
|
|
console.error("Error deleting files:", error);
|
|
}
|
|
};
|