@payloadcms/plugin-cloud-storage 4.0.0-internal.4a8e202 → 4.0.0-internal.4c2ee12
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/README.md +2 -0
- package/dist/exports/client.d.ts +1 -1
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +1 -1
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/utilities.d.ts +1 -1
- package/dist/exports/utilities.d.ts.map +1 -1
- package/dist/exports/utilities.js +1 -1
- package/dist/exports/utilities.js.map +1 -1
- package/dist/fields/getFields.d.ts +1 -5
- package/dist/fields/getFields.d.ts.map +1 -1
- package/dist/fields/getFields.js +118 -24
- package/dist/fields/getFields.js.map +1 -1
- package/dist/hooks/afterChange.d.ts +5 -1
- package/dist/hooks/afterChange.d.ts.map +1 -1
- package/dist/hooks/afterChange.js +137 -23
- package/dist/hooks/afterChange.js.map +1 -1
- package/dist/hooks/afterDelete.d.ts +3 -1
- package/dist/hooks/afterDelete.d.ts.map +1 -1
- package/dist/hooks/afterDelete.js +26 -4
- package/dist/hooks/afterDelete.js.map +1 -1
- package/dist/hooks/afterRead.d.ts +6 -1
- package/dist/hooks/afterRead.d.ts.map +1 -1
- package/dist/hooks/afterRead.js +34 -7
- package/dist/hooks/afterRead.js.map +1 -1
- package/dist/hooks/beforeChange.d.ts +2 -1
- package/dist/hooks/beforeChange.d.ts.map +1 -1
- package/dist/hooks/beforeChange.js +18 -4
- package/dist/hooks/beforeChange.js.map +1 -1
- package/dist/hooks/normalizeUploadPrefix.d.ts +11 -0
- package/dist/hooks/normalizeUploadPrefix.d.ts.map +1 -0
- package/dist/hooks/normalizeUploadPrefix.js +42 -0
- package/dist/hooks/normalizeUploadPrefix.js.map +1 -0
- package/dist/hooks/publicOriginalURL.d.ts +8 -0
- package/dist/hooks/publicOriginalURL.d.ts.map +1 -0
- package/dist/hooks/publicOriginalURL.js +34 -0
- package/dist/hooks/publicOriginalURL.js.map +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +72 -42
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +45 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities/buildPrefixWithObjectKey.d.ts +8 -0
- package/dist/utilities/buildPrefixWithObjectKey.d.ts.map +1 -0
- package/dist/utilities/buildPrefixWithObjectKey.js +13 -0
- package/dist/utilities/buildPrefixWithObjectKey.js.map +1 -0
- package/dist/utilities/buildStoragePathData.d.ts +49 -0
- package/dist/utilities/buildStoragePathData.d.ts.map +1 -0
- package/dist/utilities/buildStoragePathData.js +67 -0
- package/dist/utilities/buildStoragePathData.js.map +1 -0
- package/dist/utilities/createFileOperations.d.ts +13 -0
- package/dist/utilities/createFileOperations.d.ts.map +1 -0
- package/dist/utilities/createFileOperations.js +258 -0
- package/dist/utilities/createFileOperations.js.map +1 -0
- package/dist/utilities/getFilePrefix.d.ts +15 -10
- package/dist/utilities/getFilePrefix.d.ts.map +1 -1
- package/dist/utilities/getFilePrefix.js +85 -30
- package/dist/utilities/getFilePrefix.js.map +1 -1
- package/dist/utilities/getIncomingFiles.js +2 -2
- package/dist/utilities/getIncomingFiles.js.map +1 -1
- package/dist/utilities/getStorageLocationSelect.d.ts +9 -0
- package/dist/utilities/getStorageLocationSelect.d.ts.map +1 -0
- package/dist/utilities/getStorageLocationSelect.js +54 -0
- package/dist/utilities/getStorageLocationSelect.js.map +1 -0
- package/dist/utilities/resolveSignedURLKey.d.ts +12 -1
- package/dist/utilities/resolveSignedURLKey.d.ts.map +1 -1
- package/dist/utilities/resolveSignedURLKey.js +52 -10
- package/dist/utilities/resolveSignedURLKey.js.map +1 -1
- package/dist/utilities/sanitizePrefix.d.ts +1 -9
- package/dist/utilities/sanitizePrefix.d.ts.map +1 -1
- package/dist/utilities/sanitizePrefix.js +1 -21
- package/dist/utilities/sanitizePrefix.js.map +1 -1
- package/package.json +6 -6
- package/dist/admin/fields/getFields.d.ts +0 -17
- package/dist/admin/fields/getFields.d.ts.map +0 -1
- package/dist/admin/fields/getFields.js +0 -98
- package/dist/admin/fields/getFields.js.map +0 -1
- package/dist/admin/index.d.ts +0 -4
- package/dist/admin/index.d.ts.map +0 -1
- package/dist/admin/index.js +0 -34
- package/dist/admin/index.js.map +0 -1
- package/dist/utilities/getFileKey.d.ts +0 -22
- package/dist/utilities/getFileKey.d.ts.map +0 -1
- package/dist/utilities/getFileKey.js +0 -23
- package/dist/utilities/getFileKey.js.map +0 -1
- package/dist/utilities/getFileKey.spec.js +0 -174
- package/dist/utilities/getFileKey.spec.js.map +0 -1
- package/dist/utilities/getFilePrefix.spec.js +0 -105
- package/dist/utilities/getFilePrefix.spec.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n}\n\nexport const getAfterChangeHook =\n ({ adapter, collection }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ doc, operation, previousDoc, req }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n const isDraftSave = (doc as { _status?: string })._status === 'draft'\n const isDraftOverPublished =\n isDraftSave && (previousDoc as { _status?: string } | undefined)?._status === 'published'\n\n try {\n const files = getIncomingFiles({ data: doc, req })\n\n if (files.length > 0) {\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.uploadReference)\n .map((file) =>\n adapter.handleUpload({\n collection,\n data: doc,\n file,\n req,\n }),\n ),\n )\n\n const uploadMetadata = uploadResults\n .filter(\n (result): result is Partial<FileData & TypeWithID> =>\n result != null && typeof result === 'object',\n )\n .reduce(\n (acc, metadata) => ({ ...acc, ...metadata }),\n {} as Partial<FileData & TypeWithID>,\n )\n\n let docWithMetadata = doc\n\n if (Object.keys(uploadMetadata).length > 0) {\n if (!req.context) {\n req.context = {}\n }\n req.context.skipCloudStorage = true\n\n // Clear to prevent re-processing\n req.file = undefined\n req.payloadUploadSizes = undefined\n\n try {\n await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: uploadMetadata,\n depth: 0,\n draft: isDraftSave,\n req,\n })\n } finally {\n delete req.context.skipCloudStorage\n }\n\n docWithMetadata = { ...doc, ...uploadMetadata }\n }\n\n // Delete previous files only after the new upload and metadata\n // persistence have succeeded. Deleting earlier would orphan the\n // record if a later step throws (e.g. a user-defined afterChange\n // hook on the same collection).\n if (previousDoc && operation === 'update' && !isDraftOverPublished) {\n let filesToDelete: string[] = []\n\n if (typeof previousDoc?.filename === 'string') {\n filesToDelete.push(previousDoc.filename)\n }\n\n if (typeof previousDoc.sizes === 'object') {\n filesToDelete = filesToDelete.concat(\n Object.values(previousDoc?.sizes || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n )\n }\n\n // Collect new filenames (main + sizes) so we don't delete a\n // file that the new upload reused (e.g. same filename on reupload\n // where Payload overwrites in place).\n const newFilenames = new Set<string>()\n if (typeof docWithMetadata.filename === 'string') {\n newFilenames.add(docWithMetadata.filename)\n }\n if (typeof docWithMetadata.sizes === 'object') {\n for (const size of Object.values(docWithMetadata.sizes || {})) {\n if (size?.filename && typeof size.filename === 'string') {\n newFilenames.add(size.filename)\n }\n }\n }\n\n const deletionPromises = filesToDelete.map(async (filename) => {\n if (filename && !newFilenames.has(filename)) {\n await adapter.handleDelete({ collection, doc: previousDoc, filename, req })\n }\n })\n\n await Promise.all(deletionPromises)\n }\n\n if (docWithMetadata !== doc) {\n return docWithMetadata\n }\n }\n } catch (err: unknown) {\n req.payload.logger.error(\n `There was an error while uploading files corresponding to the collection ${collection.slug} with filename ${doc.filename}:`,\n )\n req.payload.logger.error({ err })\n throw err\n }\n return doc\n }\n"],"names":["getIncomingFiles","getAfterChangeHook","adapter","collection","doc","operation","previousDoc","req","context","skipCloudStorage","isDraftSave","_status","isDraftOverPublished","files","data","length","uploadResults","Promise","all","filter","file","uploadReference","map","handleUpload","uploadMetadata","result","reduce","acc","metadata","docWithMetadata","Object","keys","undefined","payloadUploadSizes","payload","update","id","slug","depth","draft","filesToDelete","filename","push","sizes","concat","values","resizedFileData","newFilenames","Set","add","size","deletionPromises","has","handleDelete","err","logger","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterChange.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport { deepMergeWithSourceArrays } from 'payload'\n\nimport type { GeneratedAdapter } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\nimport {\n buildStoragePathData,\n buildUploadStoragePathData,\n} from '../utilities/buildStoragePathData.js'\nimport { getIncomingFiles } from '../utilities/getIncomingFiles.js'\nimport { appendProxyPrefix } from './afterRead.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n collectionPrefix?: string\n disablePayloadAccessControl?: boolean\n hasCustomFileURL?: boolean\n useCompositePrefixes?: boolean\n}\n\n// The object's folder: semantic prefix + `_objectKey` segment.\nconst getObjectFolder = (data: unknown): string => {\n const record = (data ?? {}) as { _objectKey?: string; prefix?: string }\n return buildPrefixWithObjectKey({ objectKey: record._objectKey, prefix: record.prefix })\n}\n\nexport const getAfterChangeHook =\n ({\n adapter,\n collection,\n collectionPrefix,\n disablePayloadAccessControl,\n hasCustomFileURL,\n useCompositePrefixes,\n }: Args): CollectionAfterChangeHook<FileData & TypeWithID> =>\n async ({ data, doc, operation, previousDoc, req, select }) => {\n // Skip if this is an internal update to prevent infinite loop\n if (req.context?.skipCloudStorage) {\n return doc\n }\n\n // Restore upload metadata removed by select, including partially selected image sizes.\n const uploadData = select ? deepMergeWithSourceArrays<FileData & TypeWithID>(data, doc) : doc\n const withProxyPrefix = (upload: FileData & TypeWithID): FileData & TypeWithID => {\n const { prefix } = upload as { prefix?: string } & FileData & TypeWithID\n\n if (disablePayloadAccessControl || hasCustomFileURL || !useCompositePrefixes || !prefix) {\n return upload\n }\n\n return {\n ...upload,\n ...(upload.url && {\n url: appendProxyPrefix({ prefix, url: upload.url }),\n }),\n ...(upload.original?.url && {\n original: {\n ...upload.original,\n url: appendProxyPrefix({ prefix, url: upload.original.url }),\n },\n }),\n }\n }\n const isDraftSave = (uploadData as { _status?: string })._status === 'draft'\n const isDraftOverPublished =\n isDraftSave && (previousDoc as { _status?: string } | undefined)?._status === 'published'\n\n if (req.context?._payloadManagedCloudStorage) {\n const metadata = req.context._payloadManagedCloudMetadata as\n | Partial<FileData & TypeWithID>\n | undefined\n\n if (!metadata || Object.keys(metadata).length === 0) {\n return withProxyPrefix(doc)\n }\n\n req.context.skipCloudStorage = true\n req.file = undefined\n req.payloadUploadSizes = undefined\n const originalQuery = req.query\n req.query = { ...req.query }\n delete req.query.uploadEdits\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: metadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n return withProxyPrefix({ ...doc, ...updatedDoc })\n } finally {\n req.query = originalQuery\n delete req.context.skipCloudStorage\n }\n }\n\n try {\n const files = getIncomingFiles({ data: uploadData, req })\n\n if (files.length > 0) {\n // Fold `_objectKey` so generated sizes land in the same folder as the original.\n const dataForUpload = { ...uploadData, prefix: getObjectFolder(uploadData) }\n\n const uploadResults = await Promise.all(\n files\n .filter((file) => !file.uploadReference)\n .map((file) =>\n adapter.handleUpload({\n collection,\n data: dataForUpload,\n file,\n req,\n storageFilePath: buildUploadStoragePathData({\n collectionPrefix,\n docPrefix: dataForUpload.prefix,\n filename: file.filename,\n useCompositePrefixes,\n }).storageFilePath,\n }),\n ),\n )\n\n const uploadMetadata = uploadResults\n .filter(\n (result): result is Partial<FileData & TypeWithID> =>\n result != null && typeof result === 'object',\n )\n .reduce(\n (acc, metadata) => ({ ...acc, ...metadata }),\n {} as Partial<FileData & TypeWithID>,\n )\n\n // Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.\n delete (uploadMetadata as Record<string, unknown>).prefix\n delete (uploadMetadata as Record<string, unknown>)._objectKey\n\n let docWithMetadata = doc\n\n if (Object.keys(uploadMetadata).length > 0) {\n if (!req.context) {\n req.context = {}\n }\n req.context.skipCloudStorage = true\n\n // Clear to prevent re-processing\n req.file = undefined\n req.payloadUploadSizes = undefined\n\n try {\n const updatedDoc = await req.payload.update({\n id: doc.id,\n collection: collection.slug,\n data: uploadMetadata,\n depth: 0,\n draft: isDraftSave,\n overrideAccess: true,\n req,\n select,\n })\n\n // Persist all adapter metadata, but do not add unselected fields to the response.\n docWithMetadata = select ? { ...doc, ...updatedDoc } : { ...doc, ...uploadMetadata }\n } finally {\n delete req.context.skipCloudStorage\n }\n }\n\n // Delete previous files only after the new upload and metadata\n // persistence have succeeded. Deleting earlier would orphan the\n // record if a later step throws (e.g. a user-defined afterChange\n // hook on the same collection).\n if (\n previousDoc &&\n operation === 'update' &&\n !isDraftOverPublished &&\n !collection.versions &&\n !previousDoc.original\n ) {\n let filesToDelete: string[] = []\n\n if (typeof previousDoc?.filename === 'string') {\n filesToDelete.push(previousDoc.filename)\n }\n\n if (typeof previousDoc.variants === 'object') {\n filesToDelete = filesToDelete.concat(\n Object.values(previousDoc?.variants || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n )\n }\n\n // Compare full locations: a replacement can reuse a filename while moving\n // a legacy object beneath the collection prefix.\n const newFileData = { ...uploadData, ...uploadMetadata }\n const newFilenames = new Set<string>()\n if (typeof newFileData.filename === 'string') {\n newFilenames.add(newFileData.filename)\n }\n if (typeof newFileData.variants === 'object') {\n for (const size of Object.values(newFileData.variants || {})) {\n if (size?.filename && typeof size.filename === 'string') {\n newFilenames.add(size.filename)\n }\n }\n }\n\n const resolveKey = ({\n data,\n filename,\n }: {\n data: { _objectKey?: string; prefix?: string }\n filename: string\n }) =>\n buildStoragePathData({\n collectionPrefix,\n docPrefix: getObjectFolder(data),\n filename,\n useCompositePrefixes,\n }).storageFilePath\n const newKeys = new Set(\n [...newFilenames].map((filename) =>\n resolveKey({\n data: newFileData as { _objectKey?: string; prefix?: string },\n filename,\n }),\n ),\n )\n\n const deletionPromises = filesToDelete.map(async (filename) => {\n if (!filename) {\n return\n }\n const storageFilePath = resolveKey({\n data: previousDoc as { _objectKey?: string; prefix?: string },\n filename,\n })\n if (!newKeys.has(storageFilePath)) {\n await adapter.handleDelete({\n collection,\n doc: previousDoc,\n filename,\n req,\n storageFilePath,\n })\n }\n })\n\n await Promise.all(deletionPromises)\n }\n\n if (docWithMetadata !== doc) {\n return docWithMetadata\n }\n }\n } catch (err: unknown) {\n req.payload.logger.error(\n `There was an error while uploading files corresponding to the collection ${collection.slug} with filename ${doc.filename}:`,\n )\n req.payload.logger.error({ err })\n throw err\n }\n return doc\n }\n"],"names":["deepMergeWithSourceArrays","buildPrefixWithObjectKey","buildStoragePathData","buildUploadStoragePathData","getIncomingFiles","appendProxyPrefix","getObjectFolder","data","record","objectKey","_objectKey","prefix","getAfterChangeHook","adapter","collection","collectionPrefix","disablePayloadAccessControl","hasCustomFileURL","useCompositePrefixes","doc","operation","previousDoc","req","select","context","skipCloudStorage","uploadData","withProxyPrefix","upload","url","original","isDraftSave","_status","isDraftOverPublished","_payloadManagedCloudStorage","metadata","_payloadManagedCloudMetadata","Object","keys","length","file","undefined","payloadUploadSizes","originalQuery","query","uploadEdits","updatedDoc","payload","update","id","slug","depth","draft","overrideAccess","files","dataForUpload","uploadResults","Promise","all","filter","uploadReference","map","handleUpload","storageFilePath","docPrefix","filename","uploadMetadata","result","reduce","acc","docWithMetadata","versions","filesToDelete","push","variants","concat","values","resizedFileData","newFileData","newFilenames","Set","add","size","resolveKey","newKeys","deletionPromises","has","handleDelete","err","logger","error"],"mappings":"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"}
|
|
@@ -3,7 +3,9 @@ import type { GeneratedAdapter, TypeWithPrefix } from '../types.js';
|
|
|
3
3
|
interface Args {
|
|
4
4
|
adapter: GeneratedAdapter;
|
|
5
5
|
collection: CollectionConfig;
|
|
6
|
+
collectionPrefix?: string;
|
|
7
|
+
useCompositePrefixes?: boolean;
|
|
6
8
|
}
|
|
7
|
-
export declare const getAfterDeleteHook: ({ adapter, collection, }: Args) => CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix>;
|
|
9
|
+
export declare const getAfterDeleteHook: ({ adapter, collection, collectionPrefix, useCompositePrefixes, }: Args) => CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix>;
|
|
8
10
|
export {};
|
|
9
11
|
//# sourceMappingURL=afterDelete.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAKnE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,eAAO,MAAM,kBAAkB,qEAK5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CAiDzE,CAAA"}
|
|
@@ -1,17 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
|
|
2
|
+
import { buildStoragePathData } from '../utilities/buildStoragePathData.js';
|
|
3
|
+
export const getAfterDeleteHook = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>{
|
|
4
|
+
return async ({ id, doc, req })=>{
|
|
5
|
+
// Managed objects are deleted after the operation commits and all references are checked.
|
|
6
|
+
const managedDeletedUploads = req.context?._payloadManagedDeletedUploads;
|
|
7
|
+
if (collection.versions || Boolean(doc.original) && typeof doc.original?.filename === 'string' || managedDeletedUploads?.has(JSON.stringify([
|
|
8
|
+
collection.slug,
|
|
9
|
+
String(id)
|
|
10
|
+
]))) {
|
|
11
|
+
return doc;
|
|
12
|
+
}
|
|
3
13
|
try {
|
|
14
|
+
// Fold `_objectKey` so deletes target the real object folder.
|
|
15
|
+
const docPrefix = buildPrefixWithObjectKey({
|
|
16
|
+
objectKey: doc._objectKey,
|
|
17
|
+
prefix: doc.prefix
|
|
18
|
+
});
|
|
4
19
|
const filesToDelete = [
|
|
5
20
|
doc.filename,
|
|
6
|
-
...Object.values(doc?.
|
|
21
|
+
...Object.values(doc?.variants || []).map((resizedFileData)=>resizedFileData?.filename)
|
|
7
22
|
];
|
|
8
23
|
const promises = filesToDelete.map(async (filename)=>{
|
|
9
24
|
if (filename) {
|
|
25
|
+
const { storageFilePath } = buildStoragePathData({
|
|
26
|
+
collectionPrefix,
|
|
27
|
+
docPrefix,
|
|
28
|
+
filename,
|
|
29
|
+
useCompositePrefixes
|
|
30
|
+
});
|
|
10
31
|
await adapter.handleDelete({
|
|
11
32
|
collection,
|
|
12
33
|
doc,
|
|
13
34
|
filename,
|
|
14
|
-
req
|
|
35
|
+
req,
|
|
36
|
+
storageFilePath
|
|
15
37
|
});
|
|
16
38
|
}
|
|
17
39
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterDelete.ts"],"sourcesContent":["import type { CollectionAfterDeleteHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter, TypeWithPrefix } from '../types.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n}\n\nexport const getAfterDeleteHook = ({\n adapter,\n collection,\n}: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {\n return async ({ doc, req }) => {\n try {\n const filesToDelete: string[] = [\n doc.filename,\n ...Object.values(doc?.
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterDelete.ts"],"sourcesContent":["import type { CollectionAfterDeleteHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter, TypeWithPrefix } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\nimport { buildStoragePathData } from '../utilities/buildStoragePathData.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n collectionPrefix?: string\n useCompositePrefixes?: boolean\n}\n\nexport const getAfterDeleteHook = ({\n adapter,\n collection,\n collectionPrefix,\n useCompositePrefixes,\n}: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {\n return async ({ id, doc, req }) => {\n // Managed objects are deleted after the operation commits and all references are checked.\n const managedDeletedUploads = req.context?._payloadManagedDeletedUploads as\n | Set<string>\n | undefined\n if (\n collection.versions ||\n (Boolean(doc.original) && typeof doc.original?.filename === 'string') ||\n managedDeletedUploads?.has(JSON.stringify([collection.slug, String(id)]))\n ) {\n return doc\n }\n\n try {\n // Fold `_objectKey` so deletes target the real object folder.\n const docPrefix = buildPrefixWithObjectKey({\n objectKey: (doc as { _objectKey?: string })._objectKey,\n prefix: doc.prefix,\n })\n\n const filesToDelete: string[] = [\n doc.filename,\n ...Object.values(doc?.variants || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n ]\n\n const promises = filesToDelete.map(async (filename) => {\n if (filename) {\n const { storageFilePath } = buildStoragePathData({\n collectionPrefix,\n docPrefix,\n filename,\n useCompositePrefixes,\n })\n await adapter.handleDelete({ collection, doc, filename, req, storageFilePath })\n }\n })\n\n await Promise.all(promises)\n } catch (err: unknown) {\n req.payload.logger.error({\n err,\n msg: `There was an error while deleting files corresponding to the ${collection.labels?.singular} with ID ${doc.id}.`,\n })\n }\n return doc\n }\n}\n"],"names":["buildPrefixWithObjectKey","buildStoragePathData","getAfterDeleteHook","adapter","collection","collectionPrefix","useCompositePrefixes","id","doc","req","managedDeletedUploads","context","_payloadManagedDeletedUploads","versions","Boolean","original","filename","has","JSON","stringify","slug","String","docPrefix","objectKey","_objectKey","prefix","filesToDelete","Object","values","variants","map","resizedFileData","promises","storageFilePath","handleDelete","Promise","all","err","payload","logger","error","msg","labels","singular"],"mappings":"AAIA,SAASA,wBAAwB,QAAQ,2CAA0C;AACnF,SAASC,oBAAoB,QAAQ,uCAAsC;AAS3E,OAAO,MAAMC,qBAAqB,CAAC,EACjCC,OAAO,EACPC,UAAU,EACVC,gBAAgB,EAChBC,oBAAoB,EACf;IACL,OAAO,OAAO,EAAEC,EAAE,EAAEC,GAAG,EAAEC,GAAG,EAAE;QAC5B,0FAA0F;QAC1F,MAAMC,wBAAwBD,IAAIE,OAAO,EAAEC;QAG3C,IACER,WAAWS,QAAQ,IAClBC,QAAQN,IAAIO,QAAQ,KAAK,OAAOP,IAAIO,QAAQ,EAAEC,aAAa,YAC5DN,uBAAuBO,IAAIC,KAAKC,SAAS,CAAC;YAACf,WAAWgB,IAAI;YAAEC,OAAOd;SAAI,IACvE;YACA,OAAOC;QACT;QAEA,IAAI;YACF,8DAA8D;YAC9D,MAAMc,YAAYtB,yBAAyB;gBACzCuB,WAAW,AAACf,IAAgCgB,UAAU;gBACtDC,QAAQjB,IAAIiB,MAAM;YACpB;YAEA,MAAMC,gBAA0B;gBAC9BlB,IAAIQ,QAAQ;mBACTW,OAAOC,MAAM,CAACpB,KAAKqB,YAAY,EAAE,EAAEC,GAAG,CACvC,CAACC,kBAAoBA,iBAAiBf;aAEzC;YAED,MAAMgB,WAAWN,cAAcI,GAAG,CAAC,OAAOd;gBACxC,IAAIA,UAAU;oBACZ,MAAM,EAAEiB,eAAe,EAAE,GAAGhC,qBAAqB;wBAC/CI;wBACAiB;wBACAN;wBACAV;oBACF;oBACA,MAAMH,QAAQ+B,YAAY,CAAC;wBAAE9B;wBAAYI;wBAAKQ;wBAAUP;wBAAKwB;oBAAgB;gBAC/E;YACF;YAEA,MAAME,QAAQC,GAAG,CAACJ;QACpB,EAAE,OAAOK,KAAc;YACrB5B,IAAI6B,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBACvBH;gBACAI,KAAK,CAAC,6DAA6D,EAAErC,WAAWsC,MAAM,EAAEC,SAAS,SAAS,EAAEnC,IAAID,EAAE,CAAC,CAAC,CAAC;YACvH;QACF;QACA,OAAOC;IACT;AACF,EAAC"}
|
|
@@ -5,8 +5,13 @@ interface Args {
|
|
|
5
5
|
collection: CollectionConfig;
|
|
6
6
|
disablePayloadAccessControl?: boolean;
|
|
7
7
|
generateFileURL?: GenerateFileURL;
|
|
8
|
+
isOriginal?: boolean;
|
|
8
9
|
size?: ImageSize;
|
|
9
10
|
}
|
|
10
|
-
export declare const getAfterReadHook: ({ adapter, collection, disablePayloadAccessControl, generateFileURL, size }: Args) => FieldHook;
|
|
11
|
+
export declare const getAfterReadHook: ({ adapter, collection, disablePayloadAccessControl, generateFileURL, isOriginal, size, }: Args) => FieldHook;
|
|
12
|
+
export declare const appendProxyPrefix: ({ prefix, url }: {
|
|
13
|
+
prefix: string;
|
|
14
|
+
url: string;
|
|
15
|
+
}) => string;
|
|
11
16
|
export {};
|
|
12
17
|
//# sourceMappingURL=afterRead.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"afterRead.d.ts","sourceRoot":"","sources":["../../src/hooks/afterRead.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"afterRead.d.ts","sourceRoot":"","sources":["../../src/hooks/afterRead.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAiBD,eAAO,MAAM,gBAAgB,6FAQxB,IAAI,KAAG,SAkCT,CAAA;AAEH,eAAO,MAAM,iBAAiB,oBAAqB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAG,MAMpF,CAAA"}
|
package/dist/hooks/afterRead.js
CHANGED
|
@@ -1,13 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
2
|
+
// The object's folder: semantic prefix + `_objectKey` segment.
|
|
3
|
+
const getObjectFolder = (data)=>{
|
|
4
|
+
const record = data ?? {};
|
|
5
|
+
const safePrefix = sanitizePrefix(typeof record.prefix === 'string' ? record.prefix : '');
|
|
6
|
+
const safeObjectKey = sanitizePrefix(typeof record._objectKey === 'string' ? record._objectKey : '');
|
|
7
|
+
if (safePrefix && safeObjectKey) {
|
|
8
|
+
return `${safePrefix}/${safeObjectKey}`;
|
|
9
|
+
}
|
|
10
|
+
return safePrefix || safeObjectKey;
|
|
11
|
+
};
|
|
12
|
+
export const getAfterReadHook = ({ adapter, collection, disablePayloadAccessControl, generateFileURL, isOriginal, size })=>async ({ data, value })=>{
|
|
13
|
+
const representation = isOriginal ? data?.original : size ? data?.variants?.[size.name] : data;
|
|
14
|
+
const filename = representation?.filename;
|
|
15
|
+
const hasLegacyVariant = Boolean(size && !data?.original?.filename);
|
|
16
|
+
const prefix = representation?.prefix ?? (hasLegacyVariant ? data?.prefix : undefined);
|
|
17
|
+
// Direct-serve URLs encode the full location; the proxy resolves `_objectKey` server-side.
|
|
18
|
+
const objectFolder = getObjectFolder({
|
|
19
|
+
_objectKey: representation?._objectKey ?? (hasLegacyVariant ? data?._objectKey : undefined),
|
|
20
|
+
prefix
|
|
21
|
+
});
|
|
4
22
|
let url = value;
|
|
5
23
|
if (filename) {
|
|
6
24
|
if (generateFileURL) {
|
|
7
25
|
url = await generateFileURL({
|
|
8
26
|
collection,
|
|
9
27
|
filename,
|
|
10
|
-
prefix,
|
|
28
|
+
prefix: objectFolder,
|
|
11
29
|
size
|
|
12
30
|
});
|
|
13
31
|
} else if (disablePayloadAccessControl && adapter.generateURL) {
|
|
@@ -15,14 +33,23 @@ export const getAfterReadHook = ({ adapter, collection, disablePayloadAccessCont
|
|
|
15
33
|
collection,
|
|
16
34
|
data,
|
|
17
35
|
filename,
|
|
18
|
-
prefix
|
|
36
|
+
prefix: objectFolder
|
|
19
37
|
});
|
|
20
38
|
} else if (url && prefix) {
|
|
21
|
-
|
|
22
|
-
|
|
39
|
+
url = appendProxyPrefix({
|
|
40
|
+
prefix,
|
|
41
|
+
url
|
|
42
|
+
});
|
|
23
43
|
}
|
|
24
44
|
}
|
|
25
45
|
return url;
|
|
26
46
|
};
|
|
47
|
+
export const appendProxyPrefix = ({ prefix, url })=>{
|
|
48
|
+
if (new URL(url, 'http://payload.local').searchParams.has('prefix')) {
|
|
49
|
+
return url;
|
|
50
|
+
}
|
|
51
|
+
const separator = url.includes('?') ? '&' : '?';
|
|
52
|
+
return `${url}${separator}prefix=${encodeURIComponent(prefix)}`;
|
|
53
|
+
};
|
|
27
54
|
|
|
28
55
|
//# sourceMappingURL=afterRead.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/afterRead.ts"],"sourcesContent":["import type { CollectionConfig, FieldHook, ImageSize } from 'payload'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: boolean\n generateFileURL?: GenerateFileURL\n size?: ImageSize\n}\n\nexport const getAfterReadHook =\n ({
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/afterRead.ts"],"sourcesContent":["import type { CollectionConfig, FieldHook, ImageSize } from 'payload'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\nimport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: boolean\n generateFileURL?: GenerateFileURL\n isOriginal?: boolean\n size?: ImageSize\n}\n\n// The object's folder: semantic prefix + `_objectKey` segment.\nconst getObjectFolder = (data: unknown): string => {\n const record = (data ?? {}) as Record<string, unknown>\n const safePrefix = sanitizePrefix(typeof record.prefix === 'string' ? record.prefix : '')\n const safeObjectKey = sanitizePrefix(\n typeof record._objectKey === 'string' ? record._objectKey : '',\n )\n\n if (safePrefix && safeObjectKey) {\n return `${safePrefix}/${safeObjectKey}`\n }\n\n return safePrefix || safeObjectKey\n}\n\nexport const getAfterReadHook =\n ({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal,\n size,\n }: Args): FieldHook =>\n async ({ data, value }) => {\n const representation = isOriginal ? data?.original : size ? data?.variants?.[size.name] : data\n const filename = representation?.filename\n const hasLegacyVariant = Boolean(size && !data?.original?.filename)\n const prefix = representation?.prefix ?? (hasLegacyVariant ? data?.prefix : undefined)\n // Direct-serve URLs encode the full location; the proxy resolves `_objectKey` server-side.\n const objectFolder = getObjectFolder({\n _objectKey: representation?._objectKey ?? (hasLegacyVariant ? data?._objectKey : undefined),\n prefix,\n })\n let url = value\n\n if (filename) {\n if (generateFileURL) {\n url = await generateFileURL({\n collection,\n filename,\n prefix: objectFolder,\n size,\n })\n } else if (disablePayloadAccessControl && adapter.generateURL) {\n url = await adapter.generateURL({\n collection,\n data,\n filename,\n prefix: objectFolder,\n })\n } else if (url && prefix) {\n url = appendProxyPrefix({ prefix, url })\n }\n }\n\n return url\n }\n\nexport const appendProxyPrefix = ({ prefix, url }: { prefix: string; url: string }): string => {\n if (new URL(url, 'http://payload.local').searchParams.has('prefix')) {\n return url\n }\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}prefix=${encodeURIComponent(prefix)}`\n}\n"],"names":["sanitizePrefix","getObjectFolder","data","record","safePrefix","prefix","safeObjectKey","_objectKey","getAfterReadHook","adapter","collection","disablePayloadAccessControl","generateFileURL","isOriginal","size","value","representation","original","variants","name","filename","hasLegacyVariant","Boolean","undefined","objectFolder","url","generateURL","appendProxyPrefix","URL","searchParams","has","separator","includes","encodeURIComponent"],"mappings":"AAIA,SAASA,cAAc,QAAQ,iCAAgC;AAW/D,+DAA+D;AAC/D,MAAMC,kBAAkB,CAACC;IACvB,MAAMC,SAAUD,QAAQ,CAAC;IACzB,MAAME,aAAaJ,eAAe,OAAOG,OAAOE,MAAM,KAAK,WAAWF,OAAOE,MAAM,GAAG;IACtF,MAAMC,gBAAgBN,eACpB,OAAOG,OAAOI,UAAU,KAAK,WAAWJ,OAAOI,UAAU,GAAG;IAG9D,IAAIH,cAAcE,eAAe;QAC/B,OAAO,GAAGF,WAAW,CAAC,EAAEE,eAAe;IACzC;IAEA,OAAOF,cAAcE;AACvB;AAEA,OAAO,MAAME,mBACX,CAAC,EACCC,OAAO,EACPC,UAAU,EACVC,2BAA2B,EAC3BC,eAAe,EACfC,UAAU,EACVC,IAAI,EACC,GACP,OAAO,EAAEZ,IAAI,EAAEa,KAAK,EAAE;QACpB,MAAMC,iBAAiBH,aAAaX,MAAMe,WAAWH,OAAOZ,MAAMgB,UAAU,CAACJ,KAAKK,IAAI,CAAC,GAAGjB;QAC1F,MAAMkB,WAAWJ,gBAAgBI;QACjC,MAAMC,mBAAmBC,QAAQR,QAAQ,CAACZ,MAAMe,UAAUG;QAC1D,MAAMf,SAASW,gBAAgBX,UAAWgB,CAAAA,mBAAmBnB,MAAMG,SAASkB,SAAQ;QACpF,2FAA2F;QAC3F,MAAMC,eAAevB,gBAAgB;YACnCM,YAAYS,gBAAgBT,cAAec,CAAAA,mBAAmBnB,MAAMK,aAAagB,SAAQ;YACzFlB;QACF;QACA,IAAIoB,MAAMV;QAEV,IAAIK,UAAU;YACZ,IAAIR,iBAAiB;gBACnBa,MAAM,MAAMb,gBAAgB;oBAC1BF;oBACAU;oBACAf,QAAQmB;oBACRV;gBACF;YACF,OAAO,IAAIH,+BAA+BF,QAAQiB,WAAW,EAAE;gBAC7DD,MAAM,MAAMhB,QAAQiB,WAAW,CAAC;oBAC9BhB;oBACAR;oBACAkB;oBACAf,QAAQmB;gBACV;YACF,OAAO,IAAIC,OAAOpB,QAAQ;gBACxBoB,MAAME,kBAAkB;oBAAEtB;oBAAQoB;gBAAI;YACxC;QACF;QAEA,OAAOA;IACT,EAAC;AAEH,OAAO,MAAME,oBAAoB,CAAC,EAAEtB,MAAM,EAAEoB,GAAG,EAAmC;IAChF,IAAI,IAAIG,IAAIH,KAAK,wBAAwBI,YAAY,CAACC,GAAG,CAAC,WAAW;QACnE,OAAOL;IACT;IACA,MAAMM,YAAYN,IAAIO,QAAQ,CAAC,OAAO,MAAM;IAC5C,OAAO,GAAGP,MAAMM,UAAU,OAAO,EAAEE,mBAAmB5B,SAAS;AACjE,EAAC"}
|
|
@@ -5,8 +5,9 @@ interface Args {
|
|
|
5
5
|
collection: CollectionConfig;
|
|
6
6
|
disablePayloadAccessControl?: boolean;
|
|
7
7
|
generateFileURL?: GenerateFileURL;
|
|
8
|
+
isOriginal?: boolean;
|
|
8
9
|
size?: ImageSize;
|
|
9
10
|
}
|
|
10
|
-
export declare const getBeforeChangeHook: ({ adapter, collection, disablePayloadAccessControl, generateFileURL, size }: Args) => FieldHook;
|
|
11
|
+
export declare const getBeforeChangeHook: ({ adapter, collection, disablePayloadAccessControl, generateFileURL, isOriginal, size, }: Args) => FieldHook;
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=beforeChange.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAErE,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIpE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAA;IACrC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAiBD,eAAO,MAAM,mBAAmB,6FAQ3B,IAAI,KAAG,SAoCT,CAAA"}
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { sanitizePrefix } from '../utilities/sanitizePrefix.js';
|
|
2
|
+
// The object's folder: semantic prefix + `_objectKey` segment.
|
|
3
|
+
const getObjectFolder = (data, originalDoc)=>{
|
|
4
|
+
const source = data ?? originalDoc ?? {};
|
|
5
|
+
const safePrefix = sanitizePrefix(typeof source.prefix === 'string' ? source.prefix : '');
|
|
6
|
+
const safeObjectKey = sanitizePrefix(typeof source._objectKey === 'string' ? source._objectKey : '');
|
|
7
|
+
if (safePrefix && safeObjectKey) {
|
|
8
|
+
return `${safePrefix}/${safeObjectKey}`;
|
|
9
|
+
}
|
|
10
|
+
return safePrefix || safeObjectKey;
|
|
11
|
+
};
|
|
12
|
+
export const getBeforeChangeHook = ({ adapter, collection, disablePayloadAccessControl, generateFileURL, isOriginal, size })=>async ({ data, originalDoc, value })=>{
|
|
13
|
+
const newRepresentation = isOriginal ? data?.original : size ? data?.variants?.[size.name] : data;
|
|
14
|
+
const originalRepresentation = isOriginal ? originalDoc?.original : size ? originalDoc?.variants?.[size.name] : originalDoc;
|
|
15
|
+
const newFilename = newRepresentation?.filename;
|
|
16
|
+
const originalFilename = originalRepresentation?.filename;
|
|
4
17
|
const filename = newFilename || originalFilename;
|
|
5
|
-
const
|
|
18
|
+
const representation = newRepresentation ?? originalRepresentation;
|
|
19
|
+
const prefix = getObjectFolder(representation, data ?? originalDoc);
|
|
6
20
|
let url = value;
|
|
7
21
|
if (generateFileURL && filename) {
|
|
8
22
|
url = await generateFileURL({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/beforeChange.ts"],"sourcesContent":["import type { CollectionConfig, FieldHook, ImageSize } from 'payload'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: boolean\n generateFileURL?: GenerateFileURL\n size?: ImageSize\n}\n\nexport const getBeforeChangeHook =\n ({
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/beforeChange.ts"],"sourcesContent":["import type { CollectionConfig, FieldHook, ImageSize } from 'payload'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\nimport { sanitizePrefix } from '../utilities/sanitizePrefix.js'\n\ninterface Args {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n disablePayloadAccessControl?: boolean\n generateFileURL?: GenerateFileURL\n isOriginal?: boolean\n size?: ImageSize\n}\n\n// The object's folder: semantic prefix + `_objectKey` segment.\nconst getObjectFolder = (data: unknown, originalDoc: unknown): string => {\n const source = (data ?? originalDoc ?? {}) as Record<string, unknown>\n const safePrefix = sanitizePrefix(typeof source.prefix === 'string' ? source.prefix : '')\n const safeObjectKey = sanitizePrefix(\n typeof source._objectKey === 'string' ? source._objectKey : '',\n )\n\n if (safePrefix && safeObjectKey) {\n return `${safePrefix}/${safeObjectKey}`\n }\n\n return safePrefix || safeObjectKey\n}\n\nexport const getBeforeChangeHook =\n ({\n adapter,\n collection,\n disablePayloadAccessControl,\n generateFileURL,\n isOriginal,\n size,\n }: Args): FieldHook =>\n async ({ data, originalDoc, value }) => {\n const newRepresentation = isOriginal\n ? data?.original\n : size\n ? data?.variants?.[size.name]\n : data\n const originalRepresentation = isOriginal\n ? originalDoc?.original\n : size\n ? originalDoc?.variants?.[size.name]\n : originalDoc\n const newFilename = newRepresentation?.filename\n const originalFilename = originalRepresentation?.filename\n const filename = newFilename || originalFilename\n const representation = newRepresentation ?? originalRepresentation\n const prefix = getObjectFolder(representation, data ?? originalDoc)\n let url = value\n\n if (generateFileURL && filename) {\n url = await generateFileURL({\n collection,\n filename,\n prefix,\n size,\n })\n } else if (disablePayloadAccessControl && filename && adapter.generateURL) {\n url = await adapter.generateURL({\n collection,\n data: data || originalDoc,\n filename,\n prefix,\n })\n }\n\n return url\n }\n"],"names":["sanitizePrefix","getObjectFolder","data","originalDoc","source","safePrefix","prefix","safeObjectKey","_objectKey","getBeforeChangeHook","adapter","collection","disablePayloadAccessControl","generateFileURL","isOriginal","size","value","newRepresentation","original","variants","name","originalRepresentation","newFilename","filename","originalFilename","representation","url","generateURL"],"mappings":"AAIA,SAASA,cAAc,QAAQ,iCAAgC;AAW/D,+DAA+D;AAC/D,MAAMC,kBAAkB,CAACC,MAAeC;IACtC,MAAMC,SAAUF,QAAQC,eAAe,CAAC;IACxC,MAAME,aAAaL,eAAe,OAAOI,OAAOE,MAAM,KAAK,WAAWF,OAAOE,MAAM,GAAG;IACtF,MAAMC,gBAAgBP,eACpB,OAAOI,OAAOI,UAAU,KAAK,WAAWJ,OAAOI,UAAU,GAAG;IAG9D,IAAIH,cAAcE,eAAe;QAC/B,OAAO,GAAGF,WAAW,CAAC,EAAEE,eAAe;IACzC;IAEA,OAAOF,cAAcE;AACvB;AAEA,OAAO,MAAME,sBACX,CAAC,EACCC,OAAO,EACPC,UAAU,EACVC,2BAA2B,EAC3BC,eAAe,EACfC,UAAU,EACVC,IAAI,EACC,GACP,OAAO,EAAEb,IAAI,EAAEC,WAAW,EAAEa,KAAK,EAAE;QACjC,MAAMC,oBAAoBH,aACtBZ,MAAMgB,WACNH,OACEb,MAAMiB,UAAU,CAACJ,KAAKK,IAAI,CAAC,GAC3BlB;QACN,MAAMmB,yBAAyBP,aAC3BX,aAAae,WACbH,OACEZ,aAAagB,UAAU,CAACJ,KAAKK,IAAI,CAAC,GAClCjB;QACN,MAAMmB,cAAcL,mBAAmBM;QACvC,MAAMC,mBAAmBH,wBAAwBE;QACjD,MAAMA,WAAWD,eAAeE;QAChC,MAAMC,iBAAiBR,qBAAqBI;QAC5C,MAAMf,SAASL,gBAAgBwB,gBAAgBvB,QAAQC;QACvD,IAAIuB,MAAMV;QAEV,IAAIH,mBAAmBU,UAAU;YAC/BG,MAAM,MAAMb,gBAAgB;gBAC1BF;gBACAY;gBACAjB;gBACAS;YACF;QACF,OAAO,IAAIH,+BAA+BW,YAAYb,QAAQiB,WAAW,EAAE;YACzED,MAAM,MAAMhB,QAAQiB,WAAW,CAAC;gBAC9BhB;gBACAT,MAAMA,QAAQC;gBACdoB;gBACAjB;YACF;QACF;QAEA,OAAOoB;IACT,EAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CollectionBeforeChangeHook, FieldHook } from 'payload';
|
|
2
|
+
type Args = {
|
|
3
|
+
collectionPrefix?: string;
|
|
4
|
+
useCompositePrefixes?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/** Persist new upload destinations without reinterpreting metadata-only updates. */
|
|
7
|
+
export declare const getNormalizeUploadPrefixHook: ({ collectionPrefix, useCompositePrefixes }: Args) => CollectionBeforeChangeHook;
|
|
8
|
+
/** Run last on the prefix field so user hooks cannot leave stale storage coordinates. */
|
|
9
|
+
export declare const getNormalizeUploadPrefixFieldHook: ({ collectionPrefix, useCompositePrefixes }: Args) => FieldHook;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=normalizeUploadPrefix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeUploadPrefix.d.ts","sourceRoot":"","sources":["../../src/hooks/normalizeUploadPrefix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIpE,KAAK,IAAI,GAAG;IACV,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B,CAAA;AAiBD,oFAAoF;AACpF,eAAO,MAAM,4BAA4B,+CACM,IAAI,KAAG,0BAiBnD,CAAA;AAEH,yFAAyF;AACzF,eAAO,MAAM,iCAAiC,+CACC,IAAI,KAAG,SAenD,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { buildUploadPrefix } from '../utilities/buildStoragePathData.js';
|
|
2
|
+
/**
|
|
3
|
+
* A prefix the caller did not supply, or supplied unchanged, is left as stored so
|
|
4
|
+
* pre-upgrade files keep resolving to their original object keys. Anything the caller
|
|
5
|
+
* chooses is contained, because `prefix` is writable through the REST, GraphQL and
|
|
6
|
+
* Local APIs and the read path trusts whatever is persisted.
|
|
7
|
+
*/ const isPrefixSupplied = ({ storedPrefix, value })=>typeof value === 'string' && value !== (typeof storedPrefix === 'string' ? storedPrefix : '');
|
|
8
|
+
/** Persist new upload destinations without reinterpreting metadata-only updates. */ export const getNormalizeUploadPrefixHook = ({ collectionPrefix, useCompositePrefixes })=>({ data, originalDoc, req })=>{
|
|
9
|
+
if (req.context?.skipCloudStorage) {
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
if (!req.file && !isPrefixSupplied({
|
|
13
|
+
storedPrefix: originalDoc?.prefix,
|
|
14
|
+
value: data.prefix
|
|
15
|
+
})) {
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
data.prefix = buildUploadPrefix({
|
|
19
|
+
collectionPrefix,
|
|
20
|
+
docPrefix: typeof data.prefix === 'string' ? data.prefix : '',
|
|
21
|
+
useCompositePrefixes
|
|
22
|
+
}).sanitizedDocPrefix;
|
|
23
|
+
return data;
|
|
24
|
+
};
|
|
25
|
+
/** Run last on the prefix field so user hooks cannot leave stale storage coordinates. */ export const getNormalizeUploadPrefixFieldHook = ({ collectionPrefix, useCompositePrefixes })=>({ previousValue, req, value })=>{
|
|
26
|
+
if (req.context?.skipCloudStorage) {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
if (!req.file && !isPrefixSupplied({
|
|
30
|
+
storedPrefix: previousValue,
|
|
31
|
+
value
|
|
32
|
+
})) {
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
return buildUploadPrefix({
|
|
36
|
+
collectionPrefix,
|
|
37
|
+
docPrefix: typeof value === 'string' ? value : '',
|
|
38
|
+
useCompositePrefixes
|
|
39
|
+
}).sanitizedDocPrefix;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=normalizeUploadPrefix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/normalizeUploadPrefix.ts"],"sourcesContent":["import type { CollectionBeforeChangeHook, FieldHook } from 'payload'\n\nimport { buildUploadPrefix } from '../utilities/buildStoragePathData.js'\n\ntype Args = {\n collectionPrefix?: string\n useCompositePrefixes?: boolean\n}\n\n/**\n * A prefix the caller did not supply, or supplied unchanged, is left as stored so\n * pre-upgrade files keep resolving to their original object keys. Anything the caller\n * chooses is contained, because `prefix` is writable through the REST, GraphQL and\n * Local APIs and the read path trusts whatever is persisted.\n */\nconst isPrefixSupplied = ({\n storedPrefix,\n value,\n}: {\n storedPrefix: unknown\n value: unknown\n}): boolean =>\n typeof value === 'string' && value !== (typeof storedPrefix === 'string' ? storedPrefix : '')\n\n/** Persist new upload destinations without reinterpreting metadata-only updates. */\nexport const getNormalizeUploadPrefixHook =\n ({ collectionPrefix, useCompositePrefixes }: Args): CollectionBeforeChangeHook =>\n ({ data, originalDoc, req }) => {\n if (req.context?.skipCloudStorage) {\n return data\n }\n\n if (!req.file && !isPrefixSupplied({ storedPrefix: originalDoc?.prefix, value: data.prefix })) {\n return data\n }\n\n data.prefix = buildUploadPrefix({\n collectionPrefix,\n docPrefix: typeof data.prefix === 'string' ? data.prefix : '',\n useCompositePrefixes,\n }).sanitizedDocPrefix\n\n return data\n }\n\n/** Run last on the prefix field so user hooks cannot leave stale storage coordinates. */\nexport const getNormalizeUploadPrefixFieldHook =\n ({ collectionPrefix, useCompositePrefixes }: Args): FieldHook =>\n ({ previousValue, req, value }) => {\n if (req.context?.skipCloudStorage) {\n return value\n }\n\n if (!req.file && !isPrefixSupplied({ storedPrefix: previousValue, value })) {\n return value\n }\n\n return buildUploadPrefix({\n collectionPrefix,\n docPrefix: typeof value === 'string' ? value : '',\n useCompositePrefixes,\n }).sanitizedDocPrefix\n }\n"],"names":["buildUploadPrefix","isPrefixSupplied","storedPrefix","value","getNormalizeUploadPrefixHook","collectionPrefix","useCompositePrefixes","data","originalDoc","req","context","skipCloudStorage","file","prefix","docPrefix","sanitizedDocPrefix","getNormalizeUploadPrefixFieldHook","previousValue"],"mappings":"AAEA,SAASA,iBAAiB,QAAQ,uCAAsC;AAOxE;;;;;CAKC,GACD,MAAMC,mBAAmB,CAAC,EACxBC,YAAY,EACZC,KAAK,EAIN,GACC,OAAOA,UAAU,YAAYA,UAAW,CAAA,OAAOD,iBAAiB,WAAWA,eAAe,EAAC;AAE7F,kFAAkF,GAClF,OAAO,MAAME,+BACX,CAAC,EAAEC,gBAAgB,EAAEC,oBAAoB,EAAQ,GACjD,CAAC,EAAEC,IAAI,EAAEC,WAAW,EAAEC,GAAG,EAAE;QACzB,IAAIA,IAAIC,OAAO,EAAEC,kBAAkB;YACjC,OAAOJ;QACT;QAEA,IAAI,CAACE,IAAIG,IAAI,IAAI,CAACX,iBAAiB;YAAEC,cAAcM,aAAaK;YAAQV,OAAOI,KAAKM,MAAM;QAAC,IAAI;YAC7F,OAAON;QACT;QAEAA,KAAKM,MAAM,GAAGb,kBAAkB;YAC9BK;YACAS,WAAW,OAAOP,KAAKM,MAAM,KAAK,WAAWN,KAAKM,MAAM,GAAG;YAC3DP;QACF,GAAGS,kBAAkB;QAErB,OAAOR;IACT,EAAC;AAEH,uFAAuF,GACvF,OAAO,MAAMS,oCACX,CAAC,EAAEX,gBAAgB,EAAEC,oBAAoB,EAAQ,GACjD,CAAC,EAAEW,aAAa,EAAER,GAAG,EAAEN,KAAK,EAAE;QAC5B,IAAIM,IAAIC,OAAO,EAAEC,kBAAkB;YACjC,OAAOR;QACT;QAEA,IAAI,CAACM,IAAIG,IAAI,IAAI,CAACX,iBAAiB;YAAEC,cAAce;YAAed;QAAM,IAAI;YAC1E,OAAOA;QACT;QAEA,OAAOH,kBAAkB;YACvBK;YACAS,WAAW,OAAOX,UAAU,WAAWA,QAAQ;YAC/CG;QACF,GAAGS,kBAAkB;IACvB,EAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CollectionAfterReadHook, CollectionConfig } from 'payload';
|
|
2
|
+
import type { GeneratedAdapter, GenerateFileURL } from '../types.js';
|
|
3
|
+
export declare const getPublicOriginalURLHook: ({ adapter, collection, generateFileURL, }: {
|
|
4
|
+
adapter: GeneratedAdapter;
|
|
5
|
+
collection: CollectionConfig;
|
|
6
|
+
generateFileURL?: GenerateFileURL;
|
|
7
|
+
}) => CollectionAfterReadHook;
|
|
8
|
+
//# sourceMappingURL=publicOriginalURL.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publicOriginalURL.d.ts","sourceRoot":"","sources":["../../src/hooks/publicOriginalURL.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAwB,MAAM,SAAS,CAAA;AAE9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAIpE,eAAO,MAAM,wBAAwB,8CAKhC;IACD,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,KAAG,uBAsBH,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
|
|
2
|
+
export const getPublicOriginalURLHook = ({ adapter, collection, generateFileURL })=>async ({ doc })=>{
|
|
3
|
+
const upload = doc;
|
|
4
|
+
const filename = upload.original?.filename;
|
|
5
|
+
if (!filename) {
|
|
6
|
+
return doc;
|
|
7
|
+
}
|
|
8
|
+
if (upload.original?.url && !upload.original.url.startsWith('/')) {
|
|
9
|
+
return doc;
|
|
10
|
+
}
|
|
11
|
+
const prefix = buildPrefixWithObjectKey({
|
|
12
|
+
objectKey: upload.original?._objectKey,
|
|
13
|
+
prefix: upload.original?.prefix
|
|
14
|
+
});
|
|
15
|
+
const url = generateFileURL ? await generateFileURL({
|
|
16
|
+
collection,
|
|
17
|
+
filename,
|
|
18
|
+
prefix
|
|
19
|
+
}) : await adapter.generateURL?.({
|
|
20
|
+
collection,
|
|
21
|
+
data: upload,
|
|
22
|
+
filename,
|
|
23
|
+
prefix
|
|
24
|
+
});
|
|
25
|
+
return url ? {
|
|
26
|
+
...doc,
|
|
27
|
+
original: {
|
|
28
|
+
...upload.original,
|
|
29
|
+
url
|
|
30
|
+
}
|
|
31
|
+
} : doc;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=publicOriginalURL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/publicOriginalURL.ts"],"sourcesContent":["import type { CollectionAfterReadHook, CollectionConfig, FileData, TypeWithID } from 'payload'\n\nimport type { GeneratedAdapter, GenerateFileURL } from '../types.js'\n\nimport { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js'\n\nexport const getPublicOriginalURLHook =\n ({\n adapter,\n collection,\n generateFileURL,\n }: {\n adapter: GeneratedAdapter\n collection: CollectionConfig\n generateFileURL?: GenerateFileURL\n }): CollectionAfterReadHook =>\n async ({ doc }) => {\n const upload = doc as { _objectKey?: string; prefix?: string } & FileData & TypeWithID\n const filename = upload.original?.filename\n\n if (!filename) {\n return doc\n }\n\n if (upload.original?.url && !upload.original.url.startsWith('/')) {\n return doc\n }\n\n const prefix = buildPrefixWithObjectKey({\n objectKey: upload.original?._objectKey,\n prefix: upload.original?.prefix,\n })\n const url = generateFileURL\n ? await generateFileURL({ collection, filename, prefix })\n : await adapter.generateURL?.({ collection, data: upload, filename, prefix })\n\n return url ? { ...doc, original: { ...upload.original, url } } : doc\n }\n"],"names":["buildPrefixWithObjectKey","getPublicOriginalURLHook","adapter","collection","generateFileURL","doc","upload","filename","original","url","startsWith","prefix","objectKey","_objectKey","generateURL","data"],"mappings":"AAIA,SAASA,wBAAwB,QAAQ,2CAA0C;AAEnF,OAAO,MAAMC,2BACX,CAAC,EACCC,OAAO,EACPC,UAAU,EACVC,eAAe,EAKhB,GACD,OAAO,EAAEC,GAAG,EAAE;QACZ,MAAMC,SAASD;QACf,MAAME,WAAWD,OAAOE,QAAQ,EAAED;QAElC,IAAI,CAACA,UAAU;YACb,OAAOF;QACT;QAEA,IAAIC,OAAOE,QAAQ,EAAEC,OAAO,CAACH,OAAOE,QAAQ,CAACC,GAAG,CAACC,UAAU,CAAC,MAAM;YAChE,OAAOL;QACT;QAEA,MAAMM,SAASX,yBAAyB;YACtCY,WAAWN,OAAOE,QAAQ,EAAEK;YAC5BF,QAAQL,OAAOE,QAAQ,EAAEG;QAC3B;QACA,MAAMF,MAAML,kBACR,MAAMA,gBAAgB;YAAED;YAAYI;YAAUI;QAAO,KACrD,MAAMT,QAAQY,WAAW,GAAG;YAAEX;YAAYY,MAAMT;YAAQC;YAAUI;QAAO;QAE7E,OAAOF,MAAM;YAAE,GAAGJ,GAAG;YAAEG,UAAU;gBAAE,GAAGF,OAAOE,QAAQ;gBAAEC;YAAI;QAAE,IAAIJ;IACnE,EAAC"}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAA;AAoBnE,eAAO,MAAM,kBAAkB,kBACb,aAAa,sBACZ,MAAM,KAAG,MA+PzB,CAAA"}
|