@payloadcms/plugin-cloud-storage 3.91.0-internal.c1569dc → 4.0.0-beta.0

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 (106) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +4 -4
  3. package/dist/client/createClientUploadHandler.d.ts +8 -7
  4. package/dist/client/createClientUploadHandler.d.ts.map +1 -1
  5. package/dist/client/createClientUploadHandler.js +26 -22
  6. package/dist/client/createClientUploadHandler.js.map +1 -1
  7. package/dist/exports/client.d.ts +1 -1
  8. package/dist/exports/client.d.ts.map +1 -1
  9. package/dist/exports/client.js +1 -1
  10. package/dist/exports/client.js.map +1 -1
  11. package/dist/exports/utilities.d.ts +2 -4
  12. package/dist/exports/utilities.d.ts.map +1 -1
  13. package/dist/exports/utilities.js +2 -4
  14. package/dist/exports/utilities.js.map +1 -1
  15. package/dist/fields/getFields.d.ts +1 -5
  16. package/dist/fields/getFields.d.ts.map +1 -1
  17. package/dist/fields/getFields.js +102 -35
  18. package/dist/fields/getFields.js.map +1 -1
  19. package/dist/hooks/afterChange.d.ts +3 -1
  20. package/dist/hooks/afterChange.d.ts.map +1 -1
  21. package/dist/hooks/afterChange.js +93 -27
  22. package/dist/hooks/afterChange.js.map +1 -1
  23. package/dist/hooks/afterDelete.d.ts.map +1 -1
  24. package/dist/hooks/afterDelete.js +10 -2
  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 +27 -11
  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 +14 -9
  33. package/dist/hooks/beforeChange.js.map +1 -1
  34. package/dist/hooks/publicOriginalURL.d.ts +8 -0
  35. package/dist/hooks/publicOriginalURL.d.ts.map +1 -0
  36. package/dist/hooks/publicOriginalURL.js +34 -0
  37. package/dist/hooks/publicOriginalURL.js.map +1 -0
  38. package/dist/plugin.d.ts.map +1 -1
  39. package/dist/plugin.js +198 -133
  40. package/dist/plugin.js.map +1 -1
  41. package/dist/types.d.ts +48 -31
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/types.js.map +1 -1
  44. package/dist/utilities/buildStoragePathData.d.ts +0 -6
  45. package/dist/utilities/buildStoragePathData.d.ts.map +1 -1
  46. package/dist/utilities/buildStoragePathData.js +0 -2
  47. package/dist/utilities/buildStoragePathData.js.map +1 -1
  48. package/dist/utilities/createFileOperations.d.ts +13 -0
  49. package/dist/utilities/createFileOperations.d.ts.map +1 -0
  50. package/dist/utilities/createFileOperations.js +258 -0
  51. package/dist/utilities/createFileOperations.js.map +1 -0
  52. package/dist/utilities/getFilePrefix.d.ts +9 -20
  53. package/dist/utilities/getFilePrefix.d.ts.map +1 -1
  54. package/dist/utilities/getFilePrefix.js +42 -31
  55. package/dist/utilities/getFilePrefix.js.map +1 -1
  56. package/dist/utilities/getIncomingFiles.js +4 -4
  57. package/dist/utilities/getIncomingFiles.js.map +1 -1
  58. package/dist/utilities/getStorageLocationSelect.d.ts +9 -0
  59. package/dist/utilities/getStorageLocationSelect.d.ts.map +1 -0
  60. package/dist/utilities/getStorageLocationSelect.js +54 -0
  61. package/dist/utilities/getStorageLocationSelect.js.map +1 -0
  62. package/dist/utilities/resolveSignedURLKey.d.ts +10 -10
  63. package/dist/utilities/resolveSignedURLKey.d.ts.map +1 -1
  64. package/dist/utilities/resolveSignedURLKey.js +33 -26
  65. package/dist/utilities/resolveSignedURLKey.js.map +1 -1
  66. package/dist/utilities/sanitizePrefix.d.ts +1 -9
  67. package/dist/utilities/sanitizePrefix.d.ts.map +1 -1
  68. package/dist/utilities/sanitizePrefix.js +1 -21
  69. package/dist/utilities/sanitizePrefix.js.map +1 -1
  70. package/package.json +6 -6
  71. package/dist/admin/fields/getFields.d.ts +0 -17
  72. package/dist/admin/fields/getFields.d.ts.map +0 -1
  73. package/dist/admin/fields/getFields.js +0 -98
  74. package/dist/admin/fields/getFields.js.map +0 -1
  75. package/dist/admin/index.d.ts +0 -4
  76. package/dist/admin/index.d.ts.map +0 -1
  77. package/dist/admin/index.js +0 -34
  78. package/dist/admin/index.js.map +0 -1
  79. package/dist/hooks/afterChange.spec.js +0 -150
  80. package/dist/hooks/afterChange.spec.js.map +0 -1
  81. package/dist/hooks/normalizeUploadPrefix.spec.js +0 -154
  82. package/dist/hooks/normalizeUploadPrefix.spec.js.map +0 -1
  83. package/dist/plugin.spec.js +0 -186
  84. package/dist/plugin.spec.js.map +0 -1
  85. package/dist/utilities/assertReceiptMatchesFileKey.d.ts +0 -15
  86. package/dist/utilities/assertReceiptMatchesFileKey.d.ts.map +0 -1
  87. package/dist/utilities/assertReceiptMatchesFileKey.js +0 -31
  88. package/dist/utilities/assertReceiptMatchesFileKey.js.map +0 -1
  89. package/dist/utilities/buildStoragePathData.spec.js +0 -254
  90. package/dist/utilities/buildStoragePathData.spec.js.map +0 -1
  91. package/dist/utilities/getFilePrefix.spec.js +0 -291
  92. package/dist/utilities/getFilePrefix.spec.js.map +0 -1
  93. package/dist/utilities/initClientUploads.d.ts +0 -13
  94. package/dist/utilities/initClientUploads.d.ts.map +0 -1
  95. package/dist/utilities/initClientUploads.js +0 -66
  96. package/dist/utilities/initClientUploads.js.map +0 -1
  97. package/dist/utilities/initClientUploads.spec.js +0 -31
  98. package/dist/utilities/initClientUploads.spec.js.map +0 -1
  99. package/dist/utilities/resolveSignedURLKey.spec.js +0 -56
  100. package/dist/utilities/resolveSignedURLKey.spec.js.map +0 -1
  101. package/dist/utilities/verifyClientUploadReceiptForFileKey.d.ts +0 -20
  102. package/dist/utilities/verifyClientUploadReceiptForFileKey.d.ts.map +0 -1
  103. package/dist/utilities/verifyClientUploadReceiptForFileKey.js +0 -24
  104. package/dist/utilities/verifyClientUploadReceiptForFileKey.js.map +0 -1
  105. package/dist/utilities/verifyClientUploadReceiptForFileKey.spec.js +0 -108
  106. package/dist/utilities/verifyClientUploadReceiptForFileKey.spec.js.map +0 -1
