@payloadcms/payload-cloud 3.8.0 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"staticHandler.d.ts","sourceRoot":"","sources":["../src/staticHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAA2B,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAKvF,UAAU,IAAI;IACZ,cAAc,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;IAC/C,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAWD,eAAO,MAAM,gBAAgB,mCAAoC,IAAI,KAAG,aA2DvE,CAAA"}
1
+ {"version":3,"file":"staticHandler.d.ts","sourceRoot":"","sources":["../src/staticHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAA2B,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAKvF,UAAU,IAAI;IACZ,cAAc,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;IAC/C,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAWD,eAAO,MAAM,gBAAgB,mCAAoC,IAAI,KAAG,aAgFvE,CAAA"}
@@ -52,6 +52,22 @@ export const getStaticHandler = ({ cachingOptions, collection })=>{
52
52
  status: 200
53
53
  });
54
54
  } catch (err) {
55
+ /**
56
+ * If object key does not found, the getObject function attempts a ListBucket operation.
57
+ * Because of permissions, this will throw very specific error that we can catch and handle.
58
+ */ if (err instanceof Error && err.name === 'AccessDenied' && err.message?.includes('s3:ListBucket') && 'type' in err && err.type === 'S3ServiceException') {
59
+ req.payload.logger.error({
60
+ collectionSlug: collection.slug,
61
+ err,
62
+ msg: `Requested file not found in cloud storage: ${params.filename}`,
63
+ params,
64
+ requestedKey: key
65
+ });
66
+ return new Response(null, {
67
+ status: 404,
68
+ statusText: 'Not Found'
69
+ });
70
+ }
55
71
  req.payload.logger.error({
56
72
  collectionSlug: collection.slug,
57
73
  err,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/staticHandler.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { CollectionCachingConfig, PluginOptions, StaticHandler } from './types.js'\n\nimport { createKey } from './utilities/createKey.js'\nimport { getStorageClient } from './utilities/getStorageClient.js'\n\ninterface Args {\n cachingOptions?: PluginOptions['uploadCaching']\n collection: CollectionConfig\n}\n\n// Convert a stream into a promise that resolves with a Buffer\nconst streamToBuffer = async (readableStream) => {\n const chunks = []\n for await (const chunk of readableStream) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nexport const getStaticHandler = ({ cachingOptions, collection }: Args): StaticHandler => {\n let maxAge = 86400 // 24 hours default\n let collCacheConfig: CollectionCachingConfig | undefined\n if (cachingOptions !== false) {\n // Set custom maxAge for all collections\n maxAge = cachingOptions?.maxAge || maxAge\n collCacheConfig = cachingOptions?.collections?.[collection.slug] || {}\n }\n\n // Set maxAge using collection-specific override\n maxAge = collCacheConfig?.maxAge || maxAge\n\n const cachingEnabled =\n cachingOptions !== false &&\n !!process.env.PAYLOAD_CLOUD_CACHE_KEY &&\n collCacheConfig?.enabled !== false\n\n return async (req, { params }) => {\n let key = ''\n try {\n const { identityID, storageClient } = await getStorageClient()\n\n key = createKey({\n collection: collection.slug,\n filename: params.filename,\n identityID,\n })\n\n const object = await storageClient.getObject({\n Bucket: process.env.PAYLOAD_CLOUD_BUCKET,\n Key: key,\n })\n\n if (!object.Body) {\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n\n const bodyBuffer = await streamToBuffer(object.Body)\n\n return new Response(bodyBuffer, {\n headers: new Headers({\n 'Content-Length': String(object.ContentLength),\n 'Content-Type': object.ContentType,\n ...(cachingEnabled && { 'Cache-Control': `public, max-age=${maxAge}` }),\n ETag: object.ETag,\n }),\n status: 200,\n })\n } catch (err: unknown) {\n req.payload.logger.error({\n collectionSlug: collection.slug,\n err,\n msg: `Error getting file from cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response('Internal Server Error', { status: 500 })\n }\n }\n}\n"],"names":["createKey","getStorageClient","streamToBuffer","readableStream","chunks","chunk","push","Buffer","from","concat","getStaticHandler","cachingOptions","collection","maxAge","collCacheConfig","collections","slug","cachingEnabled","process","env","PAYLOAD_CLOUD_CACHE_KEY","enabled","req","params","key","identityID","storageClient","filename","object","getObject","Bucket","PAYLOAD_CLOUD_BUCKET","Key","Body","Response","status","statusText","bodyBuffer","headers","Headers","String","ContentLength","ContentType","ETag","err","payload","logger","error","collectionSlug","msg","requestedKey"],"mappings":"AAIA,SAASA,SAAS,QAAQ,2BAA0B;AACpD,SAASC,gBAAgB,QAAQ,kCAAiC;AAOlE,8DAA8D;AAC9D,MAAMC,iBAAiB,OAAOC;IAC5B,MAAMC,SAAS,EAAE;IACjB,WAAW,MAAMC,SAASF,eAAgB;QACxCC,OAAOE,IAAI,CAAC,OAAOD,UAAU,WAAWE,OAAOC,IAAI,CAACH,SAASA;IAC/D;IACA,OAAOE,OAAOE,MAAM,CAACL;AACvB;AAEA,OAAO,MAAMM,mBAAmB,CAAC,EAAEC,cAAc,EAAEC,UAAU,EAAQ;IACnE,IAAIC,SAAS,MAAM,mBAAmB;;IACtC,IAAIC;IACJ,IAAIH,mBAAmB,OAAO;QAC5B,wCAAwC;QACxCE,SAASF,gBAAgBE,UAAUA;QACnCC,kBAAkBH,gBAAgBI,aAAa,CAACH,WAAWI,IAAI,CAAC,IAAI,CAAC;IACvE;IAEA,gDAAgD;IAChDH,SAASC,iBAAiBD,UAAUA;IAEpC,MAAMI,iBACJN,mBAAmB,SACnB,CAAC,CAACO,QAAQC,GAAG,CAACC,uBAAuB,IACrCN,iBAAiBO,YAAY;IAE/B,OAAO,OAAOC,KAAK,EAAEC,MAAM,EAAE;QAC3B,IAAIC,MAAM;QACV,IAAI;YACF,MAAM,EAAEC,UAAU,EAAEC,aAAa,EAAE,GAAG,MAAMzB;YAE5CuB,MAAMxB,UAAU;gBACdY,YAAYA,WAAWI,IAAI;gBAC3BW,UAAUJ,OAAOI,QAAQ;gBACzBF;YACF;YAEA,MAAMG,SAAS,MAAMF,cAAcG,SAAS,CAAC;gBAC3CC,QAAQZ,QAAQC,GAAG,CAACY,oBAAoB;gBACxCC,KAAKR;YACP;YAEA,IAAI,CAACI,OAAOK,IAAI,EAAE;gBAChB,OAAO,IAAIC,SAAS,MAAM;oBAAEC,QAAQ;oBAAKC,YAAY;gBAAY;YACnE;YAEA,MAAMC,aAAa,MAAMnC,eAAe0B,OAAOK,IAAI;YAEnD,OAAO,IAAIC,SAASG,YAAY;gBAC9BC,SAAS,IAAIC,QAAQ;oBACnB,kBAAkBC,OAAOZ,OAAOa,aAAa;oBAC7C,gBAAgBb,OAAOc,WAAW;oBAClC,GAAIzB,kBAAkB;wBAAE,iBAAiB,CAAC,gBAAgB,EAAEJ,QAAQ;oBAAC,CAAC;oBACtE8B,MAAMf,OAAOe,IAAI;gBACnB;gBACAR,QAAQ;YACV;QACF,EAAE,OAAOS,KAAc;YACrBtB,IAAIuB,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBACvBC,gBAAgBpC,WAAWI,IAAI;gBAC/B4B;gBACAK,KAAK,CAAC,uCAAuC,EAAE1B,OAAOI,QAAQ,EAAE;gBAChEJ;gBACA2B,cAAc1B;YAChB;YACA,OAAO,IAAIU,SAAS,yBAAyB;gBAAEC,QAAQ;YAAI;QAC7D;IACF;AACF,EAAC"}
1
+ {"version":3,"sources":["../src/staticHandler.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nimport type { CollectionCachingConfig, PluginOptions, StaticHandler } from './types.js'\n\nimport { createKey } from './utilities/createKey.js'\nimport { getStorageClient } from './utilities/getStorageClient.js'\n\ninterface Args {\n cachingOptions?: PluginOptions['uploadCaching']\n collection: CollectionConfig\n}\n\n// Convert a stream into a promise that resolves with a Buffer\nconst streamToBuffer = async (readableStream) => {\n const chunks = []\n for await (const chunk of readableStream) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nexport const getStaticHandler = ({ cachingOptions, collection }: Args): StaticHandler => {\n let maxAge = 86400 // 24 hours default\n let collCacheConfig: CollectionCachingConfig | undefined\n if (cachingOptions !== false) {\n // Set custom maxAge for all collections\n maxAge = cachingOptions?.maxAge || maxAge\n collCacheConfig = cachingOptions?.collections?.[collection.slug] || {}\n }\n\n // Set maxAge using collection-specific override\n maxAge = collCacheConfig?.maxAge || maxAge\n\n const cachingEnabled =\n cachingOptions !== false &&\n !!process.env.PAYLOAD_CLOUD_CACHE_KEY &&\n collCacheConfig?.enabled !== false\n\n return async (req, { params }) => {\n let key = ''\n try {\n const { identityID, storageClient } = await getStorageClient()\n\n key = createKey({\n collection: collection.slug,\n filename: params.filename,\n identityID,\n })\n\n const object = await storageClient.getObject({\n Bucket: process.env.PAYLOAD_CLOUD_BUCKET,\n Key: key,\n })\n\n if (!object.Body) {\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n\n const bodyBuffer = await streamToBuffer(object.Body)\n\n return new Response(bodyBuffer, {\n headers: new Headers({\n 'Content-Length': String(object.ContentLength),\n 'Content-Type': object.ContentType,\n ...(cachingEnabled && { 'Cache-Control': `public, max-age=${maxAge}` }),\n ETag: object.ETag,\n }),\n status: 200,\n })\n } catch (err: unknown) {\n /**\n * If object key does not found, the getObject function attempts a ListBucket operation.\n * Because of permissions, this will throw very specific error that we can catch and handle.\n */\n if (\n err instanceof Error &&\n err.name === 'AccessDenied' &&\n err.message?.includes('s3:ListBucket') &&\n 'type' in err &&\n err.type === 'S3ServiceException'\n ) {\n req.payload.logger.error({\n collectionSlug: collection.slug,\n err,\n msg: `Requested file not found in cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n\n req.payload.logger.error({\n collectionSlug: collection.slug,\n err,\n msg: `Error getting file from cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response('Internal Server Error', { status: 500 })\n }\n }\n}\n"],"names":["createKey","getStorageClient","streamToBuffer","readableStream","chunks","chunk","push","Buffer","from","concat","getStaticHandler","cachingOptions","collection","maxAge","collCacheConfig","collections","slug","cachingEnabled","process","env","PAYLOAD_CLOUD_CACHE_KEY","enabled","req","params","key","identityID","storageClient","filename","object","getObject","Bucket","PAYLOAD_CLOUD_BUCKET","Key","Body","Response","status","statusText","bodyBuffer","headers","Headers","String","ContentLength","ContentType","ETag","err","Error","name","message","includes","type","payload","logger","error","collectionSlug","msg","requestedKey"],"mappings":"AAIA,SAASA,SAAS,QAAQ,2BAA0B;AACpD,SAASC,gBAAgB,QAAQ,kCAAiC;AAOlE,8DAA8D;AAC9D,MAAMC,iBAAiB,OAAOC;IAC5B,MAAMC,SAAS,EAAE;IACjB,WAAW,MAAMC,SAASF,eAAgB;QACxCC,OAAOE,IAAI,CAAC,OAAOD,UAAU,WAAWE,OAAOC,IAAI,CAACH,SAASA;IAC/D;IACA,OAAOE,OAAOE,MAAM,CAACL;AACvB;AAEA,OAAO,MAAMM,mBAAmB,CAAC,EAAEC,cAAc,EAAEC,UAAU,EAAQ;IACnE,IAAIC,SAAS,MAAM,mBAAmB;;IACtC,IAAIC;IACJ,IAAIH,mBAAmB,OAAO;QAC5B,wCAAwC;QACxCE,SAASF,gBAAgBE,UAAUA;QACnCC,kBAAkBH,gBAAgBI,aAAa,CAACH,WAAWI,IAAI,CAAC,IAAI,CAAC;IACvE;IAEA,gDAAgD;IAChDH,SAASC,iBAAiBD,UAAUA;IAEpC,MAAMI,iBACJN,mBAAmB,SACnB,CAAC,CAACO,QAAQC,GAAG,CAACC,uBAAuB,IACrCN,iBAAiBO,YAAY;IAE/B,OAAO,OAAOC,KAAK,EAAEC,MAAM,EAAE;QAC3B,IAAIC,MAAM;QACV,IAAI;YACF,MAAM,EAAEC,UAAU,EAAEC,aAAa,EAAE,GAAG,MAAMzB;YAE5CuB,MAAMxB,UAAU;gBACdY,YAAYA,WAAWI,IAAI;gBAC3BW,UAAUJ,OAAOI,QAAQ;gBACzBF;YACF;YAEA,MAAMG,SAAS,MAAMF,cAAcG,SAAS,CAAC;gBAC3CC,QAAQZ,QAAQC,GAAG,CAACY,oBAAoB;gBACxCC,KAAKR;YACP;YAEA,IAAI,CAACI,OAAOK,IAAI,EAAE;gBAChB,OAAO,IAAIC,SAAS,MAAM;oBAAEC,QAAQ;oBAAKC,YAAY;gBAAY;YACnE;YAEA,MAAMC,aAAa,MAAMnC,eAAe0B,OAAOK,IAAI;YAEnD,OAAO,IAAIC,SAASG,YAAY;gBAC9BC,SAAS,IAAIC,QAAQ;oBACnB,kBAAkBC,OAAOZ,OAAOa,aAAa;oBAC7C,gBAAgBb,OAAOc,WAAW;oBAClC,GAAIzB,kBAAkB;wBAAE,iBAAiB,CAAC,gBAAgB,EAAEJ,QAAQ;oBAAC,CAAC;oBACtE8B,MAAMf,OAAOe,IAAI;gBACnB;gBACAR,QAAQ;YACV;QACF,EAAE,OAAOS,KAAc;YACrB;;;OAGC,GACD,IACEA,eAAeC,SACfD,IAAIE,IAAI,KAAK,kBACbF,IAAIG,OAAO,EAAEC,SAAS,oBACtB,UAAUJ,OACVA,IAAIK,IAAI,KAAK,sBACb;gBACA3B,IAAI4B,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;oBACvBC,gBAAgBzC,WAAWI,IAAI;oBAC/B4B;oBACAU,KAAK,CAAC,2CAA2C,EAAE/B,OAAOI,QAAQ,EAAE;oBACpEJ;oBACAgC,cAAc/B;gBAChB;gBACA,OAAO,IAAIU,SAAS,MAAM;oBAAEC,QAAQ;oBAAKC,YAAY;gBAAY;YACnE;YAEAd,IAAI4B,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBACvBC,gBAAgBzC,WAAWI,IAAI;gBAC/B4B;gBACAU,KAAK,CAAC,uCAAuC,EAAE/B,OAAOI,QAAQ,EAAE;gBAChEJ;gBACAgC,cAAc/B;YAChB;YACA,OAAO,IAAIU,SAAS,yBAAyB;gBAAEC,QAAQ;YAAI;QAC7D;IACF;AACF,EAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/payload-cloud",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "description": "The official Payload Cloud plugin",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -38,16 +38,16 @@
38
38
  "amazon-cognito-identity-js": "^6.1.2",
39
39
  "nodemailer": "6.9.10",
40
40
  "resend": "^0.17.2",
41
- "@payloadcms/email-nodemailer": "3.8.0"
41
+ "@payloadcms/email-nodemailer": "3.9.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/jest": "29.5.12",
45
45
  "@types/nodemailer": "6.4.14",
46
46
  "ts-jest": "^29.1.0",
47
- "payload": "3.8.0"
47
+ "payload": "3.9.0"
48
48
  },
49
49
  "peerDependencies": {
50
- "payload": "3.8.0"
50
+ "payload": "3.9.0"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "pnpm build:types && pnpm build:swc",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=email.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email.spec.d.ts","sourceRoot":"","sources":["../src/email.spec.ts"],"names":[],"mappings":""}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=plugin.spec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.spec.d.ts","sourceRoot":"","sources":["../src/plugin.spec.ts"],"names":[],"mappings":""}