Files
klz-cables.com/.pnpm-store/v10/files/40/888cb29c22409ee8252262c8dfc288e8dacc1f47ccdef882431579642a96e20626ad1a70ad59600df1157275d10c2c64147f7cd9ee58828e3acde50bd34c86
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

1 line
8.8 KiB
Plaintext

{"version":3,"sources":["../../../src/uploads/endpoints/getFile.ts"],"sourcesContent":["import type { Stats } from 'fs'\n\nimport { fileTypeFromFile } from 'file-type'\nimport fsPromises from 'fs/promises'\nimport { status as httpStatus } from 'http-status'\nimport path from 'path'\n\nimport type { PayloadHandler } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { checkFileAccess } from '../../uploads/checkFileAccess.js'\nimport { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'\nimport { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'\nimport { parseRangeHeader } from '../../uploads/parseRangeHeader.js'\nimport { getRequestCollection } from '../../utilities/getRequestEntity.js'\nimport { headersWithCors } from '../../utilities/headersWithCors.js'\n\nexport const getFileHandler: PayloadHandler = async (req) => {\n const collection = getRequestCollection(req)\n\n const filename = req.routeParams?.filename as string\n\n if (!collection.config.upload) {\n throw new APIError(\n `This collection is not an upload collection: ${collection.config.slug}`,\n httpStatus.BAD_REQUEST,\n )\n }\n\n const accessResult = (await checkFileAccess({\n collection,\n filename,\n req,\n }))!\n\n if (accessResult instanceof Response) {\n return accessResult\n }\n\n if (collection.config.upload.handlers?.length) {\n let customResponse: null | Response | void = null\n const headers = new Headers()\n\n for (const handler of collection.config.upload.handlers) {\n customResponse = await handler(req, {\n doc: accessResult,\n headers,\n params: {\n collection: collection.config.slug,\n filename,\n },\n })\n if (customResponse && customResponse instanceof Response) {\n break\n }\n }\n\n if (customResponse instanceof Response) {\n return customResponse\n }\n }\n\n const fileDir = collection.config.upload?.staticDir || collection.config.slug\n const filePath = path.resolve(`${fileDir}/${filename}`)\n let stats: Stats\n\n try {\n stats = await fsPromises.stat(filePath)\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n req.payload.logger.error(\n `File ${filename} for collection ${collection.config.slug} is missing on the disk. Expected path: ${filePath}`,\n )\n\n // Omit going to the routeError handler by returning response instead of\n // throwing an error to cut down log noise. The response still matches what you get with APIError to not leak details to the user.\n return Response.json(\n {\n errors: [\n {\n message: 'Something went wrong.',\n },\n ],\n },\n {\n headers: headersWithCors({\n headers: new Headers(),\n req,\n }),\n status: 500,\n },\n )\n }\n\n throw err\n }\n\n const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)\n let mimeType = fileTypeResult.mime\n\n if (filePath.endsWith('.svg') && fileTypeResult.mime === 'application/xml') {\n mimeType = 'image/svg+xml'\n }\n\n // Parse Range header for byte range requests\n const rangeHeader = req.headers.get('range')\n const rangeResult = parseRangeHeader({\n fileSize: stats.size,\n rangeHeader,\n })\n\n if (rangeResult.type === 'invalid') {\n let headers = new Headers()\n headers.set('Content-Range', `bytes */${stats.size}`)\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(null, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status: httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,\n })\n }\n\n let headers = new Headers()\n headers.set('Content-Type', mimeType)\n headers.set('Accept-Ranges', 'bytes')\n\n if (mimeType === 'image/svg+xml') {\n headers.set('Content-Security-Policy', \"script-src 'none'\")\n }\n\n let data: ReadableStream\n let status: number\n const isPartial = rangeResult.type === 'partial'\n const range = rangeResult.range\n\n if (isPartial && range) {\n const contentLength = range.end - range.start + 1\n headers.set('Content-Length', String(contentLength))\n headers.set('Content-Range', `bytes ${range.start}-${range.end}/${stats.size}`)\n data = streamFile({ filePath, options: { end: range.end, start: range.start } })\n status = httpStatus.PARTIAL_CONTENT\n } else {\n headers.set('Content-Length', String(stats.size))\n data = streamFile({ filePath })\n status = httpStatus.OK\n }\n\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(data, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status,\n })\n}\n"],"names":["fileTypeFromFile","fsPromises","status","httpStatus","path","APIError","checkFileAccess","streamFile","getFileTypeFallback","parseRangeHeader","getRequestCollection","headersWithCors","getFileHandler","req","collection","filename","routeParams","config","upload","slug","BAD_REQUEST","accessResult","Response","handlers","length","customResponse","headers","Headers","handler","doc","params","fileDir","staticDir","filePath","resolve","stats","stat","err","code","payload","logger","error","json","errors","message","fileTypeResult","mimeType","mime","endsWith","rangeHeader","get","rangeResult","fileSize","size","type","set","modifyResponseHeaders","REQUESTED_RANGE_NOT_SATISFIABLE","data","isPartial","range","contentLength","end","start","String","options","PARTIAL_CONTENT","OK"],"mappings":"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"}