@payloadcms/storage-azure 4.0.0-internal.cd47d20 → 4.0.0-internal.ce66a41
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.
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +2 -1
- package/dist/adapter.js.map +1 -1
- package/dist/getFile.d.ts +3 -2
- package/dist/getFile.d.ts.map +1 -1
- package/dist/getFile.js +5 -9
- package/dist/getFile.js.map +1 -1
- package/package.json +4 -4
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EACV,OAAO,EACP,mBAAmB,EAEpB,MAAM,wCAAwC,CAAA;AAS/C,UAAU,sBAAsB;IAC9B,oBAAoB,EAAE,OAAO,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,aAAa,EAAE,MAAM,CAAA;IACrB,0BAA0B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtD,gBAAgB,EAAE,MAAM,eAAe,CAAA;IACvC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,oBAAoB,EACpB,OAAO,EACP,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAChB,oBAA4B,GAC7B,EAAE,sBAAsB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EACV,OAAO,EACP,mBAAmB,EAEpB,MAAM,wCAAwC,CAAA;AAS/C,UAAU,sBAAsB;IAC9B,oBAAoB,EAAE,OAAO,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,mBAAmB,CAAA;IACnC,aAAa,EAAE,MAAM,CAAA;IACrB,0BAA0B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtD,gBAAgB,EAAE,MAAM,eAAe,CAAA;IACvC,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,oBAAoB,EACpB,OAAO,EACP,aAAa,EACb,aAAa,EACb,0BAA0B,EAC1B,gBAAgB,EAChB,oBAA4B,GAC7B,EAAE,sBAAsB,GAAG,OAAO,CAgElC"}
|
package/dist/adapter.js
CHANGED
|
@@ -44,13 +44,14 @@ export function createAzureAdapter({ allowContainerCreate, baseURL, clientUpload
|
|
|
44
44
|
});
|
|
45
45
|
return data;
|
|
46
46
|
},
|
|
47
|
-
staticHandler: (req, { doc, headers, params: { filename, uploadReference } })=>getFile({
|
|
47
|
+
staticHandler: (req, { doc, headers, params: { filename, operation, uploadReference } })=>getFile({
|
|
48
48
|
client: getStorageClient(),
|
|
49
49
|
collection,
|
|
50
50
|
collectionPrefix: prefix,
|
|
51
51
|
doc,
|
|
52
52
|
filename,
|
|
53
53
|
incomingHeaders: headers,
|
|
54
|
+
operation,
|
|
54
55
|
req,
|
|
55
56
|
uploadReference,
|
|
56
57
|
useCompositePrefixes
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter.ts"],"sourcesContent":["import type { ContainerClient } from '@azure/storage-blob'\nimport type {\n Adapter,\n ClientUploadsConfig,\n GeneratedAdapter,\n} from '@payloadcms/plugin-cloud-storage/types'\n\nimport { deleteFile } from './deleteFile.js'\nimport { generateUploadInstructions } from './generateUploadInstructions.js'\nimport { generateURL } from './generateURL.js'\nimport { getFile } from './getFile.js'\nimport { isClientUploadAllowed } from './isClientUploadAllowed.js'\nimport { uploadFile } from './uploadFile.js'\n\ninterface CreateAzureAdapterArgs {\n allowContainerCreate: boolean\n baseURL: string\n clientUploads?: ClientUploadsConfig\n containerName: string\n createContainerIfNotExists: () => Promise<void> | void\n getStorageClient: () => ContainerClient\n useCompositePrefixes?: boolean\n}\n\nexport function createAzureAdapter({\n allowContainerCreate,\n baseURL,\n clientUploads,\n containerName,\n createContainerIfNotExists,\n getStorageClient,\n useCompositePrefixes = false,\n}: CreateAzureAdapterArgs): Adapter {\n return ({ collection, prefix = '' }): GeneratedAdapter => ({\n name: 'azure',\n\n generateURL: ({ filename, prefix: urlPrefix = '' }) =>\n generateURL({\n baseURL,\n collectionPrefix: prefix,\n containerName,\n filename,\n prefix: urlPrefix,\n useCompositePrefixes,\n }),\n\n uploadInstructions: {\n adminHandler: {\n path: '@payloadcms/storage-azure/client#AzureClientUploadHandler',\n },\n enabled: Boolean(clientUploads) && isClientUploadAllowed(collection),\n generate: generateUploadInstructions({\n access: typeof clientUploads === 'object' ? clientUploads.access : undefined,\n collectionPrefix: prefix,\n containerName,\n getStorageClient,\n useCompositePrefixes,\n }),\n requiresUploadReceipt: true,\n useInAdmin: true,\n },\n\n handleDelete: ({ storageFilePath }) =>\n deleteFile({\n client: getStorageClient(),\n storageFilePath,\n }),\n\n handleUpload: async ({ data, file, storageFilePath }) => {\n await uploadFile({\n buffer: file.buffer,\n client: getStorageClient(),\n mimeType: file.mimeType,\n storageFilePath,\n tempFilePath: file.tempFilePath,\n })\n\n return data\n },\n\n staticHandler: (req, { doc, headers, params: { filename, uploadReference } }) =>\n getFile({\n client: getStorageClient(),\n collection,\n collectionPrefix: prefix,\n doc,\n filename,\n incomingHeaders: headers,\n req,\n uploadReference,\n useCompositePrefixes,\n }),\n\n ...(allowContainerCreate && { onInit: createContainerIfNotExists }),\n })\n}\n"],"names":["deleteFile","generateUploadInstructions","generateURL","getFile","isClientUploadAllowed","uploadFile","createAzureAdapter","allowContainerCreate","baseURL","clientUploads","containerName","createContainerIfNotExists","getStorageClient","useCompositePrefixes","collection","prefix","name","filename","urlPrefix","collectionPrefix","uploadInstructions","adminHandler","path","enabled","Boolean","generate","access","undefined","requiresUploadReceipt","useInAdmin","handleDelete","storageFilePath","client","handleUpload","data","file","buffer","mimeType","tempFilePath","staticHandler","req","doc","headers","params","uploadReference","incomingHeaders","onInit"],"mappings":"AAOA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,0BAA0B,QAAQ,kCAAiC;AAC5E,SAASC,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,UAAU,QAAQ,kBAAiB;AAY5C,OAAO,SAASC,mBAAmB,EACjCC,oBAAoB,EACpBC,OAAO,EACPC,aAAa,EACbC,aAAa,EACbC,0BAA0B,EAC1BC,gBAAgB,EAChBC,uBAAuB,KAAK,EACL;IACvB,OAAO,CAAC,EAAEC,UAAU,EAAEC,SAAS,EAAE,EAAE,GAAwB,CAAA;YACzDC,MAAM;YAENd,aAAa,CAAC,EAAEe,QAAQ,EAAEF,QAAQG,YAAY,EAAE,EAAE,GAChDhB,YAAY;oBACVM;oBACAW,kBAAkBJ;oBAClBL;oBACAO;oBACAF,QAAQG;oBACRL;gBACF;YAEFO,oBAAoB;gBAClBC,cAAc;oBACZC,MAAM;gBACR;gBACAC,SAASC,QAAQf,kBAAkBL,sBAAsBU;gBACzDW,UAAUxB,2BAA2B;oBACnCyB,QAAQ,OAAOjB,kBAAkB,WAAWA,cAAciB,MAAM,GAAGC;oBACnER,kBAAkBJ;oBAClBL;oBACAE;oBACAC;gBACF;gBACAe,uBAAuB;gBACvBC,YAAY;YACd;YAEAC,cAAc,CAAC,EAAEC,eAAe,EAAE,GAChC/B,WAAW;oBACTgC,QAAQpB;oBACRmB;gBACF;YAEFE,cAAc,OAAO,EAAEC,IAAI,EAAEC,IAAI,EAAEJ,eAAe,EAAE;gBAClD,MAAM1B,WAAW;oBACf+B,QAAQD,KAAKC,MAAM;oBACnBJ,QAAQpB;oBACRyB,UAAUF,KAAKE,QAAQ;oBACvBN;oBACAO,cAAcH,KAAKG,YAAY;gBACjC;gBAEA,OAAOJ;YACT;YAEAK,eAAe,CAACC,KAAK,EAAEC,GAAG,EAAEC,OAAO,EAAEC,QAAQ,EAAE1B,QAAQ,EAAE2B,eAAe,EAAE,EAAE,
|
|
1
|
+
{"version":3,"sources":["../src/adapter.ts"],"sourcesContent":["import type { ContainerClient } from '@azure/storage-blob'\nimport type {\n Adapter,\n ClientUploadsConfig,\n GeneratedAdapter,\n} from '@payloadcms/plugin-cloud-storage/types'\n\nimport { deleteFile } from './deleteFile.js'\nimport { generateUploadInstructions } from './generateUploadInstructions.js'\nimport { generateURL } from './generateURL.js'\nimport { getFile } from './getFile.js'\nimport { isClientUploadAllowed } from './isClientUploadAllowed.js'\nimport { uploadFile } from './uploadFile.js'\n\ninterface CreateAzureAdapterArgs {\n allowContainerCreate: boolean\n baseURL: string\n clientUploads?: ClientUploadsConfig\n containerName: string\n createContainerIfNotExists: () => Promise<void> | void\n getStorageClient: () => ContainerClient\n useCompositePrefixes?: boolean\n}\n\nexport function createAzureAdapter({\n allowContainerCreate,\n baseURL,\n clientUploads,\n containerName,\n createContainerIfNotExists,\n getStorageClient,\n useCompositePrefixes = false,\n}: CreateAzureAdapterArgs): Adapter {\n return ({ collection, prefix = '' }): GeneratedAdapter => ({\n name: 'azure',\n\n generateURL: ({ filename, prefix: urlPrefix = '' }) =>\n generateURL({\n baseURL,\n collectionPrefix: prefix,\n containerName,\n filename,\n prefix: urlPrefix,\n useCompositePrefixes,\n }),\n\n uploadInstructions: {\n adminHandler: {\n path: '@payloadcms/storage-azure/client#AzureClientUploadHandler',\n },\n enabled: Boolean(clientUploads) && isClientUploadAllowed(collection),\n generate: generateUploadInstructions({\n access: typeof clientUploads === 'object' ? clientUploads.access : undefined,\n collectionPrefix: prefix,\n containerName,\n getStorageClient,\n useCompositePrefixes,\n }),\n requiresUploadReceipt: true,\n useInAdmin: true,\n },\n\n handleDelete: ({ storageFilePath }) =>\n deleteFile({\n client: getStorageClient(),\n storageFilePath,\n }),\n\n handleUpload: async ({ data, file, storageFilePath }) => {\n await uploadFile({\n buffer: file.buffer,\n client: getStorageClient(),\n mimeType: file.mimeType,\n storageFilePath,\n tempFilePath: file.tempFilePath,\n })\n\n return data\n },\n\n staticHandler: (req, { doc, headers, params: { filename, operation, uploadReference } }) =>\n getFile({\n client: getStorageClient(),\n collection,\n collectionPrefix: prefix,\n doc,\n filename,\n incomingHeaders: headers,\n operation,\n req,\n uploadReference,\n useCompositePrefixes,\n }),\n\n ...(allowContainerCreate && { onInit: createContainerIfNotExists }),\n })\n}\n"],"names":["deleteFile","generateUploadInstructions","generateURL","getFile","isClientUploadAllowed","uploadFile","createAzureAdapter","allowContainerCreate","baseURL","clientUploads","containerName","createContainerIfNotExists","getStorageClient","useCompositePrefixes","collection","prefix","name","filename","urlPrefix","collectionPrefix","uploadInstructions","adminHandler","path","enabled","Boolean","generate","access","undefined","requiresUploadReceipt","useInAdmin","handleDelete","storageFilePath","client","handleUpload","data","file","buffer","mimeType","tempFilePath","staticHandler","req","doc","headers","params","operation","uploadReference","incomingHeaders","onInit"],"mappings":"AAOA,SAASA,UAAU,QAAQ,kBAAiB;AAC5C,SAASC,0BAA0B,QAAQ,kCAAiC;AAC5E,SAASC,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,OAAO,QAAQ,eAAc;AACtC,SAASC,qBAAqB,QAAQ,6BAA4B;AAClE,SAASC,UAAU,QAAQ,kBAAiB;AAY5C,OAAO,SAASC,mBAAmB,EACjCC,oBAAoB,EACpBC,OAAO,EACPC,aAAa,EACbC,aAAa,EACbC,0BAA0B,EAC1BC,gBAAgB,EAChBC,uBAAuB,KAAK,EACL;IACvB,OAAO,CAAC,EAAEC,UAAU,EAAEC,SAAS,EAAE,EAAE,GAAwB,CAAA;YACzDC,MAAM;YAENd,aAAa,CAAC,EAAEe,QAAQ,EAAEF,QAAQG,YAAY,EAAE,EAAE,GAChDhB,YAAY;oBACVM;oBACAW,kBAAkBJ;oBAClBL;oBACAO;oBACAF,QAAQG;oBACRL;gBACF;YAEFO,oBAAoB;gBAClBC,cAAc;oBACZC,MAAM;gBACR;gBACAC,SAASC,QAAQf,kBAAkBL,sBAAsBU;gBACzDW,UAAUxB,2BAA2B;oBACnCyB,QAAQ,OAAOjB,kBAAkB,WAAWA,cAAciB,MAAM,GAAGC;oBACnER,kBAAkBJ;oBAClBL;oBACAE;oBACAC;gBACF;gBACAe,uBAAuB;gBACvBC,YAAY;YACd;YAEAC,cAAc,CAAC,EAAEC,eAAe,EAAE,GAChC/B,WAAW;oBACTgC,QAAQpB;oBACRmB;gBACF;YAEFE,cAAc,OAAO,EAAEC,IAAI,EAAEC,IAAI,EAAEJ,eAAe,EAAE;gBAClD,MAAM1B,WAAW;oBACf+B,QAAQD,KAAKC,MAAM;oBACnBJ,QAAQpB;oBACRyB,UAAUF,KAAKE,QAAQ;oBACvBN;oBACAO,cAAcH,KAAKG,YAAY;gBACjC;gBAEA,OAAOJ;YACT;YAEAK,eAAe,CAACC,KAAK,EAAEC,GAAG,EAAEC,OAAO,EAAEC,QAAQ,EAAE1B,QAAQ,EAAE2B,SAAS,EAAEC,eAAe,EAAE,EAAE,GACrF1C,QAAQ;oBACN6B,QAAQpB;oBACRE;oBACAK,kBAAkBJ;oBAClB0B;oBACAxB;oBACA6B,iBAAiBJ;oBACjBE;oBACAJ;oBACAK;oBACAhC;gBACF;YAEF,GAAIN,wBAAwB;gBAAEwC,QAAQpC;YAA2B,CAAC;QACpE,CAAA;AACF"}
|
package/dist/getFile.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContainerClient } from '@azure/storage-blob';
|
|
2
|
-
import type { CollectionConfig, PayloadRequest, TypeWithID } from 'payload';
|
|
2
|
+
import type { CollectionConfig, FileHandlerOperation, PayloadRequest, TypeWithID } from 'payload';
|
|
3
3
|
interface GetFileArgs {
|
|
4
4
|
client: ContainerClient;
|
|
5
5
|
collection: CollectionConfig;
|
|
@@ -7,10 +7,11 @@ interface GetFileArgs {
|
|
|
7
7
|
doc?: TypeWithID;
|
|
8
8
|
filename: string;
|
|
9
9
|
incomingHeaders?: Headers;
|
|
10
|
+
operation?: FileHandlerOperation;
|
|
10
11
|
req: PayloadRequest;
|
|
11
12
|
uploadReference?: unknown;
|
|
12
13
|
useCompositePrefixes?: boolean;
|
|
13
14
|
}
|
|
14
|
-
export declare function getFile({ client, collection, collectionPrefix, doc, filename, incomingHeaders, req, uploadReference, useCompositePrefixes, }: GetFileArgs): Promise<Response>;
|
|
15
|
+
export declare function getFile({ client, collection, collectionPrefix, doc, filename, incomingHeaders, operation, req, uploadReference, useCompositePrefixes, }: GetFileArgs): Promise<Response>;
|
|
15
16
|
export {};
|
|
16
17
|
//# sourceMappingURL=getFile.d.ts.map
|
package/dist/getFile.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../src/getFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../src/getFile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAUjG,UAAU,WAAW;IACnB,MAAM,EAAE,eAAe,CAAA;IACvB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,SAAS,CAAC,EAAE,oBAAoB,CAAA;IAChC,GAAG,EAAE,cAAc,CAAA;IACnB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAgCD,wBAAsB,OAAO,CAAC,EAC5B,MAAM,EACN,UAAU,EACV,gBAAqB,EACrB,GAAG,EACH,QAAQ,EACR,eAAe,EACf,SAAkB,EAClB,GAAG,EACH,eAAe,EACf,oBAA4B,GAC7B,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsHjC"}
|
package/dist/getFile.js
CHANGED
|
@@ -13,7 +13,8 @@ const abortRequestAndDestroyStream = ({ abortController, blob })=>{
|
|
|
13
13
|
blob.readableStreamBody.destroy();
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
-
export async function getFile({ client, collection, collectionPrefix = '', doc, filename, incomingHeaders, req, uploadReference, useCompositePrefixes = false }) {
|
|
16
|
+
export async function getFile({ client, collection, collectionPrefix = '', doc, filename, incomingHeaders, operation = 'read', req, uploadReference, useCompositePrefixes = false }) {
|
|
17
|
+
const isTransformSource = operation === 'transform';
|
|
17
18
|
let blob = undefined;
|
|
18
19
|
let streamed = false;
|
|
19
20
|
const abortController = new AbortController();
|
|
@@ -42,7 +43,6 @@ export async function getFile({ client, collection, collectionPrefix = '', doc,
|
|
|
42
43
|
useCompositePrefixes
|
|
43
44
|
});
|
|
44
45
|
const blockBlobClient = client.getBlockBlobClient(storageFilePath);
|
|
45
|
-
// Get file size for range validation
|
|
46
46
|
const properties = await blockBlobClient.getProperties();
|
|
47
47
|
const fileSize = properties.contentLength;
|
|
48
48
|
if (!fileSize) {
|
|
@@ -50,8 +50,7 @@ export async function getFile({ client, collection, collectionPrefix = '', doc,
|
|
|
50
50
|
status: 500
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
const rangeHeader = req.headers.get('range');
|
|
53
|
+
const rangeHeader = isTransformSource ? null : req.headers.get('range');
|
|
55
54
|
const rangeResult = getRangeRequestInfo({
|
|
56
55
|
fileSize,
|
|
57
56
|
rangeHeader
|
|
@@ -62,18 +61,15 @@ export async function getFile({ client, collection, collectionPrefix = '', doc,
|
|
|
62
61
|
status: rangeResult.status
|
|
63
62
|
});
|
|
64
63
|
}
|
|
65
|
-
// Download with range if partial
|
|
66
64
|
blob = rangeResult.type === 'partial' ? await blockBlobClient.download(rangeResult.rangeStart, rangeResult.rangeEnd - rangeResult.rangeStart + 1, {
|
|
67
65
|
abortSignal: abortController.signal
|
|
68
66
|
}) : await blockBlobClient.download(0, undefined, {
|
|
69
67
|
abortSignal: abortController.signal
|
|
70
68
|
});
|
|
71
69
|
let headers = new Headers(incomingHeaders);
|
|
72
|
-
// Add range-related headers from the result
|
|
73
70
|
for (const [key, value] of Object.entries(rangeResult.headers)){
|
|
74
71
|
headers.append(key, value);
|
|
75
72
|
}
|
|
76
|
-
// Add Azure-specific headers
|
|
77
73
|
headers.append('Content-Type', String(properties.contentType));
|
|
78
74
|
if (properties.etag) {
|
|
79
75
|
headers.append('ETag', String(properties.etag));
|
|
@@ -83,12 +79,12 @@ export async function getFile({ client, collection, collectionPrefix = '', doc,
|
|
|
83
79
|
headers.append('Content-Security-Policy', uploadContentSecurityPolicy);
|
|
84
80
|
}
|
|
85
81
|
const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match');
|
|
86
|
-
if (collection.upload && typeof collection.upload === 'object' && typeof collection.upload.modifyResponseHeaders === 'function') {
|
|
82
|
+
if (!isTransformSource && collection.upload && typeof collection.upload === 'object' && typeof collection.upload.modifyResponseHeaders === 'function') {
|
|
87
83
|
headers = collection.upload.modifyResponseHeaders({
|
|
88
84
|
headers
|
|
89
85
|
}) || headers;
|
|
90
86
|
}
|
|
91
|
-
if (etagFromHeaders && etagFromHeaders === properties.etag) {
|
|
87
|
+
if (!isTransformSource && etagFromHeaders && etagFromHeaders === properties.etag) {
|
|
92
88
|
return new Response(null, {
|
|
93
89
|
headers,
|
|
94
90
|
status: 304
|
package/dist/getFile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/getFile.ts"],"sourcesContent":["import type { BlobDownloadResponseParsed, ContainerClient } from '@azure/storage-blob'\nimport type { CollectionConfig, PayloadRequest, TypeWithID } from 'payload'\nimport type { Readable } from 'stream'\n\nimport { RestError } from '@azure/storage-blob'\nimport {\n buildStoragePathData,\n getFilePrefix as getDocPrefix,\n} from '@payloadcms/plugin-cloud-storage/utilities'\nimport { getRangeRequestInfo, isXmlMimeType, uploadContentSecurityPolicy } from 'payload/internal'\n\ninterface GetFileArgs {\n client: ContainerClient\n collection: CollectionConfig\n collectionPrefix?: string\n doc?: TypeWithID\n filename: string\n incomingHeaders?: Headers\n req: PayloadRequest\n uploadReference?: unknown\n useCompositePrefixes?: boolean\n}\n\nconst isNodeReadableStream = (\n body: BlobDownloadResponseParsed['readableStreamBody'],\n): body is Readable => {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'pipe' in body &&\n typeof body.pipe === 'function' &&\n 'destroy' in body &&\n typeof body.destroy === 'function'\n )\n}\n\nconst abortRequestAndDestroyStream = ({\n abortController,\n blob,\n}: {\n abortController: AbortController\n blob?: BlobDownloadResponseParsed\n}) => {\n try {\n abortController.abort()\n } catch {\n /* noop */\n }\n if (blob?.readableStreamBody && isNodeReadableStream(blob.readableStreamBody)) {\n blob.readableStreamBody.destroy()\n }\n}\n\nexport async function getFile({\n client,\n collection,\n collectionPrefix = '',\n doc,\n filename,\n incomingHeaders,\n req,\n uploadReference,\n useCompositePrefixes = false,\n}: GetFileArgs): Promise<Response> {\n let blob: BlobDownloadResponseParsed | undefined = undefined\n let streamed = false\n\n const abortController = new AbortController()\n if (req.signal) {\n req.signal.addEventListener('abort', () => {\n abortRequestAndDestroyStream({ abortController, blob })\n })\n }\n\n try {\n const docPrefix = await getDocPrefix({\n collection,\n collectionPrefix,\n doc,\n filename,\n req,\n uploadReference,\n useCompositePrefixes,\n })\n\n const { storageFilePath } = buildStoragePathData({\n collectionPrefix,\n docPrefix,\n filename,\n useCompositePrefixes,\n })\n\n const blockBlobClient = client.getBlockBlobClient(storageFilePath)\n\n
|
|
1
|
+
{"version":3,"sources":["../src/getFile.ts"],"sourcesContent":["import type { BlobDownloadResponseParsed, ContainerClient } from '@azure/storage-blob'\nimport type { CollectionConfig, FileHandlerOperation, PayloadRequest, TypeWithID } from 'payload'\nimport type { Readable } from 'stream'\n\nimport { RestError } from '@azure/storage-blob'\nimport {\n buildStoragePathData,\n getFilePrefix as getDocPrefix,\n} from '@payloadcms/plugin-cloud-storage/utilities'\nimport { getRangeRequestInfo, isXmlMimeType, uploadContentSecurityPolicy } from 'payload/internal'\n\ninterface GetFileArgs {\n client: ContainerClient\n collection: CollectionConfig\n collectionPrefix?: string\n doc?: TypeWithID\n filename: string\n incomingHeaders?: Headers\n operation?: FileHandlerOperation\n req: PayloadRequest\n uploadReference?: unknown\n useCompositePrefixes?: boolean\n}\n\nconst isNodeReadableStream = (\n body: BlobDownloadResponseParsed['readableStreamBody'],\n): body is Readable => {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'pipe' in body &&\n typeof body.pipe === 'function' &&\n 'destroy' in body &&\n typeof body.destroy === 'function'\n )\n}\n\nconst abortRequestAndDestroyStream = ({\n abortController,\n blob,\n}: {\n abortController: AbortController\n blob?: BlobDownloadResponseParsed\n}) => {\n try {\n abortController.abort()\n } catch {\n /* noop */\n }\n if (blob?.readableStreamBody && isNodeReadableStream(blob.readableStreamBody)) {\n blob.readableStreamBody.destroy()\n }\n}\n\nexport async function getFile({\n client,\n collection,\n collectionPrefix = '',\n doc,\n filename,\n incomingHeaders,\n operation = 'read',\n req,\n uploadReference,\n useCompositePrefixes = false,\n}: GetFileArgs): Promise<Response> {\n const isTransformSource = operation === 'transform'\n let blob: BlobDownloadResponseParsed | undefined = undefined\n let streamed = false\n\n const abortController = new AbortController()\n if (req.signal) {\n req.signal.addEventListener('abort', () => {\n abortRequestAndDestroyStream({ abortController, blob })\n })\n }\n\n try {\n const docPrefix = await getDocPrefix({\n collection,\n collectionPrefix,\n doc,\n filename,\n req,\n uploadReference,\n useCompositePrefixes,\n })\n\n const { storageFilePath } = buildStoragePathData({\n collectionPrefix,\n docPrefix,\n filename,\n useCompositePrefixes,\n })\n\n const blockBlobClient = client.getBlockBlobClient(storageFilePath)\n\n const properties = await blockBlobClient.getProperties()\n const fileSize = properties.contentLength\n\n if (!fileSize) {\n return new Response('Internal Server Error', { status: 500 })\n }\n\n const rangeHeader = isTransformSource ? null : req.headers.get('range')\n const rangeResult = getRangeRequestInfo({ fileSize, rangeHeader })\n\n if (rangeResult.type === 'invalid') {\n return new Response(null, {\n headers: new Headers(rangeResult.headers),\n status: rangeResult.status,\n })\n }\n\n blob =\n rangeResult.type === 'partial'\n ? await blockBlobClient.download(\n rangeResult.rangeStart,\n rangeResult.rangeEnd - rangeResult.rangeStart + 1,\n { abortSignal: abortController.signal },\n )\n : await blockBlobClient.download(0, undefined, { abortSignal: abortController.signal })\n\n let headers = new Headers(incomingHeaders)\n\n for (const [key, value] of Object.entries(rangeResult.headers)) {\n headers.append(key, value)\n }\n\n headers.append('Content-Type', String(properties.contentType))\n if (properties.etag) {\n headers.append('ETag', String(properties.etag))\n }\n\n // Apply a restrictive policy to XML-family responses served through Payload.\n if (isXmlMimeType(properties.contentType)) {\n headers.append('Content-Security-Policy', uploadContentSecurityPolicy)\n }\n\n const etagFromHeaders = req.headers.get('etag') || req.headers.get('if-none-match')\n\n if (\n !isTransformSource &&\n collection.upload &&\n typeof collection.upload === 'object' &&\n typeof collection.upload.modifyResponseHeaders === 'function'\n ) {\n headers = collection.upload.modifyResponseHeaders({ headers }) || headers\n }\n\n if (!isTransformSource && etagFromHeaders && etagFromHeaders === properties.etag) {\n return new Response(null, {\n headers,\n status: 304,\n })\n }\n\n if (!blob.readableStreamBody || !isNodeReadableStream(blob.readableStreamBody)) {\n return new Response('Internal Server Error', { status: 500 })\n }\n\n const stream = blob.readableStreamBody\n stream.on('error', (err: Error) => {\n req.payload.logger.error({\n err,\n msg: 'Error while streaming Azure blob (aborting)',\n })\n abortRequestAndDestroyStream({ abortController, blob })\n })\n\n streamed = true\n return new Response(stream, { headers, status: rangeResult.status })\n } catch (err: unknown) {\n if (err instanceof RestError && err.statusCode === 404) {\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n req.payload.logger.error(err)\n return new Response('Internal Server Error', { status: 500 })\n } finally {\n if (!streamed) {\n abortRequestAndDestroyStream({ abortController, blob })\n }\n }\n}\n"],"names":["RestError","buildStoragePathData","getFilePrefix","getDocPrefix","getRangeRequestInfo","isXmlMimeType","uploadContentSecurityPolicy","isNodeReadableStream","body","pipe","destroy","abortRequestAndDestroyStream","abortController","blob","abort","readableStreamBody","getFile","client","collection","collectionPrefix","doc","filename","incomingHeaders","operation","req","uploadReference","useCompositePrefixes","isTransformSource","undefined","streamed","AbortController","signal","addEventListener","docPrefix","storageFilePath","blockBlobClient","getBlockBlobClient","properties","getProperties","fileSize","contentLength","Response","status","rangeHeader","headers","get","rangeResult","type","Headers","download","rangeStart","rangeEnd","abortSignal","key","value","Object","entries","append","String","contentType","etag","etagFromHeaders","upload","modifyResponseHeaders","stream","on","err","payload","logger","error","msg","statusCode","statusText"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/storage-azure",
|
|
3
|
-
"version": "4.0.0-internal.
|
|
3
|
+
"version": "4.0.0-internal.ce66a41",
|
|
4
4
|
"description": "Payload storage adapter for Azure Blob Storage",
|
|
5
5
|
"homepage": "https://payloadcms.com",
|
|
6
6
|
"repository": {
|
|
@@ -39,13 +39,13 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@azure/abort-controller": "^1.1.0",
|
|
41
41
|
"@azure/storage-blob": "^12.33.0",
|
|
42
|
-
"@payloadcms/plugin-cloud-storage": "4.0.0-internal.
|
|
42
|
+
"@payloadcms/plugin-cloud-storage": "4.0.0-internal.ce66a41"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"payload": "4.0.0-internal.
|
|
45
|
+
"payload": "4.0.0-internal.ce66a41"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"payload": "4.0.0-internal.
|
|
48
|
+
"payload": "4.0.0-internal.ce66a41"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=24.15.0"
|