{"version":3,"file":"tusPostProcessorHandler.mjs","names":[],"sources":["../../src/endpoints/tusPostProcessorHandler.ts"],"sourcesContent":["import type { PayloadHandler } from 'payload'\nimport { useErrorHandler } from '../hooks/useErrorHandler'\nimport { MediaCloudErrors } from '../types/errors'\n\nimport { S3Store } from '../tus/stores/s3/s3Store'\nimport { imageSize } from 'image-size'\nimport { sanitizeFilename } from '../utils/file'\n\ninterface GetTusPostProcessorHandlerArgs {\n  getS3Store: () => S3Store\n  collection: string\n}\n\nexport function getTusPostProcessorHandler(\n  args: GetTusPostProcessorHandlerArgs\n): PayloadHandler {\n  const { getS3Store, collection } = args\n  const { throwError, logError } = useErrorHandler()\n\n  return async function (req) {\n    try {\n      const { routeParams, payload } = req\n      const filename = routeParams?.filename as string\n\n      if (!filename) {\n        throwError(MediaCloudErrors.FILE_MISSING_NAME)\n      }\n\n      const sanitizedFilename = sanitizeFilename(filename)\n\n      const { docs } = await payload.find({\n        collection,\n        where: {\n          filename: {\n            equals: sanitizedFilename,\n          },\n        },\n        limit: 1,\n        pagination: false,\n      })\n\n      const media = docs?.[0]\n\n      if (!media) {\n        throwError(MediaCloudErrors.FILE_NOT_FOUND)\n      }\n\n      if (media.storage !== 's3') {\n        return Response.json(\n          { message: 'Asset not stored on S3, skipping …' },\n          { status: 200 }\n        )\n      }\n\n      const s3Store = getS3Store()\n      const matchedId = media?.id\n\n      const Key = media.path ?? media.filename ?? ''\n      const Bucket = s3Store.bucket\n      const Range = 'bytes=0-524288' // ONLY fetch the first 512KB\n\n      const { Body } = await s3Store.client.getObject({\n        Key,\n        Bucket,\n        Range,\n      })\n\n      if (!Body) {\n        logError(MediaCloudErrors.FILE_DIMENSIONS_ERROR.message)\n        return Response.json(\n          { message: 'Failed to process asset' },\n          { status: 500 }\n        )\n      }\n\n      const byteArray = await Body.transformToByteArray()\n      const buffer = Buffer.from(byteArray)\n\n      const dimensions = imageSize(buffer)\n      const { width, height } = dimensions\n\n      if (width && height) {\n        await payload.update({\n          collection,\n          id: matchedId,\n          data: {\n            width,\n            height,\n          },\n        })\n      }\n\n      return Response.json({ message: 'Asset processed' }, { status: 200 })\n    } catch (_error) {\n      logError(MediaCloudErrors.FILE_DIMENSIONS_ERROR.message)\n      return Response.json(\n        { message: 'Failed to process asset' },\n        { status: 500 }\n      )\n    }\n  }\n}\n"],"mappings":";;;;;;AAaA,SAAgB,2BACd,MACgB;CAChB,MAAM,EAAE,YAAY,eAAe;CACnC,MAAM,EAAE,YAAY,aAAa,iBAAiB;AAElD,QAAO,eAAgB,KAAK;AAC1B,MAAI;GACF,MAAM,EAAE,aAAa,YAAY;GACjC,MAAM,WAAW,aAAa;AAE9B,OAAI,CAAC,SACH,YAAW,iBAAiB,kBAAkB;GAGhD,MAAM,oBAAoB,iBAAiB,SAAS;GAEpD,MAAM,EAAE,SAAS,MAAM,QAAQ,KAAK;IAClC;IACA,OAAO,EACL,UAAU,EACR,QAAQ,mBACT,EACF;IACD,OAAO;IACP,YAAY;IACb,CAAC;GAEF,MAAM,QAAQ,OAAO;AAErB,OAAI,CAAC,MACH,YAAW,iBAAiB,eAAe;AAG7C,OAAI,MAAM,YAAY,KACpB,QAAO,SAAS,KACd,EAAE,SAAS,sCAAsC,EACjD,EAAE,QAAQ,KAAK,CAChB;GAGH,MAAM,UAAU,YAAY;GAC5B,MAAM,YAAY,OAAO;GAEzB,MAAM,MAAM,MAAM,QAAQ,MAAM,YAAY;GAC5C,MAAM,SAAS,QAAQ;GAGvB,MAAM,EAAE,SAAS,MAAM,QAAQ,OAAO,UAAU;IAC9C;IACA;IACA,OALY;IAMb,CAAC;AAEF,OAAI,CAAC,MAAM;AACT,aAAS,iBAAiB,sBAAsB,QAAQ;AACxD,WAAO,SAAS,KACd,EAAE,SAAS,2BAA2B,EACtC,EAAE,QAAQ,KAAK,CAChB;;GAGH,MAAM,YAAY,MAAM,KAAK,sBAAsB;GAInD,MAAM,EAAE,OAAO,WADI,UAFJ,OAAO,KAAK,UAAU,CAED;AAGpC,OAAI,SAAS,OACX,OAAM,QAAQ,OAAO;IACnB;IACA,IAAI;IACJ,MAAM;KACJ;KACA;KACD;IACF,CAAC;AAGJ,UAAO,SAAS,KAAK,EAAE,SAAS,mBAAmB,EAAE,EAAE,QAAQ,KAAK,CAAC;WAC9D,QAAQ;AACf,YAAS,iBAAiB,sBAAsB,QAAQ;AACxD,UAAO,SAAS,KACd,EAAE,SAAS,2BAA2B,EACtC,EAAE,QAAQ,KAAK,CAChB"}