@payloadcms/payload-cloud 3.23.0-canary.e847e12 → 3.23.0-canary.f4bcd50
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;
|
|
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"}
|
package/dist/staticHandler.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { createKey } from './utilities/createKey.js';
|
|
2
2
|
import { getStorageClient } from './utilities/getStorageClient.js';
|
|
3
|
-
// Type guard for NodeJS.Readable streams
|
|
4
|
-
const isNodeReadableStream = (body)=>{
|
|
5
|
-
return typeof body === 'object' && body !== null && 'pipe' in body && typeof body.pipe === 'function' && 'destroy' in body && typeof body.destroy === 'function';
|
|
6
|
-
};
|
|
7
3
|
// Convert a stream into a promise that resolves with a Buffer
|
|
8
4
|
const streamToBuffer = async (readableStream)=>{
|
|
9
5
|
const chunks = [];
|
|
@@ -43,18 +39,6 @@ export const getStaticHandler = ({ cachingOptions, collection })=>{
|
|
|
43
39
|
statusText: 'Not Found'
|
|
44
40
|
});
|
|
45
41
|
}
|
|
46
|
-
// On error, manually destroy stream to close socket
|
|
47
|
-
if (object.Body && isNodeReadableStream(object.Body)) {
|
|
48
|
-
const stream = object.Body;
|
|
49
|
-
stream.on('error', (err)=>{
|
|
50
|
-
req.payload.logger.error({
|
|
51
|
-
err,
|
|
52
|
-
key,
|
|
53
|
-
msg: 'Error streaming S3 object, destroying stream'
|
|
54
|
-
});
|
|
55
|
-
stream.destroy();
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
42
|
const bodyBuffer = await streamToBuffer(object.Body);
|
|
59
43
|
return new Response(bodyBuffer, {
|
|
60
44
|
headers: new Headers({
|
|
@@ -68,45 +52,21 @@ export const getStaticHandler = ({ cachingOptions, collection })=>{
|
|
|
68
52
|
status: 200
|
|
69
53
|
});
|
|
70
54
|
} catch (err) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
params,
|
|
87
|
-
requestedKey: key
|
|
88
|
-
});
|
|
89
|
-
return new Response(null, {
|
|
90
|
-
status: 404,
|
|
91
|
-
statusText: 'Not Found'
|
|
92
|
-
});
|
|
93
|
-
} else if (err.name === 'NoSuchKey') {
|
|
94
|
-
req.payload.logger.warn({
|
|
95
|
-
awsErr: {
|
|
96
|
-
...err,
|
|
97
|
-
// Remove stack trace, not relevant
|
|
98
|
-
stack: undefined
|
|
99
|
-
},
|
|
100
|
-
collectionSlug: collection.slug,
|
|
101
|
-
msg: `Requested file not found in cloud storage: ${params.filename}`,
|
|
102
|
-
params,
|
|
103
|
-
requestedKey: key
|
|
104
|
-
});
|
|
105
|
-
return new Response(null, {
|
|
106
|
-
status: 404,
|
|
107
|
-
statusText: 'Not Found'
|
|
108
|
-
});
|
|
109
|
-
}
|
|
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
|
+
});
|
|
110
70
|
}
|
|
111
71
|
req.payload.logger.error({
|
|
112
72
|
collectionSlug: collection.slug,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/staticHandler.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\
|
|
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: any) => {\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 || !object.ContentType || !object.ETag) {\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","ContentType","ETag","Response","status","statusText","bodyBuffer","headers","Headers","String","ContentLength","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,IAAI,CAACL,OAAOM,WAAW,IAAI,CAACN,OAAOO,IAAI,EAAE;gBACvD,OAAO,IAAIC,SAAS,MAAM;oBAAEC,QAAQ;oBAAKC,YAAY;gBAAY;YACnE;YAEA,MAAMC,aAAa,MAAMrC,eAAe0B,OAAOK,IAAI;YAEnD,OAAO,IAAIG,SAASG,YAAY;gBAC9BC,SAAS,IAAIC,QAAQ;oBACnB,kBAAkBC,OAAOd,OAAOe,aAAa;oBAC7C,gBAAgBf,OAAOM,WAAW;oBAClC,GAAIjB,kBAAkB;wBAAE,iBAAiB,CAAC,gBAAgB,EAAEJ,QAAQ;oBAAC,CAAC;oBACtEsB,MAAMP,OAAOO,IAAI;gBACnB;gBACAE,QAAQ;YACV;QACF,EAAE,OAAOO,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,IAAIY,SAAS,MAAM;oBAAEC,QAAQ;oBAAKC,YAAY;gBAAY;YACnE;YAEAhB,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,IAAIY,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.23.0-canary.
|
|
3
|
+
"version": "3.23.0-canary.f4bcd50",
|
|
4
4
|
"description": "The official Payload Cloud plugin",
|
|
5
5
|
"homepage": "https://payloadcms.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"@aws-sdk/lib-storage": "^3.614.0",
|
|
38
38
|
"amazon-cognito-identity-js": "^6.1.2",
|
|
39
39
|
"nodemailer": "6.9.16",
|
|
40
|
-
"@payloadcms/email-nodemailer": "3.23.0-canary.
|
|
40
|
+
"@payloadcms/email-nodemailer": "3.23.0-canary.f4bcd50"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/jest": "29.5.12",
|
|
44
44
|
"@types/nodemailer": "6.4.17",
|
|
45
|
-
"payload": "3.23.0-canary.
|
|
45
|
+
"payload": "3.23.0-canary.f4bcd50"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"payload": "3.23.0-canary.
|
|
48
|
+
"payload": "3.23.0-canary.f4bcd50"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "pnpm build:types && pnpm build:swc",
|