@@ -1,254 +0,0 @@
1
- import { buildStoragePathData, buildUploadStoragePathData, isStoragePathWithinCollectionPrefix } from './buildStoragePathData.js';
2
- import { describe, expect, it } from 'vitest';
3
- describe('buildStoragePathData', ()=>{
4
- describe('non-composite mode (useCompositePrefixes: false)', ()=>{
5
- it('should preserve the key of a legacy document outside the collection prefix', ()=>{
6
- const result = buildStoragePathData({
7
- collectionPrefix: 'media/',
8
- docPrefix: 'media-archive',
9
- filename: 'test.png',
10
- useCompositePrefixes: false
11
- });
12
- expect(result).toEqual({
13
- fileKey: 'media-archive/test.png',
14
- sanitizedCollectionPrefix: 'media',
15
- sanitizedDocPrefix: 'media-archive',
16
- sanitizedFilename: 'test.png',
17
- storageFilePath: 'media-archive/test.png'
18
- });
19
- });
20
- it('should fallback to collectionPrefix when docPrefix is empty', ()=>{
21
- const result = buildStoragePathData({
22
- collectionPrefix: 'collection',
23
- docPrefix: '',
24
- filename: 'test.png',
25
- useCompositePrefixes: false
26
- });
27
- expect(result).toEqual({
28
- fileKey: 'collection/test.png',
29
- sanitizedCollectionPrefix: 'collection',
30
- sanitizedDocPrefix: '',
31
- sanitizedFilename: 'test.png',
32
- storageFilePath: 'collection/test.png'
33
- });
34
- });
35
- it('should fallback to collectionPrefix when docPrefix is undefined', ()=>{
36
- const result = buildStoragePathData({
37
- collectionPrefix: 'collection',
38
- filename: 'test.png',
39
- useCompositePrefixes: false
40
- });
41
- expect(result).toEqual({
42
- fileKey: 'collection/test.png',
43
- sanitizedCollectionPrefix: 'collection',
44
- sanitizedDocPrefix: '',
45
- sanitizedFilename: 'test.png',
46
- storageFilePath: 'collection/test.png'
47
- });
48
- });
49
- it('should return only filename when both prefixes are empty', ()=>{
50
- const result = buildStoragePathData({
51
- filename: 'test.png',
52
- useCompositePrefixes: false
53
- });
54
- expect(result).toEqual({
55
- fileKey: 'test.png',
56
- sanitizedCollectionPrefix: '',
57
- sanitizedDocPrefix: '',
58
- sanitizedFilename: 'test.png',
59
- storageFilePath: 'test.png'
60
- });
61
- });
62
- });
63
- describe('composite mode (useCompositePrefixes: true)', ()=>{
64
- it('should combine collectionPrefix and docPrefix', ()=>{
65
- const result = buildStoragePathData({
66
- collectionPrefix: 'collection',
67
- docPrefix: 'document',
68
- filename: 'test.png',
69
- useCompositePrefixes: true
70
- });
71
- expect(result).toEqual({
72
- fileKey: 'collection/document/test.png',
73
- sanitizedCollectionPrefix: 'collection',
74
- sanitizedDocPrefix: 'document',
75
- sanitizedFilename: 'test.png',
76
- storageFilePath: 'collection/document/test.png'
77
- });
78
- });
79
- it('should work with only collectionPrefix', ()=>{
80
- const result = buildStoragePathData({
81
- collectionPrefix: 'collection',
82
- filename: 'test.png',
83
- useCompositePrefixes: true
84
- });
85
- expect(result).toEqual({
86
- fileKey: 'collection/test.png',
87
- sanitizedCollectionPrefix: 'collection',
88
- sanitizedDocPrefix: '',
89
- sanitizedFilename: 'test.png',
90
- storageFilePath: 'collection/test.png'
91
- });
92
- });
93
- it('should work with only docPrefix', ()=>{
94
- const result = buildStoragePathData({
95
- docPrefix: 'document',
96
- filename: 'test.png',
97
- useCompositePrefixes: true
98
- });
99
- expect(result).toEqual({
100
- fileKey: 'document/test.png',
101
- sanitizedCollectionPrefix: '',
102
- sanitizedDocPrefix: 'document',
103
- sanitizedFilename: 'test.png',
104
- storageFilePath: 'document/test.png'
105
- });
106
- });
107
- it('should return only filename when both prefixes are empty', ()=>{
108
- const result = buildStoragePathData({
109
- filename: 'test.png',
110
- useCompositePrefixes: true
111
- });
112
- expect(result).toEqual({
113
- fileKey: 'test.png',
114
- sanitizedCollectionPrefix: '',
115
- sanitizedDocPrefix: '',
116
- sanitizedFilename: 'test.png',
117
- storageFilePath: 'test.png'
118
- });
119
- });
120
- });
121
- describe('collection prefix boundaries', ()=>{
122
- it('should accept a file key within a slash-terminated collection prefix', ()=>{
123
- expect(isStoragePathWithinCollectionPrefix({
124
- collectionPrefix: 'media/',
125
- docPrefix: 'media/documents/test.png'
126
- })).toBe(true);
127
- });
128
- });
129
- describe('sanitization', ()=>{
130
- it.each([
131
- './media/./images',
132
- 'media\\images',
133
- '/media//images'
134
- ])('should canonicalize equivalent prefix paths', (docPrefix)=>{
135
- const result = buildStoragePathData({
136
- docPrefix,
137
- filename: 'test.png'
138
- });
139
- expect(result).toEqual({
140
- fileKey: 'media/images/test.png',
141
- sanitizedCollectionPrefix: '',
142
- sanitizedDocPrefix: 'media/images',
143
- sanitizedFilename: 'test.png',
144
- storageFilePath: 'media/images/test.png'
145
- });
146
- });
147
- it('should remove path traversal segments from collectionPrefix', ()=>{
148
- const result = buildStoragePathData({
149
- collectionPrefix: '../../../etc',
150
- filename: 'test.png',
151
- useCompositePrefixes: false
152
- });
153
- expect(result).toEqual({
154
- fileKey: 'etc/test.png',
155
- sanitizedCollectionPrefix: 'etc',
156
- sanitizedDocPrefix: '',
157
- sanitizedFilename: 'test.png',
158
- storageFilePath: 'etc/test.png'
159
- });
160
- expect(result.fileKey).not.toContain('..');
161
- });
162
- it('should remove path traversal segments from docPrefix', ()=>{
163
- const result = buildStoragePathData({
164
- docPrefix: 'a/../../outside',
165
- filename: 'test.png',
166
- useCompositePrefixes: false
167
- });
168
- expect(result).toEqual({
169
- fileKey: 'a/outside/test.png',
170
- sanitizedCollectionPrefix: '',
171
- sanitizedDocPrefix: 'a/outside',
172
- sanitizedFilename: 'test.png',
173
- storageFilePath: 'a/outside/test.png'
174
- });
175
- expect(result.fileKey).not.toContain('..');
176
- });
177
- it('should remove control characters from prefixes', ()=>{
178
- const result = buildStoragePathData({
179
- collectionPrefix: 'test\x00\x1fprefix',
180
- filename: 'test.png',
181
- useCompositePrefixes: false
182
- });
183
- expect(result).toEqual({
184
- fileKey: 'testprefix/test.png',
185
- sanitizedCollectionPrefix: 'testprefix',
186
- sanitizedDocPrefix: '',
187
- sanitizedFilename: 'test.png',
188
- storageFilePath: 'testprefix/test.png'
189
- });
190
- expect(result.fileKey).not.toMatch(/[\x00-\x1f]/);
191
- });
192
- it('should normalize both prefixes after removing control characters in composite mode', ()=>{
193
- const result = buildStoragePathData({
194
- collectionPrefix: '.\x00./collection',
195
- docPrefix: '.\x00./doc',
196
- filename: 'test.png',
197
- useCompositePrefixes: true
198
- });
199
- expect(result).toEqual({
200
- fileKey: 'collection/doc/test.png',
201
- sanitizedCollectionPrefix: 'collection',
202
- sanitizedDocPrefix: 'doc',
203
- sanitizedFilename: 'test.png',
204
- storageFilePath: 'collection/doc/test.png'
205
- });
206
- expect(result.fileKey).not.toContain('..');
207
- });
208
- });
209
- });
210
- describe('buildUploadStoragePathData', ()=>{
211
- it.each([
212
- [
213
- 'invoices',
214
- false,
215
- 'media/invoices/file.png',
216
- 'media/invoices'
217
- ],
218
- [
219
- 'media/invoices',
220
- false,
221
- 'media/invoices/file.png',
222
- 'media/invoices'
223
- ],
224
- [
225
- '',
226
- false,
227
- 'media/file.png',
228
- ''
229
- ],
230
- [
231
- 'invoices',
232
- true,
233
- 'media/invoices/file.png',
234
- 'invoices'
235
- ]
236
- ])('should persist a readable destination for %s (composite %s)', (docPrefix, useCompositePrefixes, fileKey, storedPrefix)=>{
237
- const result = buildUploadStoragePathData({
238
- collectionPrefix: 'media',
239
- docPrefix,
240
- filename: 'file.png',
241
- useCompositePrefixes
242
- });
243
- expect(result.storageFilePath).toBe(fileKey);
244
- expect(result.sanitizedDocPrefix).toBe(storedPrefix);
245
- expect(buildStoragePathData({
246
- collectionPrefix: 'media',
247
- docPrefix: result.sanitizedDocPrefix,
248
- filename: 'file.png',
249
- useCompositePrefixes
250
- }).fileKey).toBe(fileKey);
251
- });
252
- });
253
-
254
- //# sourceMappingURL=buildStoragePathData.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/buildStoragePathData.spec.ts"],"sourcesContent":["import {\n buildStoragePathData,\n buildUploadStoragePathData,\n isStoragePathWithinCollectionPrefix,\n} from './buildStoragePathData.js'\nimport { describe, expect, it } from 'vitest'\n\ndescribe('buildStoragePathData', () => {\n describe('non-composite mode (useCompositePrefixes: false)', () => {\n it('should preserve the key of a legacy document outside the collection prefix', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'media/',\n docPrefix: 'media-archive',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n\n expect(result).toEqual({\n fileKey: 'media-archive/test.png',\n sanitizedCollectionPrefix: 'media',\n sanitizedDocPrefix: 'media-archive',\n sanitizedFilename: 'test.png',\n storageFilePath: 'media-archive/test.png',\n })\n })\n\n it('should fallback to collectionPrefix when docPrefix is empty', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'collection',\n docPrefix: '',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'collection/test.png',\n sanitizedCollectionPrefix: 'collection',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'collection/test.png',\n })\n })\n\n it('should fallback to collectionPrefix when docPrefix is undefined', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'collection',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'collection/test.png',\n sanitizedCollectionPrefix: 'collection',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'collection/test.png',\n })\n })\n\n it('should return only filename when both prefixes are empty', () => {\n const result = buildStoragePathData({\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'test.png',\n sanitizedCollectionPrefix: '',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'test.png',\n })\n })\n })\n\n describe('composite mode (useCompositePrefixes: true)', () => {\n it('should combine collectionPrefix and docPrefix', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'collection',\n docPrefix: 'document',\n filename: 'test.png',\n useCompositePrefixes: true,\n })\n expect(result).toEqual({\n fileKey: 'collection/document/test.png',\n sanitizedCollectionPrefix: 'collection',\n sanitizedDocPrefix: 'document',\n sanitizedFilename: 'test.png',\n storageFilePath: 'collection/document/test.png',\n })\n })\n\n it('should work with only collectionPrefix', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'collection',\n filename: 'test.png',\n useCompositePrefixes: true,\n })\n expect(result).toEqual({\n fileKey: 'collection/test.png',\n sanitizedCollectionPrefix: 'collection',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'collection/test.png',\n })\n })\n\n it('should work with only docPrefix', () => {\n const result = buildStoragePathData({\n docPrefix: 'document',\n filename: 'test.png',\n useCompositePrefixes: true,\n })\n expect(result).toEqual({\n fileKey: 'document/test.png',\n sanitizedCollectionPrefix: '',\n sanitizedDocPrefix: 'document',\n sanitizedFilename: 'test.png',\n storageFilePath: 'document/test.png',\n })\n })\n\n it('should return only filename when both prefixes are empty', () => {\n const result = buildStoragePathData({\n filename: 'test.png',\n useCompositePrefixes: true,\n })\n expect(result).toEqual({\n fileKey: 'test.png',\n sanitizedCollectionPrefix: '',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'test.png',\n })\n })\n })\n\n describe('collection prefix boundaries', () => {\n it('should accept a file key within a slash-terminated collection prefix', () => {\n expect(\n isStoragePathWithinCollectionPrefix({\n collectionPrefix: 'media/',\n docPrefix: 'media/documents/test.png',\n }),\n ).toBe(true)\n })\n })\n\n describe('sanitization', () => {\n it.each(['./media/./images', 'media\\\\images', '/media//images'])(\n 'should canonicalize equivalent prefix paths',\n (docPrefix) => {\n const result = buildStoragePathData({ docPrefix, filename: 'test.png' })\n\n expect(result).toEqual({\n fileKey: 'media/images/test.png',\n sanitizedCollectionPrefix: '',\n sanitizedDocPrefix: 'media/images',\n sanitizedFilename: 'test.png',\n storageFilePath: 'media/images/test.png',\n })\n },\n )\n\n it('should remove path traversal segments from collectionPrefix', () => {\n const result = buildStoragePathData({\n collectionPrefix: '../../../etc',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'etc/test.png',\n sanitizedCollectionPrefix: 'etc',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'etc/test.png',\n })\n expect(result.fileKey).not.toContain('..')\n })\n\n it('should remove path traversal segments from docPrefix', () => {\n const result = buildStoragePathData({\n docPrefix: 'a/../../outside',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'a/outside/test.png',\n sanitizedCollectionPrefix: '',\n sanitizedDocPrefix: 'a/outside',\n sanitizedFilename: 'test.png',\n storageFilePath: 'a/outside/test.png',\n })\n expect(result.fileKey).not.toContain('..')\n })\n\n it('should remove control characters from prefixes', () => {\n const result = buildStoragePathData({\n collectionPrefix: 'test\\x00\\x1fprefix',\n filename: 'test.png',\n useCompositePrefixes: false,\n })\n expect(result).toEqual({\n fileKey: 'testprefix/test.png',\n sanitizedCollectionPrefix: 'testprefix',\n sanitizedDocPrefix: '',\n sanitizedFilename: 'test.png',\n storageFilePath: 'testprefix/test.png',\n })\n expect(result.fileKey).not.toMatch(/[\\x00-\\x1f]/)\n })\n\n it('should normalize both prefixes after removing control characters in composite mode', () => {\n const result = buildStoragePathData({\n collectionPrefix: '.\\x00./collection',\n docPrefix: '.\\x00./doc',\n filename: 'test.png',\n useCompositePrefixes: true,\n })\n expect(result).toEqual({\n fileKey: 'collection/doc/test.png',\n sanitizedCollectionPrefix: 'collection',\n sanitizedDocPrefix: 'doc',\n sanitizedFilename: 'test.png',\n storageFilePath: 'collection/doc/test.png',\n })\n expect(result.fileKey).not.toContain('..')\n })\n })\n})\n\ndescribe('buildUploadStoragePathData', () => {\n it.each([\n ['invoices', false, 'media/invoices/file.png', 'media/invoices'],\n ['media/invoices', false, 'media/invoices/file.png', 'media/invoices'],\n ['', false, 'media/file.png', ''],\n ['invoices', true, 'media/invoices/file.png', 'invoices'],\n ] as const)(\n 'should persist a readable destination for %s (composite %s)',\n (docPrefix, useCompositePrefixes, fileKey, storedPrefix) => {\n const result = buildUploadStoragePathData({\n collectionPrefix: 'media',\n docPrefix,\n filename: 'file.png',\n useCompositePrefixes,\n })\n\n expect(result.storageFilePath).toBe(fileKey)\n expect(result.sanitizedDocPrefix).toBe(storedPrefix)\n expect(\n buildStoragePathData({\n collectionPrefix: 'media',\n docPrefix: result.sanitizedDocPrefix,\n filename: 'file.png',\n useCompositePrefixes,\n }).fileKey,\n ).toBe(fileKey)\n },\n )\n})\n"],"names":["buildStoragePathData","buildUploadStoragePathData","isStoragePathWithinCollectionPrefix","describe","expect","it","result","collectionPrefix","docPrefix","filename","useCompositePrefixes","toEqual","fileKey","sanitizedCollectionPrefix","sanitizedDocPrefix","sanitizedFilename","storageFilePath","toBe","each","not","toContain","toMatch","storedPrefix"],"mappings":"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"}
@@ -1,291 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { getFilePrefix } from './getFilePrefix.js';
3
- const makeReq = ({ docs = [] } = {})=>({
4
- payload: {
5
- find: vi.fn().mockResolvedValue({
6
- docs
7
- })
8
- }
9
- });
10
- const makeCollection = ({ hasPrefixField = false } = {})=>({
11
- slug: 'media',
12
- fields: hasPrefixField ? [
13
- {
14
- name: 'prefix',
15
- type: 'text'
16
- }
17
- ] : [],
18
- upload: {}
19
- });
20
- const whereOf = (req)=>JSON.stringify(req.payload.find.mock.calls[0][0].where);
21
- describe('getFilePrefix', ()=>{
22
- it('prefers an already-authorized document over a client upload context or query prefix', async ()=>{
23
- const req = makeReq({
24
- docs: [
25
- {
26
- prefix: 'db-prefix'
27
- }
28
- ]
29
- });
30
- const doc = {
31
- id: 1,
32
- prefix: 'invoices'
33
- };
34
- const result = await getFilePrefix({
35
- clientUploadContext: {
36
- prefix: 'reference-prefix'
37
- },
38
- collection: makeCollection(),
39
- collectionPrefix: 'media',
40
- doc,
41
- filename: 'logo.png',
42
- prefixQueryParam: 'query-prefix',
43
- req
44
- });
45
- expect(result).toBe('invoices');
46
- expect(req.payload.find).not.toHaveBeenCalled();
47
- });
48
- it('does not fall back to a lookup when the checked document has no prefix', async ()=>{
49
- const req = makeReq({
50
- docs: [
51
- {
52
- prefix: 'db-prefix'
53
- }
54
- ]
55
- });
56
- const result = await getFilePrefix({
57
- collection: makeCollection(),
58
- collectionPrefix: 'media',
59
- doc: {
60
- id: 1
61
- },
62
- filename: 'logo.png',
63
- req
64
- });
65
- expect(result).toBe('');
66
- expect(req.payload.find).not.toHaveBeenCalled();
67
- });
68
- it('contains a client upload context prefix beneath the collection prefix', async ()=>{
69
- const req = makeReq({
70
- docs: [
71
- {
72
- prefix: 'invoices'
73
- }
74
- ]
75
- });
76
- const result = await getFilePrefix({
77
- clientUploadContext: {
78
- prefix: 'invoices'
79
- },
80
- collection: makeCollection(),
81
- collectionPrefix: 'media',
82
- filename: 'file.png',
83
- req
84
- });
85
- expect(result).toBe('media/invoices');
86
- expect(req.payload.find).not.toHaveBeenCalled();
87
- });
88
- describe('authorized document (trusted)', ()=>{
89
- it('folds the object key into the document prefix and skips the database', async ()=>{
90
- const req = makeReq({
91
- docs: [
92
- {
93
- prefix: 'db-prefix'
94
- }
95
- ]
96
- });
97
- const result = await getFilePrefix({
98
- collection: makeCollection(),
99
- doc: {
100
- id: 1,
101
- _objectKey: 'abc123',
102
- prefix: 'doc-prefix'
103
- },
104
- filename: 'logo.png',
105
- req
106
- });
107
- expect(result).toBe('doc-prefix/abc123');
108
- expect(req.payload.find).not.toHaveBeenCalled();
109
- });
110
- it('returns the document prefix alone when it has no object key', async ()=>{
111
- const req = makeReq();
112
- const result = await getFilePrefix({
113
- collection: makeCollection(),
114
- doc: {
115
- id: 1,
116
- prefix: 'doc-prefix'
117
- },
118
- filename: 'logo.png',
119
- req
120
- });
121
- expect(result).toBe('doc-prefix');
122
- });
123
- it('sanitizes the document prefix', async ()=>{
124
- const req = makeReq();
125
- const result = await getFilePrefix({
126
- collection: makeCollection(),
127
- doc: {
128
- id: 1,
129
- prefix: '../secret'
130
- },
131
- filename: 'logo.png',
132
- req
133
- });
134
- expect(result).toBe('secret');
135
- });
136
- });
137
- describe('verified clientUploadContext (trusted)', ()=>{
138
- it('folds the server-owned object key into the prefix and skips the database', async ()=>{
139
- const req = makeReq();
140
- const result = await getFilePrefix({
141
- clientUploadContext: {
142
- _objectKey: 'abc123',
143
- prefix: 'documents'
144
- },
145
- collection: makeCollection(),
146
- filename: 'logo.png',
147
- req
148
- });
149
- expect(result).toBe('documents/abc123');
150
- expect(req.payload.find).not.toHaveBeenCalled();
151
- });
152
- it('returns the prefix alone when the context has no object key', async ()=>{
153
- const req = makeReq();
154
- const result = await getFilePrefix({
155
- clientUploadContext: {
156
- prefix: 'documents'
157
- },
158
- collection: makeCollection(),
159
- filename: 'logo.png',
160
- req
161
- });
162
- expect(result).toBe('documents');
163
- });
164
- });
165
- describe('access-controlled database resolution', ()=>{
166
- it('does NOT short-circuit on a client-supplied prefix — the access-controlled query still runs', async ()=>{
167
- const req = makeReq({
168
- docs: [
169
- {
170
- _objectKey: 'abc123',
171
- prefix: 'documents'
172
- }
173
- ]
174
- });
175
- await getFilePrefix({
176
- collection: makeCollection({
177
- hasPrefixField: true
178
- }),
179
- filename: 'logo.png',
180
- prefixQueryParam: 'documents',
181
- req
182
- });
183
- // A client-supplied prefix must not bypass the access-controlled lookup.
184
- expect(req.payload.find).toHaveBeenCalledOnce();
185
- });
186
- it('queries with access control enabled', async ()=>{
187
- const req = makeReq({
188
- docs: [
189
- {
190
- prefix: 'db-prefix'
191
- }
192
- ]
193
- });
194
- await getFilePrefix({
195
- collection: makeCollection(),
196
- filename: 'logo.png',
197
- req
198
- });
199
- expect(req.payload.find).toHaveBeenCalledWith(expect.objectContaining({
200
- overrideAccess: false,
201
- req
202
- }));
203
- });
204
- it('folds the stored object key into the resolved prefix', async ()=>{
205
- const req = makeReq({
206
- docs: [
207
- {
208
- _objectKey: 'abc123',
209
- prefix: 'db-prefix'
210
- }
211
- ]
212
- });
213
- const result = await getFilePrefix({
214
- collection: makeCollection(),
215
- filename: 'logo.png',
216
- req
217
- });
218
- expect(result).toBe('db-prefix/abc123');
219
- });
220
- it('returns an empty string when no document is found', async ()=>{
221
- const req = makeReq({
222
- docs: []
223
- });
224
- const result = await getFilePrefix({
225
- collection: makeCollection(),
226
- filename: 'logo.png',
227
- req
228
- });
229
- expect(result).toBe('');
230
- });
231
- it('prioritizes a verified clientUploadContext over the database query', async ()=>{
232
- const req = makeReq({
233
- docs: [
234
- {
235
- prefix: 'db-prefix'
236
- }
237
- ]
238
- });
239
- const result = await getFilePrefix({
240
- clientUploadContext: {
241
- prefix: 'context-prefix'
242
- },
243
- collection: makeCollection(),
244
- filename: 'logo.png',
245
- req
246
- });
247
- expect(result).toBe('context-prefix');
248
- expect(req.payload.find).not.toHaveBeenCalled();
249
- });
250
- });
251
- describe('client prefix as a disambiguation filter only', ()=>{
252
- it('adds the prefix filter when the collection persists a prefix field', async ()=>{
253
- const req = makeReq({
254
- docs: [
255
- {
256
- prefix: 'documents'
257
- }
258
- ]
259
- });
260
- await getFilePrefix({
261
- collection: makeCollection({
262
- hasPrefixField: true
263
- }),
264
- filename: 'logo.png',
265
- prefixQueryParam: 'documents',
266
- req
267
- });
268
- expect(whereOf(req)).toContain('prefix');
269
- });
270
- it('omits the prefix filter when the collection has no prefix field (avoids querying a missing field)', async ()=>{
271
- const req = makeReq({
272
- docs: [
273
- {
274
- prefix: ''
275
- }
276
- ]
277
- });
278
- await getFilePrefix({
279
- collection: makeCollection({
280
- hasPrefixField: false
281
- }),
282
- filename: 'logo.png',
283
- prefixQueryParam: 'anything',
284
- req
285
- });
286
- expect(whereOf(req)).not.toContain('prefix');
287
- });
288
- });
289
- });
290
-
291
- //# sourceMappingURL=getFilePrefix.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/getFilePrefix.spec.ts"],"sourcesContent":["import type { CollectionConfig, PayloadRequest } from 'payload'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport { getFilePrefix } from './getFilePrefix.js'\n\nconst makeReq = ({ docs = [] }: { docs?: unknown[] } = {}) =>\n ({\n payload: {\n find: vi.fn().mockResolvedValue({ docs }),\n },\n }) as unknown as PayloadRequest\n\nconst makeCollection = ({\n hasPrefixField = false,\n}: { hasPrefixField?: boolean } = {}): CollectionConfig =>\n ({\n slug: 'media',\n fields: hasPrefixField ? [{ name: 'prefix', type: 'text' }] : [],\n upload: {},\n }) as unknown as CollectionConfig\n\nconst whereOf = (req: PayloadRequest) =>\n JSON.stringify(\n (req.payload.find as unknown as { mock: { calls: [{ where: unknown }][] } }).mock.calls[0][0]\n .where,\n )\n\ndescribe('getFilePrefix', () => {\n it('prefers an already-authorized document over a client upload context or query prefix', async () => {\n const req = makeReq({ docs: [{ prefix: 'db-prefix' }] })\n const doc = { id: 1, prefix: 'invoices' }\n\n const result = await getFilePrefix({\n clientUploadContext: { prefix: 'reference-prefix' },\n collection: makeCollection(),\n collectionPrefix: 'media',\n doc,\n filename: 'logo.png',\n prefixQueryParam: 'query-prefix',\n req,\n })\n\n expect(result).toBe('invoices')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('does not fall back to a lookup when the checked document has no prefix', async () => {\n const req = makeReq({ docs: [{ prefix: 'db-prefix' }] })\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n collectionPrefix: 'media',\n doc: { id: 1 },\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('contains a client upload context prefix beneath the collection prefix', async () => {\n const req = makeReq({ docs: [{ prefix: 'invoices' }] })\n\n const result = await getFilePrefix({\n clientUploadContext: { prefix: 'invoices' },\n collection: makeCollection(),\n collectionPrefix: 'media',\n filename: 'file.png',\n req,\n })\n\n expect(result).toBe('media/invoices')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n describe('authorized document (trusted)', () => {\n it('folds the object key into the document prefix and skips the database', async () => {\n const req = makeReq({ docs: [{ prefix: 'db-prefix' }] })\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n doc: { id: 1, _objectKey: 'abc123', prefix: 'doc-prefix' },\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('doc-prefix/abc123')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('returns the document prefix alone when it has no object key', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n doc: { id: 1, prefix: 'doc-prefix' },\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('doc-prefix')\n })\n\n it('sanitizes the document prefix', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n doc: { id: 1, prefix: '../secret' },\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('secret')\n })\n })\n\n describe('verified clientUploadContext (trusted)', () => {\n it('folds the server-owned object key into the prefix and skips the database', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n clientUploadContext: { _objectKey: 'abc123', prefix: 'documents' },\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('documents/abc123')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n\n it('returns the prefix alone when the context has no object key', async () => {\n const req = makeReq()\n\n const result = await getFilePrefix({\n clientUploadContext: { prefix: 'documents' },\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('documents')\n })\n })\n\n describe('access-controlled database resolution', () => {\n it('does NOT short-circuit on a client-supplied prefix — the access-controlled query still runs', async () => {\n const req = makeReq({ docs: [{ _objectKey: 'abc123', prefix: 'documents' }] })\n\n await getFilePrefix({\n collection: makeCollection({ hasPrefixField: true }),\n filename: 'logo.png',\n prefixQueryParam: 'documents',\n req,\n })\n\n // A client-supplied prefix must not bypass the access-controlled lookup.\n expect(req.payload.find).toHaveBeenCalledOnce()\n })\n\n it('queries with access control enabled', async () => {\n const req = makeReq({ docs: [{ prefix: 'db-prefix' }] })\n\n await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(req.payload.find).toHaveBeenCalledWith(\n expect.objectContaining({ overrideAccess: false, req }),\n )\n })\n\n it('folds the stored object key into the resolved prefix', async () => {\n const req = makeReq({ docs: [{ _objectKey: 'abc123', prefix: 'db-prefix' }] })\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('db-prefix/abc123')\n })\n\n it('returns an empty string when no document is found', async () => {\n const req = makeReq({ docs: [] })\n\n const result = await getFilePrefix({\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('')\n })\n\n it('prioritizes a verified clientUploadContext over the database query', async () => {\n const req = makeReq({ docs: [{ prefix: 'db-prefix' }] })\n\n const result = await getFilePrefix({\n clientUploadContext: { prefix: 'context-prefix' },\n collection: makeCollection(),\n filename: 'logo.png',\n req,\n })\n\n expect(result).toBe('context-prefix')\n expect(req.payload.find).not.toHaveBeenCalled()\n })\n })\n\n describe('client prefix as a disambiguation filter only', () => {\n it('adds the prefix filter when the collection persists a prefix field', async () => {\n const req = makeReq({ docs: [{ prefix: 'documents' }] })\n\n await getFilePrefix({\n collection: makeCollection({ hasPrefixField: true }),\n filename: 'logo.png',\n prefixQueryParam: 'documents',\n req,\n })\n\n expect(whereOf(req)).toContain('prefix')\n })\n\n it('omits the prefix filter when the collection has no prefix field (avoids querying a missing field)', async () => {\n const req = makeReq({ docs: [{ prefix: '' }] })\n\n await getFilePrefix({\n collection: makeCollection({ hasPrefixField: false }),\n filename: 'logo.png',\n prefixQueryParam: 'anything',\n req,\n })\n\n expect(whereOf(req)).not.toContain('prefix')\n })\n })\n})\n"],"names":["describe","expect","it","vi","getFilePrefix","makeReq","docs","payload","find","fn","mockResolvedValue","makeCollection","hasPrefixField","slug","fields","name","type","upload","whereOf","req","JSON","stringify","mock","calls","where","prefix","doc","id","result","clientUploadContext","collection","collectionPrefix","filename","prefixQueryParam","toBe","not","toHaveBeenCalled","_objectKey","toHaveBeenCalledOnce","toHaveBeenCalledWith","objectContaining","overrideAccess","toContain"],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- import type { Config, PayloadHandler } from 'payload';
2
- export declare const initClientUploads: <ExtraProps extends Record<string, unknown>, T>({ clientHandler, collections, config, enabled, extraClientHandlerProps, serverHandler, serverHandlerPath, }: {
3
- /** Path to clientHandler component */
4
- clientHandler: string;
5
- collections: Record<string, T>;
6
- config: Config;
7
- enabled: boolean;
8
- /** extra props to pass to the client handler */
9
- extraClientHandlerProps?: (collection: T) => ExtraProps;
10
- serverHandler: PayloadHandler;
11
- serverHandlerPath: string;
12
- }) => void;
13
- //# sourceMappingURL=initClientUploads.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"initClientUploads.d.ts","sourceRoot":"","sources":["../../src/utilities/initClientUploads.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAErD,eAAO,MAAM,iBAAiB,GAAI,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,+GAQ5E;IACD,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,gDAAgD;IAChD,uBAAuB,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,UAAU,CAAA;IACvD,aAAa,EAAE,cAAc,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;CAC1B,SAkFA,CAAA"}