@payloadcms/plugin-cloud-storage 4.0.0-internal.e7d4ebc → 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.
- 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 +207 -30
- package/dist/hooks/afterChange.js.map +1 -1
- package/dist/hooks/afterDelete.d.ts +10 -2
- package/dist/hooks/afterDelete.d.ts.map +1 -1
- package/dist/hooks/afterDelete.js +110 -15
- 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 +79 -43
- 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,27 +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
|
-
|
|
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
|
-
|
|
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:
|
|
82
|
+
data: uploadData,
|
|
12
83
|
req
|
|
13
84
|
});
|
|
14
85
|
if (files.length > 0) {
|
|
86
|
+
// Fold `_objectKey` so generated sizes land in the same folder as the original.
|
|
87
|
+
const dataForUpload = {
|
|
88
|
+
...uploadData,
|
|
89
|
+
prefix: getObjectFolder(uploadData)
|
|
90
|
+
};
|
|
15
91
|
const uploadResults = await Promise.all(files.filter((file)=>!file.uploadReference).map((file)=>adapter.handleUpload({
|
|
16
92
|
collection,
|
|
17
|
-
data:
|
|
93
|
+
data: dataForUpload,
|
|
18
94
|
file,
|
|
19
|
-
req
|
|
95
|
+
req,
|
|
96
|
+
storageFilePath: buildUploadStoragePathData({
|
|
97
|
+
collectionPrefix,
|
|
98
|
+
docPrefix: dataForUpload.prefix,
|
|
99
|
+
filename: file.filename,
|
|
100
|
+
useCompositePrefixes
|
|
101
|
+
}).storageFilePath
|
|
20
102
|
})));
|
|
21
103
|
const uploadMetadata = uploadResults.filter((result)=>result != null && typeof result === 'object').reduce((acc, metadata)=>({
|
|
22
104
|
...acc,
|
|
23
105
|
...metadata
|
|
24
106
|
}), {});
|
|
107
|
+
// Adapters may echo `data` back as metadata; keep the document's own `prefix`/`_objectKey`.
|
|
108
|
+
delete uploadMetadata.prefix;
|
|
109
|
+
delete uploadMetadata._objectKey;
|
|
25
110
|
let docWithMetadata = doc;
|
|
26
111
|
if (Object.keys(uploadMetadata).length > 0) {
|
|
27
112
|
if (!req.context) {
|
|
@@ -32,59 +117,126 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
|
|
|
32
117
|
req.file = undefined;
|
|
33
118
|
req.payloadUploadSizes = undefined;
|
|
34
119
|
try {
|
|
35
|
-
await req.payload.update({
|
|
120
|
+
const updatedDoc = await req.payload.update({
|
|
36
121
|
id: doc.id,
|
|
37
122
|
collection: collection.slug,
|
|
38
123
|
data: uploadMetadata,
|
|
39
124
|
depth: 0,
|
|
40
125
|
draft: isDraftSave,
|
|
41
|
-
|
|
126
|
+
overrideAccess: true,
|
|
127
|
+
req,
|
|
128
|
+
select
|
|
42
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
|
+
};
|
|
43
138
|
} finally{
|
|
44
139
|
delete req.context.skipCloudStorage;
|
|
45
140
|
}
|
|
46
|
-
docWithMetadata = {
|
|
47
|
-
...doc,
|
|
48
|
-
...uploadMetadata
|
|
49
|
-
};
|
|
50
141
|
}
|
|
51
142
|
// Delete previous files only after the new upload and metadata
|
|
52
143
|
// persistence have succeeded. Deleting earlier would orphan the
|
|
53
144
|
// record if a later step throws (e.g. a user-defined afterChange
|
|
54
145
|
// hook on the same collection).
|
|
55
|
-
if (previousDoc && operation === 'update' && !isDraftOverPublished) {
|
|
146
|
+
if (previousDoc && operation === 'update' && !isDraftOverPublished && !collection.versions && !previousDoc.original) {
|
|
56
147
|
let filesToDelete = [];
|
|
57
148
|
if (typeof previousDoc?.filename === 'string') {
|
|
58
149
|
filesToDelete.push(previousDoc.filename);
|
|
59
150
|
}
|
|
60
|
-
if (typeof previousDoc.
|
|
61
|
-
filesToDelete = filesToDelete.concat(Object.values(previousDoc?.
|
|
151
|
+
if (typeof previousDoc.variants === 'object') {
|
|
152
|
+
filesToDelete = filesToDelete.concat(Object.values(previousDoc?.variants || []).map((resizedFileData)=>resizedFileData?.filename));
|
|
62
153
|
}
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
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
|
+
};
|
|
66
160
|
const newFilenames = new Set();
|
|
67
|
-
if (typeof
|
|
68
|
-
newFilenames.add(
|
|
161
|
+
if (typeof newFileData.filename === 'string') {
|
|
162
|
+
newFilenames.add(newFileData.filename);
|
|
69
163
|
}
|
|
70
|
-
if (typeof
|
|
71
|
-
for (const size of Object.values(
|
|
164
|
+
if (typeof newFileData.variants === 'object') {
|
|
165
|
+
for (const size of Object.values(newFileData.variants || {})){
|
|
72
166
|
if (size?.filename && typeof size.filename === 'string') {
|
|
73
167
|
newFilenames.add(size.filename);
|
|
74
168
|
}
|
|
75
169
|
}
|
|
76
170
|
}
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
+
}
|
|
85
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
|
|
86
239
|
});
|
|
87
|
-
await Promise.all(deletionPromises);
|
|
88
240
|
}
|
|
89
241
|
if (docWithMetadata !== doc) {
|
|
90
242
|
return docWithMetadata;
|
|
@@ -99,5 +251,30 @@ export const getAfterChangeHook = ({ adapter, collection })=>async ({ doc, opera
|
|
|
99
251
|
}
|
|
100
252
|
return doc;
|
|
101
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
|
+
};
|
|
102
279
|
|
|
103
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.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":"AAIA,SAASA,gBAAgB,QAAQ,mCAAkC;AAOnE,OAAO,MAAMC,qBACX,CAAC,EAAEC,OAAO,EAAEC,UAAU,EAAQ,GAC9B,OAAO,EAAEC,GAAG,EAAEC,SAAS,EAAEC,WAAW,EAAEC,GAAG,EAAE;QACzC,8DAA8D;QAC9D,IAAIA,IAAIC,OAAO,EAAEC,kBAAkB;YACjC,OAAOL;QACT;QAEA,MAAMM,cAAc,AAACN,IAA6BO,OAAO,KAAK;QAC9D,MAAMC,uBACJF,eAAe,AAACJ,aAAkDK,YAAY;QAEhF,IAAI;YACF,MAAME,QAAQb,iBAAiB;gBAAEc,MAAMV;gBAAKG;YAAI;YAEhD,IAAIM,MAAME,MAAM,GAAG,GAAG;gBACpB,MAAMC,gBAAgB,MAAMC,QAAQC,GAAG,CACrCL,MACGM,MAAM,CAAC,CAACC,OAAS,CAACA,KAAKC,eAAe,EACtCC,GAAG,CAAC,CAACF,OACJlB,QAAQqB,YAAY,CAAC;wBACnBpB;wBACAW,MAAMV;wBACNgB;wBACAb;oBACF;gBAIN,MAAMiB,iBAAiBR,cACpBG,MAAM,CACL,CAACM,SACCA,UAAU,QAAQ,OAAOA,WAAW,UAEvCC,MAAM,CACL,CAACC,KAAKC,WAAc,CAAA;wBAAE,GAAGD,GAAG;wBAAE,GAAGC,QAAQ;oBAAC,CAAA,GAC1C,CAAC;gBAGL,IAAIC,kBAAkBzB;gBAEtB,IAAI0B,OAAOC,IAAI,CAACP,gBAAgBT,MAAM,GAAG,GAAG;oBAC1C,IAAI,CAACR,IAAIC,OAAO,EAAE;wBAChBD,IAAIC,OAAO,GAAG,CAAC;oBACjB;oBACAD,IAAIC,OAAO,CAACC,gBAAgB,GAAG;oBAE/B,iCAAiC;oBACjCF,IAAIa,IAAI,GAAGY;oBACXzB,IAAI0B,kBAAkB,GAAGD;oBAEzB,IAAI;wBACF,MAAMzB,IAAI2B,OAAO,CAACC,MAAM,CAAC;4BACvBC,IAAIhC,IAAIgC,EAAE;4BACVjC,YAAYA,WAAWkC,IAAI;4BAC3BvB,MAAMU;4BACNc,OAAO;4BACPC,OAAO7B;4BACPH;wBACF;oBACF,SAAU;wBACR,OAAOA,IAAIC,OAAO,CAACC,gBAAgB;oBACrC;oBAEAoB,kBAAkB;wBAAE,GAAGzB,GAAG;wBAAE,GAAGoB,cAAc;oBAAC;gBAChD;gBAEA,+DAA+D;gBAC/D,gEAAgE;gBAChE,iEAAiE;gBACjE,gCAAgC;gBAChC,IAAIlB,eAAeD,cAAc,YAAY,CAACO,sBAAsB;oBAClE,IAAI4B,gBAA0B,EAAE;oBAEhC,IAAI,OAAOlC,aAAamC,aAAa,UAAU;wBAC7CD,cAAcE,IAAI,CAACpC,YAAYmC,QAAQ;oBACzC;oBAEA,IAAI,OAAOnC,YAAYqC,KAAK,KAAK,UAAU;wBACzCH,gBAAgBA,cAAcI,MAAM,CAClCd,OAAOe,MAAM,CAACvC,aAAaqC,SAAS,EAAE,EAAErB,GAAG,CACzC,CAACwB,kBAAoBA,iBAAiBL;oBAG5C;oBAEA,4DAA4D;oBAC5D,kEAAkE;oBAClE,sCAAsC;oBACtC,MAAMM,eAAe,IAAIC;oBACzB,IAAI,OAAOnB,gBAAgBY,QAAQ,KAAK,UAAU;wBAChDM,aAAaE,GAAG,CAACpB,gBAAgBY,QAAQ;oBAC3C;oBACA,IAAI,OAAOZ,gBAAgBc,KAAK,KAAK,UAAU;wBAC7C,KAAK,MAAMO,QAAQpB,OAAOe,MAAM,CAAChB,gBAAgBc,KAAK,IAAI,CAAC,GAAI;4BAC7D,IAAIO,MAAMT,YAAY,OAAOS,KAAKT,QAAQ,KAAK,UAAU;gCACvDM,aAAaE,GAAG,CAACC,KAAKT,QAAQ;4BAChC;wBACF;oBACF;oBAEA,MAAMU,mBAAmBX,cAAclB,GAAG,CAAC,OAAOmB;wBAChD,IAAIA,YAAY,CAACM,aAAaK,GAAG,CAACX,WAAW;4BAC3C,MAAMvC,QAAQmD,YAAY,CAAC;gCAAElD;gCAAYC,KAAKE;gCAAamC;gCAAUlC;4BAAI;wBAC3E;oBACF;oBAEA,MAAMU,QAAQC,GAAG,CAACiC;gBACpB;gBAEA,IAAItB,oBAAoBzB,KAAK;oBAC3B,OAAOyB;gBACT;YACF;QACF,EAAE,OAAOyB,KAAc;YACrB/C,IAAI2B,OAAO,CAACqB,MAAM,CAACC,KAAK,CACtB,CAAC,yEAAyE,EAAErD,WAAWkC,IAAI,CAAC,eAAe,EAAEjC,IAAIqC,QAAQ,CAAC,CAAC,CAAC;YAE9HlC,IAAI2B,OAAO,CAACqB,MAAM,CAACC,KAAK,CAAC;gBAAEF;YAAI;YAC/B,MAAMA;QACR;QACA,OAAOlD;IACT,EAAC"}
|
|
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,
|
|
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
39
|
+
logDeleteError({
|
|
40
|
+
doc,
|
|
21
41
|
err,
|
|
22
|
-
|
|
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 {
|
|
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;
|
|
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"}
|