@payloadcms/plugin-cloud-storage 4.0.0-internal.e55ccef → 4.0.0-internal.ea6e8f8

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.
Files changed (98) hide show
  1. package/README.md +2 -0
  2. package/dist/client/createClientUploadHandler.d.ts +8 -7
  3. package/dist/client/createClientUploadHandler.d.ts.map +1 -1
  4. package/dist/client/createClientUploadHandler.js +26 -22
  5. package/dist/client/createClientUploadHandler.js.map +1 -1
  6. package/dist/exports/client.d.ts +1 -1
  7. package/dist/exports/client.d.ts.map +1 -1
  8. package/dist/exports/client.js +1 -1
  9. package/dist/exports/client.js.map +1 -1
  10. package/dist/exports/utilities.d.ts +1 -2
  11. package/dist/exports/utilities.d.ts.map +1 -1
  12. package/dist/exports/utilities.js +1 -2
  13. package/dist/exports/utilities.js.map +1 -1
  14. package/dist/fields/getFields.d.ts +1 -5
  15. package/dist/fields/getFields.d.ts.map +1 -1
  16. package/dist/fields/getFields.js +118 -24
  17. package/dist/fields/getFields.js.map +1 -1
  18. package/dist/hooks/afterChange.d.ts +5 -1
  19. package/dist/hooks/afterChange.d.ts.map +1 -1
  20. package/dist/hooks/afterChange.js +208 -32
  21. package/dist/hooks/afterChange.js.map +1 -1
  22. package/dist/hooks/afterDelete.d.ts +10 -2
  23. package/dist/hooks/afterDelete.d.ts.map +1 -1
  24. package/dist/hooks/afterDelete.js +110 -15
  25. package/dist/hooks/afterDelete.js.map +1 -1
  26. package/dist/hooks/afterRead.d.ts +6 -1
  27. package/dist/hooks/afterRead.d.ts.map +1 -1
  28. package/dist/hooks/afterRead.js +34 -7
  29. package/dist/hooks/afterRead.js.map +1 -1
  30. package/dist/hooks/beforeChange.d.ts +2 -1
  31. package/dist/hooks/beforeChange.d.ts.map +1 -1
  32. package/dist/hooks/beforeChange.js +18 -4
  33. package/dist/hooks/beforeChange.js.map +1 -1
  34. package/dist/hooks/normalizeUploadPrefix.d.ts +11 -0
  35. package/dist/hooks/normalizeUploadPrefix.d.ts.map +1 -0
  36. package/dist/hooks/normalizeUploadPrefix.js +42 -0
  37. package/dist/hooks/normalizeUploadPrefix.js.map +1 -0
  38. package/dist/hooks/publicOriginalURL.d.ts +8 -0
  39. package/dist/hooks/publicOriginalURL.d.ts.map +1 -0
  40. package/dist/hooks/publicOriginalURL.js +34 -0
  41. package/dist/hooks/publicOriginalURL.js.map +1 -0
  42. package/dist/plugin.d.ts.map +1 -1
  43. package/dist/plugin.js +210 -129
  44. package/dist/plugin.js.map +1 -1
  45. package/dist/types.d.ts +60 -21
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/types.js.map +1 -1
  48. package/dist/utilities/buildPrefixWithObjectKey.d.ts +8 -0
  49. package/dist/utilities/buildPrefixWithObjectKey.d.ts.map +1 -0
  50. package/dist/utilities/buildPrefixWithObjectKey.js +13 -0
  51. package/dist/utilities/buildPrefixWithObjectKey.js.map +1 -0
  52. package/dist/utilities/buildStoragePathData.d.ts +49 -0
  53. package/dist/utilities/buildStoragePathData.d.ts.map +1 -0
  54. package/dist/utilities/buildStoragePathData.js +67 -0
  55. package/dist/utilities/buildStoragePathData.js.map +1 -0
  56. package/dist/utilities/createFileOperations.d.ts +13 -0
  57. package/dist/utilities/createFileOperations.d.ts.map +1 -0
  58. package/dist/utilities/createFileOperations.js +258 -0
  59. package/dist/utilities/createFileOperations.js.map +1 -0
  60. package/dist/utilities/getFilePrefix.d.ts +16 -11
  61. package/dist/utilities/getFilePrefix.d.ts.map +1 -1
  62. package/dist/utilities/getFilePrefix.js +86 -31
  63. package/dist/utilities/getFilePrefix.js.map +1 -1
  64. package/dist/utilities/getIncomingFiles.js +4 -4
  65. package/dist/utilities/getIncomingFiles.js.map +1 -1
  66. package/dist/utilities/getStorageLocationSelect.d.ts +9 -0
  67. package/dist/utilities/getStorageLocationSelect.d.ts.map +1 -0
  68. package/dist/utilities/getStorageLocationSelect.js +54 -0
  69. package/dist/utilities/getStorageLocationSelect.js.map +1 -0
  70. package/dist/utilities/resolveSignedURLKey.d.ts +13 -2
  71. package/dist/utilities/resolveSignedURLKey.d.ts.map +1 -1
  72. package/dist/utilities/resolveSignedURLKey.js +53 -11
  73. package/dist/utilities/resolveSignedURLKey.js.map +1 -1
  74. package/dist/utilities/sanitizePrefix.d.ts +1 -9
  75. package/dist/utilities/sanitizePrefix.d.ts.map +1 -1
  76. package/dist/utilities/sanitizePrefix.js +1 -21
  77. package/dist/utilities/sanitizePrefix.js.map +1 -1
  78. package/package.json +6 -6
  79. package/dist/admin/fields/getFields.d.ts +0 -17
  80. package/dist/admin/fields/getFields.d.ts.map +0 -1
  81. package/dist/admin/fields/getFields.js +0 -98
  82. package/dist/admin/fields/getFields.js.map +0 -1
  83. package/dist/admin/index.d.ts +0 -4
  84. package/dist/admin/index.d.ts.map +0 -1
  85. package/dist/admin/index.js +0 -34
  86. package/dist/admin/index.js.map +0 -1
  87. package/dist/utilities/getFileKey.d.ts +0 -22
  88. package/dist/utilities/getFileKey.d.ts.map +0 -1
  89. package/dist/utilities/getFileKey.js +0 -23
  90. package/dist/utilities/getFileKey.js.map +0 -1
  91. package/dist/utilities/getFileKey.spec.js +0 -174
  92. package/dist/utilities/getFileKey.spec.js.map +0 -1
  93. package/dist/utilities/getFilePrefix.spec.js +0 -105
  94. package/dist/utilities/getFilePrefix.spec.js.map +0 -1
  95. package/dist/utilities/initClientUploads.d.ts +0 -13
  96. package/dist/utilities/initClientUploads.d.ts.map +0 -1
  97. package/dist/utilities/initClientUploads.js +0 -63
  98. package/dist/utilities/initClientUploads.js.map +0 -1
