102 lines
2.6 KiB
TypeScript
102 lines
2.6 KiB
TypeScript
import type { App } from "@/routes/app";
|
|
import { authError } from "@/routes/authError";
|
|
import { getFileDownloadUrl } from "@/server/getFileDownloadUrl";
|
|
import { handleResourceUpload } from "@/server/resource";
|
|
import { z, createRoute } from "@hono/zod-openapi";
|
|
import { newId } from "./newId";
|
|
|
|
const uploadUrlRoute = createRoute({
|
|
method: "get",
|
|
path: "/upload-url",
|
|
tags: ["files"],
|
|
summary: "Upload any files to the storage",
|
|
description:
|
|
"Usually when you run something, you want to upload a file, image etc.",
|
|
request: {
|
|
query: z.object({
|
|
type: z.enum(["image/png", "image/jpg", "image/jpeg"]),
|
|
file_size: z
|
|
.string()
|
|
.refine((value) => !isNaN(Number(value)), {
|
|
message: "file_size must be a number",
|
|
path: ["file_size"],
|
|
})
|
|
.refine((value) => Number(value) > 0, {
|
|
message: "file_size cannot be less than or equal to 0",
|
|
path: ["file_size"],
|
|
})
|
|
.transform((v) => parseFloat(v)),
|
|
}),
|
|
},
|
|
responses: {
|
|
200: {
|
|
content: {
|
|
"application/json": {
|
|
schema: z.object({
|
|
upload_url: z.string(),
|
|
file_id: z.string(),
|
|
download_url: z.string(),
|
|
}),
|
|
},
|
|
},
|
|
description: "Retrieve the output",
|
|
},
|
|
500: {
|
|
content: {
|
|
"application/json": {
|
|
schema: z.object({
|
|
error: z.string(),
|
|
}),
|
|
},
|
|
},
|
|
description: "Error when generating upload url",
|
|
},
|
|
...authError,
|
|
},
|
|
});
|
|
|
|
export const registerUploadRoute = (app: App) => {
|
|
app.openapi(uploadUrlRoute, async (c) => {
|
|
const data = c.req.valid("query");
|
|
|
|
const sizeLimit = 50;
|
|
|
|
try {
|
|
if (data.file_size > sizeLimit * 1024 * 1024) {
|
|
// Check if the file size is greater than 50MB
|
|
throw new Error(`File size exceeds ${sizeLimit}MB limit`);
|
|
}
|
|
|
|
const id = newId("img");
|
|
const filePath = `inputs/${id}.${data.type.split("/")[1]}`;
|
|
|
|
const uploadUrl = await handleResourceUpload({
|
|
resourceBucket: process.env.SPACES_BUCKET,
|
|
resourceId: filePath,
|
|
resourceType: data.type,
|
|
isPublic: true,
|
|
});
|
|
|
|
return c.json(
|
|
{
|
|
upload_url: uploadUrl,
|
|
file_id: id,
|
|
download_url: await getFileDownloadUrl(filePath),
|
|
},
|
|
200,
|
|
);
|
|
} catch (error: unknown) {
|
|
const errorMessage =
|
|
error instanceof Error ? error.message : "Unknown error";
|
|
return c.json(
|
|
{
|
|
error: errorMessage,
|
|
},
|
|
{
|
|
status: 500,
|
|
},
|
|
);
|
|
}
|
|
});
|
|
};
|