68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import { createAsset } from "@/lib/server/data-store";
|
|
import { jsonOk, readJsonBody } from "@/lib/server/api";
|
|
import { authenticatePublicApiRequest } from "@/lib/server/public-api-auth";
|
|
import { listPublicApiAssets } from "@/lib/server/public-api-assets";
|
|
import { publicApiError } from "@/lib/server/public-api-response";
|
|
import { DEFAULT_OWNER_ID, requestOrigin } from "@/lib/server/runtime";
|
|
import { saveUploadAsset } from "@/lib/server/storage";
|
|
import type { AssetKind } from "@/lib/types";
|
|
|
|
export const runtime = "nodejs";
|
|
|
|
export async function GET(request: Request) {
|
|
try {
|
|
const client = authenticatePublicApiRequest(request);
|
|
return jsonOk({ assets: await listPublicApiAssets(client.id) });
|
|
} catch (error) {
|
|
return publicApiError(error);
|
|
}
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const client = authenticatePublicApiRequest(request);
|
|
const contentType = request.headers.get("content-type") || "";
|
|
if (contentType.includes("multipart/form-data")) {
|
|
const form = await request.formData();
|
|
const files = form.getAll("files").filter((item): item is File => item instanceof File);
|
|
if (!files.length) throw new Error("No files uploaded.");
|
|
const assets = await Promise.all(files.map(async (file) => saveUploadAsset({
|
|
ownerId: DEFAULT_OWNER_ID,
|
|
bytes: await awaitFileBytes(file),
|
|
fileName: file.name,
|
|
contentType: file.type || "application/octet-stream",
|
|
origin: requestOrigin(request),
|
|
tags: ["upload", "public-api", `api-client:${client.id}`]
|
|
})));
|
|
return jsonOk({ assets }, { status: 201 });
|
|
}
|
|
|
|
const body = await readJsonBody<{
|
|
url?: string;
|
|
name?: string;
|
|
kind?: AssetKind;
|
|
tags?: string[];
|
|
}>(request);
|
|
if (!body.url) throw new Error("url is required");
|
|
const asset = await createAsset({
|
|
ownerId: DEFAULT_OWNER_ID,
|
|
kind: body.kind || "image",
|
|
name: body.name || "外部素材",
|
|
url: body.url,
|
|
source: "external",
|
|
tags: [...(body.tags || []), "external", "public-api", `api-client:${client.id}`],
|
|
metadata: {
|
|
registeredFrom: "public-api",
|
|
externalClientId: client.id
|
|
}
|
|
});
|
|
return jsonOk({ asset }, { status: 201 });
|
|
} catch (error) {
|
|
return publicApiError(error);
|
|
}
|
|
}
|
|
|
|
async function awaitFileBytes(file: File): Promise<Buffer> {
|
|
return Buffer.from(await file.arrayBuffer());
|
|
}
|