@@ -1,28 +1,112 @@
1
+ import { deepMergeWithSourceArrays, MAIN_BRANCH, scheduleAfterTransactionCommit } from 'payload';
2
+ import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
3
+ import { buildStoragePathData, buildUploadStoragePathData } from '../utilities/buildStoragePathData.js';
1
4
  import { getIncomingFiles } from '../utilities/getIncomingFiles.js';
2
- export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, operation, previousDoc, req })=>{
5
+ import { appendProxyPrefix } from './afterRead.js';
6
+ // The object's folder: semantic prefix + `_objectKey` segment.
7
+ const getObjectFolder = (data)=>{
8
+ const record = data ?? {};
9
+ return buildPrefixWithObjectKey({
10
+ objectKey: record._objectKey,
11
+ prefix: record.prefix
12
+ });
13
+ };
14
+ export const getAfterChangeHook = ({ adapter, collection, collectionPrefix, disablePayloadAccessControl, hasCustomFileURL, useCompositePrefixes })=>async ({ data, doc, operation, previousDoc, req, select })=>{
3
15
  // Skip if this is an internal update to prevent infinite loop
4
16
  if (req.context?.skipCloudStorage) {
5
17
  return doc;
6
18
  }
7
- const isDraftSave = doc._status === 'draft';
19
+ // Restore upload metadata removed by select, including partially selected image sizes.
20
+ const uploadData = select ? deepMergeWithSourceArrays(data, doc) : doc;
21
+ const withProxyPrefix = (upload)=>{
22
+ const { prefix } = upload;
23
+ if (disablePayloadAccessControl || hasCustomFileURL || !useCompositePrefixes || !prefix) {
24
+ return upload;
25
+ }
26
+ return {
27
+ ...upload,
28
+ ...upload.url && {
29
+ url: appendProxyPrefix({
30
+ prefix,
31
+ url: upload.url
32
+ })
33
+ },
34
+ ...upload.original?.url && {
35
+ original: {
36
+ ...upload.original,
37
+ url: appendProxyPrefix({
38
+ prefix,
39
+ url: upload.original.url
40
+ })
41
+ }
42
+ }
43
+ };
44
+ };
45
+ const isDraftSave = uploadData._status === 'draft';
8
46
  const isDraftOverPublished = isDraftSave && previousDoc?._status === 'published';
47
+ if (req.context?._payloadManagedCloudStorage) {
48
+ const metadata = req.context._payloadManagedCloudMetadata;
49
+ if (!metadata || Object.keys(metadata).length === 0) {
50
+ return withProxyPrefix(doc);
51
+ }
52
+ req.context.skipCloudStorage = true;
53
+ req.file = undefined;
54
+ req.payloadUploadSizes = undefined;
55
+ const originalQuery = req.query;
56
+ req.query = {
57
+ ...req.query
58
+ };
59
+ delete req.query.uploadEdits;
60
+ try {
61
+ const updatedDoc = await req.payload.update({
62
+ id: doc.id,
63
+ collection: collection.slug,
64
+ data: metadata,
65
+ depth: 0,
66
+ draft: isDraftSave,
67
+ overrideAccess: true,
68
+ req,
69
+ select
70
+ });
71
+ return withProxyPrefix({
72
+ ...doc,
73
+ ...updatedDoc
74
+ });
75
+ } finally{
76
+ req.query = originalQuery;
77
+ delete req.context.skipCloudStorage;
78
+ }
79
+ }
9
80
  try {
10
81
  const files = getIncomingFiles({
11
- data: doc,
82
+ data: uploadData,
12
83
  req
13
84
  });
14
85
  if (files.length > 0) {
15
- const uploadResults = await Promise.all(files.filter((file)=>!file.clientUploadContext).map((file)=>adapter.handleUpload({
16
- clientUploadContext: file.clientUploadContext,
86
+ // Fold `_objectKey` so generated sizes land in the same folder as the original.
87
+ const dataForUpload = {
88
+ ...uploadData,
89
+ prefix: getObjectFolder(uploadData)
90
+ };
91
+ const uploadResults = await Promise.all(files.filter((file)=>!file.uploadReference).map((file)=>adapter.handleUpload({
17
92
  collection,
18
- data: doc,
93
+ data: dataForUpload,
19
94
  file,
20
- req
95
+ req,
96
+ storageFilePath: buildUploadStoragePathData({
97
+ collectionPrefix,
98
+ docPrefix: dataForUpload.prefix,
99
+ filename: file.filename,
100
+ useCompositePrefixes
101
+ }).storageFilePath
21
102
  })));
22
103
  const uploadMetadata = uploadResults.filter((result)=>result != null && typeof result === 'object').reduce((acc, metadata)=>({
23
104
  ...acc,
24
105
  ...metadata
25
106
  }), {});
107
+ // Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.
108
+ delete uploadMetadata.prefix;
109
+ delete uploadMetadata._objectKey;
26
110
  let docWithMetadata = doc;
27
111
  if (Object.keys(uploadMetadata).length > 0) {
28
112
  if (!req.context) {
@@ -33,59 +117,126 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
33
117
  req.file = undefined;
34
118
  req.payloadUploadSizes = undefined;
35
119
  try {
36
- await req.payload.update({
120
+ const updatedDoc = await req.payload.update({
37
121
  id: doc.id,
38
122
  collection: collection.slug,
39
123
  data: uploadMetadata,
40
124
  depth: 0,
41
125
  draft: isDraftSave,
42
- req
126
+ overrideAccess: true,
127
+ req,
128
+ select
43
129
  });
130
+ // Persist all adapter metadata, but do not add unselected fields to the response.
131
+ docWithMetadata = select ? {
132
+ ...doc,
133
+ ...updatedDoc
134
+ } : {
135
+ ...doc,
136
+ ...uploadMetadata
137
+ };
44
138
  } finally{
45
139
  delete req.context.skipCloudStorage;
46
140
  }
47
- docWithMetadata = {
48
- ...doc,
49
- ...uploadMetadata
50
- };
51
141
  }
52
142
  // Delete previous files only after the new upload and metadata
53
143
  // persistence have succeeded. Deleting earlier would orphan the
54
144
  // record if a later step throws (e.g. a user-defined afterChange
55
145
  // hook on the same collection).
56
- if (previousDoc && operation === 'update' && !isDraftOverPublished) {
146
+ if (previousDoc && operation === 'update' && !isDraftOverPublished && !collection.versions && !previousDoc.original) {
57
147
  let filesToDelete = [];
58
148
  if (typeof previousDoc?.filename === 'string') {
59
149
  filesToDelete.push(previousDoc.filename);
60
150
  }
61
- if (typeof previousDoc.sizes === 'object') {
62
- filesToDelete = filesToDelete.concat(Object.values(previousDoc?.sizes || []).map((resizedFileData)=>resizedFileData?.filename));
151
+ if (typeof previousDoc.variants === 'object') {
152
+ filesToDelete = filesToDelete.concat(Object.values(previousDoc?.variants || []).map((resizedFileData)=>resizedFileData?.filename));
63
153
  }
64
- // Collect new filenames (main + sizes) so we don't delete a
65
- // file that the new upload reused (e.g. same filename on reupload
66
- // where Payload overwrites in place).
154
+ // Compare full locations: a replacement can reuse a filename while moving
155
+ // a legacy object beneath the collection prefix.
156
+ const newFileData = {
157
+ ...uploadData,
158
+ ...uploadMetadata
159
+ };
67
160
  const newFilenames = new Set();
68
- if (typeof docWithMetadata.filename === 'string') {
69
- newFilenames.add(docWithMetadata.filename);
161
+ if (typeof newFileData.filename === 'string') {
162
+ newFilenames.add(newFileData.filename);
70
163
  }
71
- if (typeof docWithMetadata.sizes === 'object') {
72
- for (const size of Object.values(docWithMetadata.sizes || {})){
164
+ if (typeof newFileData.variants === 'object') {
165
+ for (const size of Object.values(newFileData.variants || {})){
73
166
  if (size?.filename && typeof size.filename === 'string') {
74
167
  newFilenames.add(size.filename);
75
168
  }
76
169
  }
77
170
  }
78
- const deletionPromises = filesToDelete.map(async (filename)=>{
79
- if (filename && !newFilenames.has(filename)) {
80
- await adapter.handleDelete({
81
- collection,
82
- doc: previousDoc,
83
- filename,
84
- req
85
- });
171
+ const resolveKey = ({ data, filename })=>buildStoragePathData({
172
+ collectionPrefix,
173
+ docPrefix: getObjectFolder(data),
174
+ filename,
175
+ useCompositePrefixes
176
+ }).storageFilePath;
177
+ const newKeys = new Set([
178
+ ...newFilenames
179
+ ].map((filename)=>resolveKey({
180
+ data: newFileData,
181
+ filename
182
+ })));
183
+ const branchDocumentID = getBranchDocumentID(previousDoc);
184
+ if (branchDocumentID !== undefined) {
185
+ const retainedMainDocument = await req.payload.db.findOne({
186
+ branch: false,
187
+ collection: collection.slug,
188
+ req,
189
+ where: {
190
+ and: [
191
+ {
192
+ _branch: {
193
+ equals: MAIN_BRANCH
194
+ }
195
+ },
196
+ {
197
+ id: {
198
+ equals: branchDocumentID
199
+ }
200
+ }
201
+ ]
202
+ }
203
+ });
204
+ if (retainedMainDocument) {
205
+ for (const filename of getDocumentFilenames(retainedMainDocument)){
206
+ newKeys.add(resolveKey({
207
+ data: retainedMainDocument,
208
+ filename
209
+ }));
210
+ }
86
211
  }
212
+ }
213
+ const deletionTargets = filesToDelete.flatMap((filename)=>{
214
+ if (!filename) {
215
+ return [];
216
+ }
217
+ const storageFilePath = resolveKey({
218
+ data: previousDoc,
219
+ filename
220
+ });
221
+ return newKeys.has(storageFilePath) ? [] : [
222
+ {
223
+ filename,
224
+ storageFilePath
225
+ }
226
+ ];
227
+ });
228
+ await scheduleAfterTransactionCommit({
229
+ callback: async ()=>{
230
+ await Promise.all(deletionTargets.map(({ filename, storageFilePath })=>adapter.handleDelete({
231
+ collection,
232
+ doc: previousDoc,
233
+ filename,
234
+ req,
235
+ storageFilePath
236
+ })));
237
+ },
238
+ req
87
239
  });
88
- await Promise.all(deletionPromises);
89
240
  }
90
241
  if (docWithMetadata !== doc) {
91
242
  return docWithMetadata;
@@ -100,5 +251,30 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
100
251
  }
101
252
  return doc;
102
253
  };
254
+ const getBranchDocumentID = (doc)=>{
255
+ if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {
256
+ return undefined;
257
+ }
258
+ const branchDocument = doc;
259
+ if (branchDocument._branch === MAIN_BRANCH) {
260
+ return undefined;
261
+ }
262
+ const relation = branchDocument._branchDocID;
263
+ const value = relation && typeof relation === 'object' && !Array.isArray(relation) && 'value' in relation ? relation.value : relation;
264
+ return typeof value === 'number' || typeof value === 'string' ? value : undefined;
265
+ };
266
+ const getDocumentFilenames = (doc)=>{
267
+ const filenames = typeof doc.filename === 'string' ? [
268
+ doc.filename
269
+ ] : [];
270
+ if (doc.variants && typeof doc.variants === 'object' && !Array.isArray(doc.variants)) {
271
+ for (const variant of Object.values(doc.variants)){
272
+ if (variant && typeof variant === 'object' && !Array.isArray(variant) && 'filename' in variant && typeof variant.filename === 'string') {
273
+ filenames.push(variant.filename);
274
+ }
275
+ }
276
+ }
277
+ return filenames;
278
+ };
103
279
 
104
280
  //# sourceMappingURL=afterChange.js.map
@@ -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.clientUploadContext)\n .map((file) =>\n adapter.handleUpload({\n clientUploadContext: file.clientUploadContext,\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","clientUploadContext","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, MAIN_BRANCH, scheduleAfterTransactionCommit } 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 const branchDocumentID = getBranchDocumentID(previousDoc)\n\n if (branchDocumentID !== undefined) {\n const retainedMainDocument = (await req.payload.db.findOne({\n branch: false,\n collection: collection.slug,\n req,\n where: {\n and: [{ _branch: { equals: MAIN_BRANCH } }, { id: { equals: branchDocumentID } }],\n },\n })) as null | Record<string, unknown>\n\n if (retainedMainDocument) {\n for (const filename of getDocumentFilenames(retainedMainDocument)) {\n newKeys.add(\n resolveKey({\n data: retainedMainDocument as { _objectKey?: string; prefix?: string },\n filename,\n }),\n )\n }\n }\n }\n\n const deletionTargets = filesToDelete.flatMap((filename) => {\n if (!filename) {\n return []\n }\n const storageFilePath = resolveKey({\n data: previousDoc as { _objectKey?: string; prefix?: string },\n filename,\n })\n return newKeys.has(storageFilePath) ? [] : [{ filename, storageFilePath }]\n })\n\n await scheduleAfterTransactionCommit({\n callback: async () => {\n await Promise.all(\n deletionTargets.map(({ filename, storageFilePath }) =>\n adapter.handleDelete({\n collection,\n doc: previousDoc,\n filename,\n req,\n storageFilePath,\n }),\n ),\n )\n },\n req,\n })\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\nconst getBranchDocumentID = (doc: unknown): number | string | undefined => {\n if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {\n return undefined\n }\n\n const branchDocument = doc as Record<string, unknown>\n\n if (branchDocument._branch === MAIN_BRANCH) {\n return undefined\n }\n\n const relation = branchDocument._branchDocID\n const value =\n relation && typeof relation === 'object' && !Array.isArray(relation) && 'value' in relation\n ? relation.value\n : relation\n\n return typeof value === 'number' || typeof value === 'string' ? value : undefined\n}\n\nconst getDocumentFilenames = (doc: Record<string, unknown>): string[] => {\n const filenames = typeof doc.filename === 'string' ? [doc.filename] : []\n\n if (doc.variants && typeof doc.variants === 'object' && !Array.isArray(doc.variants)) {\n for (const variant of Object.values(doc.variants)) {\n if (\n variant &&\n typeof variant === 'object' &&\n !Array.isArray(variant) &&\n 'filename' in variant &&\n typeof variant.filename === 'string'\n ) {\n filenames.push(variant.filename)\n }\n }\n }\n\n return filenames\n}\n"],"names":["deepMergeWithSourceArrays","MAIN_BRANCH","scheduleAfterTransactionCommit","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","branchDocumentID","getBranchDocumentID","retainedMainDocument","db","findOne","branch","where","and","_branch","equals","getDocumentFilenames","deletionTargets","flatMap","has","callback","handleDelete","err","logger","error","Array","isArray","branchDocument","relation","_branchDocID","value","filenames","variant"],"mappings":"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"}
@@ -1,9 +1,17 @@
1
- import type { CollectionAfterDeleteHook, CollectionConfig, FileData, TypeWithID } from 'payload';
1
+ import type { CollectionAfterDeleteHook, CollectionConfig, FileData, PayloadRequest, TypeWithID } from 'payload';
2
2
  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>;
10
+ export declare const getDeleteFiles: ({ adapter, collection, collectionPrefix, useCompositePrefixes }: Args) => ({ onError, req, retainedDoc, sourceDoc, }: {
11
+ onError?: (error: unknown) => void;
12
+ req: PayloadRequest;
13
+ retainedDoc?: null | object;
14
+ sourceDoc: object;
15
+ }) => Promise<void>;
8
16
  export {};
9
17
  //# 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;AAEnE,UAAU,IAAI;IACZ,OAAO,EAAE,gBAAgB,CAAA;IACzB,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,6BAG5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CAyBzE,CAAA"}
1
+ {"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,UAAU,EACX,MAAM,SAAS,CAAA;AAShB,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;AAID,eAAO,MAAM,kBAAkB,qEAK5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CAiDzE,CAAA;AAED,eAAO,MAAM,cAAc,oEACyC,IAAI,iDAMnE;IACD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAClC,GAAG,EAAE,cAAc,CAAA;IACnB,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;IAC3B,SAAS,EAAE,MAAM,CAAA;CAClB,kBAoEA,CAAA"}
@@ -1,29 +1,124 @@
1
- export const getAfterDeleteHook = ({ adapter, collection })=>{
2
- return async ({ doc, req })=>{
1
+ import { beginDeferredCleanupScopeIfNeeded, clearDeferredCleanupScope, flushDeferredCleanupScope, scheduleAfterTransactionCommit } from 'payload';
2
+ import { buildPrefixWithObjectKey } from '../utilities/buildPrefixWithObjectKey.js';
3
+ import { buildStoragePathData } from '../utilities/buildStoragePathData.js';
4
+ export const getAfterDeleteHook = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>{
5
+ const logDeleteError = ({ doc, err, req })=>{
6
+ req.payload.logger.error({
7
+ err,
8
+ msg: `There was an error while deleting files for collection ${collection.slug} document ${doc.id}.`
9
+ });
10
+ };
11
+ const deleteFiles = getDeleteFiles({
12
+ adapter,
13
+ collection,
14
+ collectionPrefix,
15
+ useCompositePrefixes
16
+ });
17
+ return async ({ id, doc, req })=>{
18
+ // Managed objects are deleted after the operation commits and all references are checked.
19
+ const managedDeletedUploads = req.context?._payloadManagedDeletedUploads;
20
+ if (collection.versions || Boolean(doc.original) && typeof doc.original?.filename === 'string' || managedDeletedUploads?.has(JSON.stringify([
21
+ collection.slug,
22
+ String(id)
23
+ ]))) {
24
+ return doc;
25
+ }
3
26
  try {
4
- const filesToDelete = [
5
- doc.filename,
6
- ...Object.values(doc?.sizes || []).map((resizedFileData)=>resizedFileData?.filename)
7
- ];
8
- const promises = filesToDelete.map(async (filename)=>{
9
- if (filename) {
10
- await adapter.handleDelete({
11
- collection,
27
+ await deleteFiles({
28
+ onError: (err)=>{
29
+ logDeleteError({
12
30
  doc,
13
- filename,
31
+ err,
14
32
  req
15
33
  });
16
- }
34
+ },
35
+ req,
36
+ sourceDoc: doc
17
37
  });
18
- await Promise.all(promises);
19
38
  } catch (err) {
20
- req.payload.logger.error({
39
+ logDeleteError({
40
+ doc,
21
41
  err,
22
- msg: `There was an error while deleting files corresponding to the ${collection.labels?.singular} with ID ${doc.id}.`
42
+ req
23
43
  });
24
44
  }
25
45
  return doc;
26
46
  };
27
47
  };
48
+ export const getDeleteFiles = ({ adapter, collection, collectionPrefix, useCompositePrefixes })=>async ({ onError, req, retainedDoc, sourceDoc })=>{
49
+ const cleanupScope = await beginDeferredCleanupScopeIfNeeded({
50
+ req
51
+ });
52
+ const sourceUploadDocument = sourceDoc;
53
+ const retainedUploadDocument = retainedDoc;
54
+ const resolveKey = ({ doc, filename })=>{
55
+ const docPrefix = buildPrefixWithObjectKey({
56
+ objectKey: doc._objectKey,
57
+ prefix: doc.prefix
58
+ });
59
+ return buildStoragePathData({
60
+ collectionPrefix,
61
+ docPrefix,
62
+ filename,
63
+ useCompositePrefixes
64
+ }).storageFilePath;
65
+ };
66
+ const retainedStoragePaths = new Set(retainedUploadDocument ? getFilenames(retainedUploadDocument).map((filename)=>resolveKey({
67
+ doc: retainedUploadDocument,
68
+ filename
69
+ })) : []);
70
+ const filesToDelete = getFilenames(sourceUploadDocument).flatMap((filename)=>{
71
+ const storageFilePath = resolveKey({
72
+ doc: sourceUploadDocument,
73
+ filename
74
+ });
75
+ return retainedStoragePaths.has(storageFilePath) ? [] : [
76
+ {
77
+ filename,
78
+ storageFilePath
79
+ }
80
+ ];
81
+ });
82
+ try {
83
+ await scheduleAfterTransactionCommit({
84
+ callback: async ()=>{
85
+ try {
86
+ await Promise.all(filesToDelete.map(({ filename, storageFilePath })=>adapter.handleDelete({
87
+ collection,
88
+ doc: sourceUploadDocument,
89
+ filename,
90
+ req,
91
+ storageFilePath
92
+ })));
93
+ } catch (error) {
94
+ if (onError) {
95
+ onError(error);
96
+ return;
97
+ }
98
+ throw error;
99
+ }
100
+ },
101
+ req
102
+ });
103
+ if (cleanupScope) {
104
+ await flushDeferredCleanupScope({
105
+ req,
106
+ scope: cleanupScope
107
+ });
108
+ }
109
+ } catch (error) {
110
+ if (cleanupScope) {
111
+ clearDeferredCleanupScope({
112
+ req,
113
+ scope: cleanupScope
114
+ });
115
+ }
116
+ throw error;
117
+ }
118
+ };
119
+ const getFilenames = (doc)=>[
120
+ doc.filename,
121
+ ...Object.values(doc.variants || {}).map((variantFileData)=>variantFileData?.filename)
122
+ ].filter((filename)=>typeof filename === 'string' && filename.length > 0);
28
123
 
29
124
  //# sourceMappingURL=afterDelete.js.map
@@ -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?.sizes || []).map(\n (resizedFileData) => resizedFileData?.filename as string,\n ),\n ]\n\n const promises = filesToDelete.map(async (filename) => {\n if (filename) {\n await adapter.handleDelete({ collection, doc, filename, req })\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":["getAfterDeleteHook","adapter","collection","doc","req","filesToDelete","filename","Object","values","sizes","map","resizedFileData","promises","handleDelete","Promise","all","err","payload","logger","error","msg","labels","singular","id"],"mappings":"AASA,OAAO,MAAMA,qBAAqB,CAAC,EACjCC,OAAO,EACPC,UAAU,EACL;IACL,OAAO,OAAO,EAAEC,GAAG,EAAEC,GAAG,EAAE;QACxB,IAAI;YACF,MAAMC,gBAA0B;gBAC9BF,IAAIG,QAAQ;mBACTC,OAAOC,MAAM,CAACL,KAAKM,SAAS,EAAE,EAAEC,GAAG,CACpC,CAACC,kBAAoBA,iBAAiBL;aAEzC;YAED,MAAMM,WAAWP,cAAcK,GAAG,CAAC,OAAOJ;gBACxC,IAAIA,UAAU;oBACZ,MAAML,QAAQY,YAAY,CAAC;wBAAEX;wBAAYC;wBAAKG;wBAAUF;oBAAI;gBAC9D;YACF;YAEA,MAAMU,QAAQC,GAAG,CAACH;QACpB,EAAE,OAAOI,KAAc;YACrBZ,IAAIa,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC;gBACvBH;gBACAI,KAAK,CAAC,6DAA6D,EAAElB,WAAWmB,MAAM,EAAEC,SAAS,SAAS,EAAEnB,IAAIoB,EAAE,CAAC,CAAC,CAAC;YACvH;QACF;QACA,OAAOpB;IACT;AACF,EAAC"}
1
+ {"version":3,"sources":["../../src/hooks/afterDelete.ts"],"sourcesContent":["import type {\n CollectionAfterDeleteHook,\n CollectionConfig,\n FileData,\n PayloadRequest,\n TypeWithID,\n} from 'payload'\n\nimport {\n beginDeferredCleanupScopeIfNeeded,\n clearDeferredCleanupScope,\n flushDeferredCleanupScope,\n scheduleAfterTransactionCommit,\n} 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\ntype UploadDocument = { _objectKey?: string } & FileData & TypeWithID & TypeWithPrefix\n\nexport const getAfterDeleteHook = ({\n adapter,\n collection,\n collectionPrefix,\n useCompositePrefixes,\n}: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {\n const logDeleteError = ({\n doc,\n err,\n req,\n }: {\n doc: TypeWithID\n err: unknown\n req: PayloadRequest\n }) => {\n req.payload.logger.error({\n err,\n msg: `There was an error while deleting files for collection ${collection.slug} document ${doc.id}.`,\n })\n }\n const deleteFiles = getDeleteFiles({\n adapter,\n collection,\n collectionPrefix,\n useCompositePrefixes,\n })\n\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 await deleteFiles({\n onError: (err) => {\n logDeleteError({ doc, err, req })\n },\n req,\n sourceDoc: doc,\n })\n } catch (err: unknown) {\n logDeleteError({ doc, err, req })\n }\n\n return doc\n }\n}\n\nexport const getDeleteFiles =\n ({ adapter, collection, collectionPrefix, useCompositePrefixes }: Args) =>\n async ({\n onError,\n req,\n retainedDoc,\n sourceDoc,\n }: {\n onError?: (error: unknown) => void\n req: PayloadRequest\n retainedDoc?: null | object\n sourceDoc: object\n }) => {\n const cleanupScope = await beginDeferredCleanupScopeIfNeeded({ req })\n const sourceUploadDocument = sourceDoc as UploadDocument\n const retainedUploadDocument = retainedDoc as null | undefined | UploadDocument\n const resolveKey = ({ doc, filename }: { doc: UploadDocument; filename: string }) => {\n const docPrefix = buildPrefixWithObjectKey({\n objectKey: doc._objectKey,\n prefix: doc.prefix,\n })\n\n return buildStoragePathData({\n collectionPrefix,\n docPrefix,\n filename,\n useCompositePrefixes,\n }).storageFilePath\n }\n const retainedStoragePaths = new Set(\n retainedUploadDocument\n ? getFilenames(retainedUploadDocument).map((filename) =>\n resolveKey({ doc: retainedUploadDocument, filename }),\n )\n : [],\n )\n\n const filesToDelete = getFilenames(sourceUploadDocument).flatMap((filename) => {\n const storageFilePath = resolveKey({ doc: sourceUploadDocument, filename })\n\n return retainedStoragePaths.has(storageFilePath) ? [] : [{ filename, storageFilePath }]\n })\n\n try {\n await scheduleAfterTransactionCommit({\n callback: async () => {\n try {\n await Promise.all(\n filesToDelete.map(({ filename, storageFilePath }) =>\n adapter.handleDelete({\n collection,\n doc: sourceUploadDocument,\n filename,\n req,\n storageFilePath,\n }),\n ),\n )\n } catch (error) {\n if (onError) {\n onError(error)\n return\n }\n\n throw error\n }\n },\n req,\n })\n\n if (cleanupScope) {\n await flushDeferredCleanupScope({ req, scope: cleanupScope })\n }\n } catch (error) {\n if (cleanupScope) {\n clearDeferredCleanupScope({ req, scope: cleanupScope })\n }\n\n throw error\n }\n }\n\nconst getFilenames = (doc: FileData): string[] =>\n [\n doc.filename,\n ...Object.values(doc.variants || {}).map((variantFileData) => variantFileData?.filename),\n ].filter((filename): filename is string => typeof filename === 'string' && filename.length > 0)\n"],"names":["beginDeferredCleanupScopeIfNeeded","clearDeferredCleanupScope","flushDeferredCleanupScope","scheduleAfterTransactionCommit","buildPrefixWithObjectKey","buildStoragePathData","getAfterDeleteHook","adapter","collection","collectionPrefix","useCompositePrefixes","logDeleteError","doc","err","req","payload","logger","error","msg","slug","id","deleteFiles","getDeleteFiles","managedDeletedUploads","context","_payloadManagedDeletedUploads","versions","Boolean","original","filename","has","JSON","stringify","String","onError","sourceDoc","retainedDoc","cleanupScope","sourceUploadDocument","retainedUploadDocument","resolveKey","docPrefix","objectKey","_objectKey","prefix","storageFilePath","retainedStoragePaths","Set","getFilenames","map","filesToDelete","flatMap","callback","Promise","all","handleDelete","scope","Object","values","variants","variantFileData","filter","length"],"mappings":"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"}
@@ -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;AAEpE,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,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB;AAED,eAAO,MAAM,gBAAgB,gFACmD,IAAI,KAAG,SA4BpF,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"}