返回 presentation-ai
lib.ts
根目录 / src / app / api / uploadthing / lib.ts
1 import "server-only";
2
3 import { createUploadthing } from "uploadthing/next";
4 import { UploadThingError, UTApi } from "uploadthing/server";
5
6 import { auth } from "@/server/auth";
7
8 export const f = createUploadthing();
9 export const utapi = new UTApi();
10
11 export async function requireUploadThingUser(): Promise<{ userId: string }> {
12 const session = await auth();
13 if (!session) {
14 throw new UploadThingError("Unauthorized");
15 }
16
17 return { userId: session.user.id };
18 }
19
20 export async function requireAdminUploadThingUser(): Promise<{
21 userId: string;
22 }> {
23 const session = await auth();
24 if (!session?.user.isAdmin) {
25 throw new UploadThingError("Unauthorized");
26 }
27
28 return { userId: session.user.id };
29 }
30
31 function getUploadThingFileKeyFromUrl(url: string): string | null {
32 const trimmedUrl = url.trim();
33
34 if (trimmedUrl.length === 0) {
35 return null;
36 }
37
38 try {
39 const parsedUrl = new URL(trimmedUrl);
40 const pathnameParts = parsedUrl.pathname.split("/").filter(Boolean);
41 return pathnameParts.at(-1) ?? null;
42 } catch {
43 const pathnameParts = trimmedUrl.split("/").filter(Boolean);
44 return pathnameParts.at(-1) ?? null;
45 }
46 }
47
48 export async function deleteUploadThingFiles(
49 fileKeys: string | string[],
50 ): Promise<void> {
51 const normalizedKeys = [
52 ...new Set(
53 (Array.isArray(fileKeys) ? fileKeys : [fileKeys])
54 .map((fileKey) => fileKey.trim())
55 .filter((fileKey) => fileKey.length > 0),
56 ),
57 ];
58
59 if (normalizedKeys.length === 0) {
60 return;
61 }
62
63 await utapi.deleteFiles(normalizedKeys);
64 }
65
66 export async function deleteUploadThingFilesByUrls(
67 urls: string | string[],
68 ): Promise<void> {
69 const normalizedKeys = (Array.isArray(urls) ? urls : [urls])
70 .map(getUploadThingFileKeyFromUrl)
71 .filter((fileKey): fileKey is string => fileKey !== null);
72
73 await deleteUploadThingFiles(normalizedKeys);
74 }
75
75 lines TYPESCRIPT