{"version":3,"file":"index.mjs","names":[],"sources":["../../../../../../../src/astro/routes/api/media/providers/[providerId]/index.ts"],"sourcesContent":["/**\n * Media Provider List/Upload Endpoint\n *\n * GET /_emdash/api/media/providers/:providerId - List media from provider\n * POST /_emdash/api/media/providers/:providerId - Upload to provider\n */\n\nimport type { APIRoute } from \"astro\";\n\nimport { requirePerm } from \"#api/authorize.js\";\nimport { apiError, apiSuccess, handleError } from \"#api/error.js\";\n\nexport const prerender = false;\n\n/**\n * List media from a specific provider\n */\nexport const GET: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { providerId } = params;\n\n\tconst readDenied = requirePerm(user, \"media:read\");\n\tif (readDenied) return readDenied;\n\n\tif (!providerId) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Provider ID required\", 400);\n\t}\n\n\tif (!emdash?.getMediaProvider) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst provider = emdash.getMediaProvider(providerId);\n\tif (!provider) {\n\t\treturn apiError(\"NOT_FOUND\", `Provider \"${providerId}\" not found`, 404);\n\t}\n\n\tconst url = new URL(request.url);\n\tconst cursor = url.searchParams.get(\"cursor\") || undefined;\n\tconst rawLimit = url.searchParams.get(\"limit\");\n\tconst limit = rawLimit ? Math.max(1, Math.min(parseInt(rawLimit, 10) || 50, 100)) : undefined;\n\tconst query = url.searchParams.get(\"query\") || undefined;\n\tconst mimeType = url.searchParams.get(\"mimeType\") || undefined;\n\n\ttry {\n\t\tconst result = await provider.list({\n\t\t\tcursor,\n\t\t\tlimit,\n\t\t\tquery,\n\t\t\tmimeType,\n\t\t});\n\n\t\treturn apiSuccess({\n\t\t\titems: result.items,\n\t\t\tnextCursor: result.nextCursor,\n\t\t});\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to list media from provider\", \"PROVIDER_LIST_ERROR\");\n\t}\n};\n\n/**\n * Upload media to a specific provider\n */\nexport const POST: APIRoute = async ({ params, request, locals }) => {\n\tconst { emdash, user } = locals;\n\tconst { providerId } = params;\n\n\tconst uploadDenied = requirePerm(user, \"media:upload\");\n\tif (uploadDenied) return uploadDenied;\n\n\tif (!providerId) {\n\t\treturn apiError(\"INVALID_REQUEST\", \"Provider ID required\", 400);\n\t}\n\n\tif (!emdash?.getMediaProvider) {\n\t\treturn apiError(\"NOT_CONFIGURED\", \"EmDash is not initialized\", 500);\n\t}\n\n\tconst provider = emdash.getMediaProvider(providerId);\n\tif (!provider) {\n\t\treturn apiError(\"NOT_FOUND\", `Provider \"${providerId}\" not found`, 404);\n\t}\n\n\tif (!provider.upload) {\n\t\treturn apiError(\"NOT_SUPPORTED\", `Provider \"${providerId}\" does not support uploads`, 400);\n\t}\n\n\ttry {\n\t\tconst formData = await request.formData();\n\t\tconst fileEntry = formData.get(\"file\");\n\t\tconst file = fileEntry instanceof File ? fileEntry : null;\n\t\tconst altEntry = formData.get(\"alt\");\n\t\tconst alt = typeof altEntry === \"string\" ? altEntry : null;\n\n\t\tif (!file) {\n\t\t\treturn apiError(\"NO_FILE\", \"No file provided\", 400);\n\t\t}\n\n\t\t// Basic size validation (default 50MB, configurable via maxUploadSize)\n\t\tconst maxSize = emdash.config?.maxUploadSize ?? 50 * 1024 * 1024;\n\t\tif (file.size > maxSize) {\n\t\t\treturn apiError(\n\t\t\t\t\"FILE_TOO_LARGE\",\n\t\t\t\t`File exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`,\n\t\t\t\t413,\n\t\t\t);\n\t\t}\n\n\t\tconst item = await provider.upload({\n\t\t\tfile,\n\t\t\tfilename: file.name,\n\t\t\talt: alt || undefined,\n\t\t});\n\n\t\treturn apiSuccess({ item }, 201);\n\t} catch (error) {\n\t\treturn handleError(error, \"Failed to upload to provider\", \"PROVIDER_UPLOAD_ERROR\");\n\t}\n};\n"],"mappings":";;;;;;AAYA,MAAa,YAAY;;;;AAKzB,MAAa,MAAgB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACnE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,eAAe;CAEvB,MAAM,aAAa,YAAY,MAAM,aAAa;AAClD,KAAI,WAAY,QAAO;AAEvB,KAAI,CAAC,WACJ,QAAO,SAAS,mBAAmB,wBAAwB,IAAI;AAGhE,KAAI,CAAC,QAAQ,iBACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,WAAW,OAAO,iBAAiB,WAAW;AACpD,KAAI,CAAC,SACJ,QAAO,SAAS,aAAa,aAAa,WAAW,cAAc,IAAI;CAGxE,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,MAAM,SAAS,IAAI,aAAa,IAAI,SAAS,IAAI;CACjD,MAAM,WAAW,IAAI,aAAa,IAAI,QAAQ;CAC9C,MAAM,QAAQ,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,UAAU,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG;CACpF,MAAM,QAAQ,IAAI,aAAa,IAAI,QAAQ,IAAI;CAC/C,MAAM,WAAW,IAAI,aAAa,IAAI,WAAW,IAAI;AAErD,KAAI;EACH,MAAM,SAAS,MAAM,SAAS,KAAK;GAClC;GACA;GACA;GACA;GACA,CAAC;AAEF,SAAO,WAAW;GACjB,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,CAAC;UACM,OAAO;AACf,SAAO,YAAY,OAAO,sCAAsC,sBAAsB;;;;;;AAOxF,MAAa,OAAiB,OAAO,EAAE,QAAQ,SAAS,aAAa;CACpE,MAAM,EAAE,QAAQ,SAAS;CACzB,MAAM,EAAE,eAAe;CAEvB,MAAM,eAAe,YAAY,MAAM,eAAe;AACtD,KAAI,aAAc,QAAO;AAEzB,KAAI,CAAC,WACJ,QAAO,SAAS,mBAAmB,wBAAwB,IAAI;AAGhE,KAAI,CAAC,QAAQ,iBACZ,QAAO,SAAS,kBAAkB,6BAA6B,IAAI;CAGpE,MAAM,WAAW,OAAO,iBAAiB,WAAW;AACpD,KAAI,CAAC,SACJ,QAAO,SAAS,aAAa,aAAa,WAAW,cAAc,IAAI;AAGxE,KAAI,CAAC,SAAS,OACb,QAAO,SAAS,iBAAiB,aAAa,WAAW,6BAA6B,IAAI;AAG3F,KAAI;EACH,MAAM,WAAW,MAAM,QAAQ,UAAU;EACzC,MAAM,YAAY,SAAS,IAAI,OAAO;EACtC,MAAM,OAAO,qBAAqB,OAAO,YAAY;EACrD,MAAM,WAAW,SAAS,IAAI,MAAM;EACpC,MAAM,MAAM,OAAO,aAAa,WAAW,WAAW;AAEtD,MAAI,CAAC,KACJ,QAAO,SAAS,WAAW,oBAAoB,IAAI;EAIpD,MAAM,UAAU,OAAO,QAAQ,iBAAiB,KAAK,OAAO;AAC5D,MAAI,KAAK,OAAO,QACf,QAAO,SACN,kBACA,gCAAgC,KAAK,MAAM,UAAU,OAAO,KAAK,CAAC,KAClE,IACA;AASF,SAAO,WAAW,EAAE,MANP,MAAM,SAAS,OAAO;GAClC;GACA,UAAU,KAAK;GACf,KAAK,OAAO;GACZ,CAAC,EAEwB,EAAE,IAAI;UACxB,OAAO;AACf,SAAO,YAAY,OAAO,gCAAgC,wBAAwB"}