@payloadcms/plugin-cloud-storage 1.0.15 → 1.0.17-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 (214) hide show
  1. package/.editorconfig +10 -10
  2. package/.eslintrc.js +14 -14
  3. package/.gitignore +248 -248
  4. package/.prettierignore +1 -1
  5. package/.prettierrc.js +8 -8
  6. package/.vscode/launch.json +40 -28
  7. package/.vscode/settings.json +9 -9
  8. package/LICENSE.md +22 -22
  9. package/README.md +196 -178
  10. package/azure.d.ts +1 -1
  11. package/azure.js +1 -1
  12. package/dev/.env +11 -15
  13. package/dev/.env.example +21 -21
  14. package/dev/nodemon.json +8 -8
  15. package/dev/package.json +34 -32
  16. package/dev/src/collections/Media.ts +56 -56
  17. package/dev/src/collections/Users.ts +23 -23
  18. package/dev/src/mocks/fsMock.js +1 -1
  19. package/dev/src/mocks/promisifyMock.js +1 -1
  20. package/dev/src/payload.config.ts +111 -111
  21. package/dev/src/server.ts +26 -26
  22. package/dev/tsconfig.json +20 -20
  23. package/dist/adapters/azure/fileStub.d.ts +2 -2
  24. package/dist/adapters/azure/fileStub.js +3 -3
  25. package/dist/adapters/azure/generateURL.d.ts +7 -7
  26. package/dist/adapters/azure/generateURL.js +15 -15
  27. package/dist/adapters/azure/handleDelete.d.ts +9 -9
  28. package/dist/adapters/azure/handleDelete.js +63 -63
  29. package/dist/adapters/azure/handleUpload.d.ts +10 -10
  30. package/dist/adapters/azure/handleUpload.js +80 -80
  31. package/dist/adapters/azure/index.d.ts +8 -8
  32. package/dist/adapters/azure/index.js +42 -42
  33. package/dist/adapters/azure/index.js.map +1 -1
  34. package/dist/adapters/azure/mock.d.ts +13 -13
  35. package/dist/adapters/azure/mock.js +12 -12
  36. package/dist/adapters/azure/staticHandler.d.ts +9 -9
  37. package/dist/adapters/azure/staticHandler.js +81 -81
  38. package/dist/adapters/azure/webpack.d.ts +2 -2
  39. package/dist/adapters/azure/webpack.js +24 -24
  40. package/dist/adapters/azure/webpack.js.map +1 -1
  41. package/dist/adapters/gcs/generateURL.d.ts +8 -8
  42. package/dist/adapters/gcs/generateURL.js +15 -15
  43. package/dist/adapters/gcs/handleDelete.d.ts +8 -8
  44. package/dist/adapters/gcs/handleDelete.js +62 -62
  45. package/dist/adapters/gcs/handleUpload.d.ts +12 -12
  46. package/dist/adapters/gcs/handleUpload.js +72 -72
  47. package/dist/adapters/gcs/index.d.ts +8 -8
  48. package/dist/adapters/gcs/index.js +35 -35
  49. package/dist/adapters/gcs/mock.d.ts +1 -1
  50. package/dist/adapters/gcs/mock.js +4 -4
  51. package/dist/adapters/gcs/staticHandler.d.ts +10 -10
  52. package/dist/adapters/gcs/staticHandler.js +76 -76
  53. package/dist/adapters/gcs/webpack.d.ts +2 -2
  54. package/dist/adapters/gcs/webpack.js +24 -24
  55. package/dist/adapters/gcs/webpack.js.map +1 -1
  56. package/dist/adapters/s3/fileStub.d.ts +2 -2
  57. package/dist/adapters/s3/fileStub.js +3 -3
  58. package/dist/adapters/s3/generateURL.d.ts +8 -8
  59. package/dist/adapters/s3/generateURL.js +15 -15
  60. package/dist/adapters/s3/handleDelete.d.ts +8 -8
  61. package/dist/adapters/s3/handleDelete.js +63 -63
  62. package/dist/adapters/s3/handleUpload.d.ts +12 -12
  63. package/dist/adapters/s3/handleUpload.js +93 -93
  64. package/dist/adapters/s3/index.d.ts +8 -8
  65. package/dist/adapters/s3/index.js +59 -59
  66. package/dist/adapters/s3/mock.d.ts +8 -8
  67. package/dist/adapters/s3/mock.js +9 -9
  68. package/dist/adapters/s3/staticHandler.d.ts +10 -10
  69. package/dist/adapters/s3/staticHandler.js +81 -80
  70. package/dist/adapters/s3/staticHandler.js.map +1 -1
  71. package/dist/adapters/s3/webpack.d.ts +2 -2
  72. package/dist/adapters/s3/webpack.js +24 -24
  73. package/dist/adapters/s3/webpack.js.map +1 -1
  74. package/dist/fields/getFields.d.ts +11 -11
  75. package/dist/fields/getFields.js +118 -118
  76. package/dist/hooks/afterDelete.d.ts +10 -10
  77. package/dist/hooks/afterDelete.js +91 -88
  78. package/dist/hooks/afterDelete.js.map +1 -1
  79. package/dist/hooks/afterRead.d.ts +12 -12
  80. package/dist/hooks/afterRead.js +79 -79
  81. package/dist/hooks/beforeChange.d.ts +10 -10
  82. package/dist/hooks/beforeChange.js +105 -77
  83. package/dist/hooks/beforeChange.js.map +1 -1
  84. package/dist/index.d.ts +1 -1
  85. package/dist/index.js +5 -5
  86. package/dist/plugin.d.ts +3 -3
  87. package/dist/plugin.js +130 -124
  88. package/dist/plugin.js.map +1 -1
  89. package/dist/types.d.ts +68 -62
  90. package/dist/types.js +2 -2
  91. package/dist/utilities/getFilePrefix.d.ts +5 -5
  92. package/dist/utilities/getFilePrefix.js +80 -80
  93. package/dist/utilities/getIncomingFiles.d.ts +7 -7
  94. package/dist/utilities/getIncomingFiles.js +37 -37
  95. package/dist/utilities/getRangeFromHeader.d.ts +6 -6
  96. package/dist/utilities/getRangeFromHeader.js +66 -66
  97. package/dist/webpack.d.ts +9 -9
  98. package/dist/webpack.js +39 -39
  99. package/docs/local-dev.md +47 -47
  100. package/eslint-config/index.js +15 -15
  101. package/eslint-config/rules/import.js +38 -38
  102. package/eslint-config/rules/prettier.js +7 -7
  103. package/eslint-config/rules/style.js +21 -21
  104. package/eslint-config/rules/typescript.js +628 -628
  105. package/gcs.d.ts +1 -1
  106. package/gcs.js +1 -1
  107. package/package.json +67 -67
  108. package/s3.d.ts +1 -1
  109. package/s3.js +1 -1
  110. package/src/adapters/azure/emulator/docker-compose.yml +16 -16
  111. package/src/adapters/azure/fileStub.js +1 -1
  112. package/src/adapters/azure/generateURL.ts +13 -13
  113. package/src/adapters/azure/handleDelete.ts +16 -16
  114. package/src/adapters/azure/handleUpload.ts +41 -41
  115. package/src/adapters/azure/index.ts +48 -47
  116. package/src/adapters/azure/mock.js +13 -13
  117. package/src/adapters/azure/staticHandler.ts +38 -38
  118. package/src/adapters/azure/webpack.ts +24 -20
  119. package/src/adapters/gcs/emulator/docker-compose.yml +15 -15
  120. package/src/adapters/gcs/generateURL.ts +16 -16
  121. package/src/adapters/gcs/handleDelete.ts +16 -16
  122. package/src/adapters/gcs/handleUpload.ts +34 -34
  123. package/src/adapters/gcs/index.ts +37 -37
  124. package/src/adapters/gcs/mock.js +3 -3
  125. package/src/adapters/gcs/staticHandler.ts +34 -34
  126. package/src/adapters/gcs/webpack.ts +21 -17
  127. package/src/adapters/s3/emulator/.localstack/cache/machine.json +1 -0
  128. package/src/adapters/s3/emulator/.localstack/cache/server.test.pem +127 -0
  129. package/src/adapters/s3/emulator/.localstack/cache/server.test.pem.crt +99 -0
  130. package/src/adapters/s3/emulator/.localstack/cache/server.test.pem.key +28 -0
  131. package/src/adapters/s3/emulator/.localstack/cache/service-catalog-2_1_1_dev-1_29_149.pickle +0 -0
  132. package/src/adapters/s3/emulator/docker-compose.yml +15 -15
  133. package/src/adapters/s3/generateURL.ts +14 -14
  134. package/src/adapters/s3/handleDelete.ts +17 -17
  135. package/src/adapters/s3/index.ts +38 -38
  136. package/src/adapters/s3/mock.js +9 -9
  137. package/src/adapters/s3/staticHandler.ts +41 -40
  138. package/src/adapters/s3/webpack.ts +4 -0
  139. package/src/fields/getFields.ts +155 -155
  140. package/src/hooks/afterDelete.ts +35 -35
  141. package/src/hooks/afterRead.ts +38 -38
  142. package/src/hooks/beforeChange.ts +59 -30
  143. package/src/index.ts +1 -1
  144. package/src/plugin.ts +101 -94
  145. package/src/types.ts +79 -73
  146. package/src/utilities/getFilePrefix.ts +26 -26
  147. package/src/utilities/getIncomingFiles.ts +44 -44
  148. package/src/utilities/getRangeFromHeader.ts +27 -27
  149. package/src/webpack.ts +46 -46
  150. package/tsconfig.json +23 -23
  151. package/yarn-error.log +8163 -0
  152. package/yarn.lock +8062 -8155
  153. package/.idea/.gitignore +0 -5
  154. package/.idea/httpRequests/2023-04-07T152957.206.png +0 -0
  155. package/.idea/httpRequests/2023-04-07T153025.403.html +0 -10
  156. package/.idea/httpRequests/2023-04-07T153146.200.png +0 -0
  157. package/.idea/httpRequests/http-client.cookies +0 -1
  158. package/.idea/httpRequests/http-requests-log.http +0 -74
  159. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  160. package/.idea/jsLinters/eslint.xml +0 -6
  161. package/.idea/modules.xml +0 -8
  162. package/.idea/plugin-cloud-storage.iml +0 -12
  163. package/.idea/vcs.xml +0 -6
  164. package/.idea/workspace.xml +0 -269
  165. package/dev/build/127.d2c2ffcfff69fabfdd1b.js +0 -1
  166. package/dev/build/16.17dbe03b1d0a96f3e564.js +0 -2
  167. package/dev/build/16.17dbe03b1d0a96f3e564.js.LICENSE.txt +0 -8
  168. package/dev/build/171.bbcbae3ea90468ad0cad.js +0 -2
  169. package/dev/build/171.bbcbae3ea90468ad0cad.js.LICENSE.txt +0 -8
  170. package/dev/build/18.e50c27edff6716f930d9.js +0 -1
  171. package/dev/build/205.33c7a29683ba98de93e0.js +0 -1
  172. package/dev/build/2211c49456cd07331ea9.woff +0 -0
  173. package/dev/build/234.79395f82c18207c13766.js +0 -1
  174. package/dev/build/266.9d4a240b3e0985bd7dd5.js +0 -1
  175. package/dev/build/296.4c5d646257b42c915834.js +0 -1
  176. package/dev/build/304.40dbe690de322c8f7c0d.js +0 -2
  177. package/dev/build/304.40dbe690de322c8f7c0d.js.LICENSE.txt +0 -37
  178. package/dev/build/349.446c12bffd3905085fdb.js +0 -1
  179. package/dev/build/354.5acd04b85b96a9839125.js +0 -1
  180. package/dev/build/40ad7515b8674bb854a1.woff2 +0 -0
  181. package/dev/build/422.086542466cdc9f6a2437.js +0 -2
  182. package/dev/build/422.086542466cdc9f6a2437.js.LICENSE.txt +0 -6
  183. package/dev/build/491.0bfe1bb0ecfe383179aa.js +0 -1
  184. package/dev/build/4d8845b830f4e8e2affb.png +0 -0
  185. package/dev/build/51922ceb71da289688d3.woff2 +0 -0
  186. package/dev/build/522443364fda49e9e0ed.woff2 +0 -0
  187. package/dev/build/531.1c6f53f3b44a3c45b444.js +0 -2
  188. package/dev/build/531.1c6f53f3b44a3c45b444.js.LICENSE.txt +0 -6
  189. package/dev/build/570.f2d9b99706765fbf0225.js +0 -1
  190. package/dev/build/599.570a04990d5806004f61.js +0 -1
  191. package/dev/build/5b718d9772de251a8c0a.woff2 +0 -0
  192. package/dev/build/778.41ae26bcd617861ad586.js +0 -1
  193. package/dev/build/783.0117995f2ff6036d6746.js +0 -1
  194. package/dev/build/787999a6af6a17efbc7c.woff +0 -0
  195. package/dev/build/78b8935fb481e11c92ce.woff +0 -0
  196. package/dev/build/860.7688681d3269f3f16e9a.js +0 -1
  197. package/dev/build/892.1a4ca5ac67d81038ceec.js +0 -1
  198. package/dev/build/896.d8cb1160388dc29d6364.js +0 -1
  199. package/dev/build/8b4ddd0d08500553efde.woff +0 -0
  200. package/dev/build/8f612153248094525d9d.woff +0 -0
  201. package/dev/build/995.cc11e738ff81a85821b4.js +0 -1
  202. package/dev/build/9c7dfd0036f7bd24b053.woff2 +0 -0
  203. package/dev/build/a1cfdc5b5250b7c4b481.woff2 +0 -0
  204. package/dev/build/d7aeda9e48ce098e7b48.woff +0 -0
  205. package/dev/build/e009f21405b4d7e89367.woff2 +0 -0
  206. package/dev/build/e7caa9e17af6ac87d182.woff +0 -0
  207. package/dev/build/ebcc1430049fddb274f8.svg +0 -15
  208. package/dev/build/efe8f6a3b46446cc9135.woff +0 -0
  209. package/dev/build/f53bb8d4b29adc903703.woff2 +0 -0
  210. package/dev/build/index.html +0 -1
  211. package/dev/build/main.a2003d502fbb9aaa3e8d.js +0 -2
  212. package/dev/build/main.a2003d502fbb9aaa3e8d.js.LICENSE.txt +0 -57
  213. package/dev/build/styles.css +0 -1
  214. package/dev/build/styles.fa29d16b0baf5b98a1cf.js +0 -1
@@ -1,38 +1,38 @@
1
- import * as AWS from '@aws-sdk/client-s3'
2
- import type { Adapter, GeneratedAdapter } from '../../types'
3
- import { getGenerateURL } from './generateURL'
4
- import { getHandler } from './staticHandler'
5
- import { getHandleDelete } from './handleDelete'
6
- import { getHandleUpload } from './handleUpload'
7
- import { extendWebpackConfig } from './webpack'
8
-
9
- export interface Args {
10
- config: AWS.S3ClientConfig
11
- bucket: string
12
- acl?: 'private' | 'public-read'
13
- }
14
-
15
- export const s3Adapter =
16
- ({ config, bucket, acl }: Args): Adapter =>
17
- ({ collection, prefix }): GeneratedAdapter => {
18
- let storageClient: AWS.S3 | null = null
19
- const getStorageClient: () => AWS.S3 = () => {
20
- if (storageClient) return storageClient
21
- storageClient = new AWS.S3(config)
22
- return storageClient
23
- }
24
-
25
- return {
26
- handleUpload: getHandleUpload({
27
- collection,
28
- getStorageClient,
29
- bucket,
30
- acl,
31
- prefix,
32
- }),
33
- handleDelete: getHandleDelete({ getStorageClient, bucket }),
34
- generateURL: getGenerateURL({ bucket, config }),
35
- staticHandler: getHandler({ bucket, getStorageClient, collection }),
36
- webpack: extendWebpackConfig,
37
- }
38
- }
1
+ import * as AWS from '@aws-sdk/client-s3'
2
+ import type { Adapter, GeneratedAdapter } from '../../types'
3
+ import { getGenerateURL } from './generateURL'
4
+ import { getHandler } from './staticHandler'
5
+ import { getHandleDelete } from './handleDelete'
6
+ import { getHandleUpload } from './handleUpload'
7
+ import { extendWebpackConfig } from './webpack'
8
+
9
+ export interface Args {
10
+ config: AWS.S3ClientConfig
11
+ bucket: string
12
+ acl?: 'private' | 'public-read'
13
+ }
14
+
15
+ export const s3Adapter =
16
+ ({ config, bucket, acl }: Args): Adapter =>
17
+ ({ collection, prefix }): GeneratedAdapter => {
18
+ let storageClient: AWS.S3 | null = null
19
+ const getStorageClient: () => AWS.S3 = () => {
20
+ if (storageClient) return storageClient
21
+ storageClient = new AWS.S3(config)
22
+ return storageClient
23
+ }
24
+
25
+ return {
26
+ handleUpload: getHandleUpload({
27
+ collection,
28
+ getStorageClient,
29
+ bucket,
30
+ acl,
31
+ prefix,
32
+ }),
33
+ handleDelete: getHandleDelete({ getStorageClient, bucket }),
34
+ generateURL: getGenerateURL({ bucket, config }),
35
+ staticHandler: getHandler({ bucket, getStorageClient, collection }),
36
+ webpack: extendWebpackConfig,
37
+ }
38
+ }
@@ -1,9 +1,9 @@
1
- exports.S3 = () => null
2
- exports.Upload = () => null
3
-
4
- exports.HeadObjectCommand = () => null
5
- exports.PutObjectCommand = () => null
6
- exports.UploadPartCommand = () => null
7
- exports.CreateMultipartUploadCommand = () => null
8
- exports.CompleteMultipartUploadCommand = () => null
9
- exports.PutObjectTaggingCommand = () => null
1
+ exports.S3 = () => null
2
+ exports.Upload = () => null
3
+
4
+ exports.HeadObjectCommand = () => null
5
+ exports.PutObjectCommand = () => null
6
+ exports.UploadPartCommand = () => null
7
+ exports.CreateMultipartUploadCommand = () => null
8
+ exports.CompleteMultipartUploadCommand = () => null
9
+ exports.PutObjectTaggingCommand = () => null
@@ -1,40 +1,41 @@
1
- import path from 'path'
2
- import type { Readable } from 'stream'
3
- import type * as AWS from '@aws-sdk/client-s3'
4
- import type { CollectionConfig } from 'payload/types'
5
- import type { StaticHandler } from '../../types'
6
- import { getFilePrefix } from '../../utilities/getFilePrefix'
7
-
8
- interface Args {
9
- getStorageClient: () => AWS.S3
10
- bucket: string
11
- collection: CollectionConfig
12
- }
13
-
14
- export const getHandler = ({ getStorageClient, bucket, collection }: Args): StaticHandler => {
15
- return async (req, res, next) => {
16
- try {
17
- const prefix = await getFilePrefix({ req, collection })
18
-
19
- const object = await getStorageClient().getObject({
20
- Bucket: bucket,
21
- Key: path.posix.join(prefix, req.params.filename),
22
- })
23
-
24
- res.set({
25
- 'Content-Length': object.ContentLength,
26
- 'Content-Type': object.ContentType,
27
- ETag: object.ETag,
28
- })
29
-
30
- if (object?.Body) {
31
- return (object.Body as Readable).pipe(res)
32
- }
33
-
34
- return next()
35
- } catch (err: unknown) {
36
- req.payload.logger.error(err)
37
- return next()
38
- }
39
- }
40
- }
1
+ import path from 'path'
2
+ import type { Readable } from 'stream'
3
+ import type * as AWS from '@aws-sdk/client-s3'
4
+ import type { CollectionConfig } from 'payload/types'
5
+ import type { StaticHandler } from '../../types'
6
+ import { getFilePrefix } from '../../utilities/getFilePrefix'
7
+
8
+ interface Args {
9
+ getStorageClient: () => AWS.S3
10
+ bucket: string
11
+ collection: CollectionConfig
12
+ }
13
+
14
+ export const getHandler = ({ getStorageClient, bucket, collection }: Args): StaticHandler => {
15
+ return async (req, res, next) => {
16
+ try {
17
+ const prefix = await getFilePrefix({ req, collection })
18
+
19
+ const object = await getStorageClient().getObject({
20
+ Bucket: bucket,
21
+ Key: path.posix.join(prefix, req.params.filename),
22
+ })
23
+
24
+ res.set({
25
+ 'Accept-Ranges': object.AcceptRanges,
26
+ 'Content-Length': object.ContentLength,
27
+ 'Content-Type': object.ContentType,
28
+ ETag: object.ETag,
29
+ })
30
+
31
+ if (object?.Body) {
32
+ return (object.Body as Readable).pipe(res)
33
+ }
34
+
35
+ return next()
36
+ } catch (err: unknown) {
37
+ req.payload.logger.error(err)
38
+ return next()
39
+ }
40
+ }
41
+ }
@@ -6,6 +6,10 @@ export const extendWebpackConfig = (existingWebpackConfig: WebpackConfig): Webpa
6
6
  ...existingWebpackConfig,
7
7
  resolve: {
8
8
  ...(existingWebpackConfig.resolve || {}),
9
+ fallback: {
10
+ ...(existingWebpackConfig.resolve?.fallback ? existingWebpackConfig.resolve.fallback : {}),
11
+ stream: false,
12
+ },
9
13
  alias: {
10
14
  ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}),
11
15
  '@aws-sdk/client-s3': path.resolve(__dirname, './mock.js'),
@@ -1,155 +1,155 @@
1
- import path from 'path'
2
- import type { GroupField, TextField } from 'payload/dist/fields/config/types'
3
- import type { CollectionConfig, Field } from 'payload/types'
4
- import { getAfterReadHook } from '../hooks/afterRead'
5
- import type { GeneratedAdapter, GenerateFileURL } from '../types'
6
-
7
- interface Args {
8
- collection: CollectionConfig
9
- disablePayloadAccessControl?: true
10
- generateFileURL?: GenerateFileURL
11
- prefix?: string
12
- adapter: GeneratedAdapter
13
- }
14
-
15
- export const getFields = ({
16
- adapter,
17
- collection,
18
- disablePayloadAccessControl,
19
- generateFileURL,
20
- prefix,
21
- }: Args): Field[] => {
22
- const baseURLField: Field = {
23
- name: 'url',
24
- label: 'URL',
25
- type: 'text',
26
- admin: {
27
- readOnly: true,
28
- hidden: true,
29
- },
30
- }
31
-
32
- const basePrefixField: Field = {
33
- name: 'prefix',
34
- type: 'text',
35
- admin: {
36
- readOnly: true,
37
- hidden: true,
38
- },
39
- }
40
-
41
- const fields = [...collection.fields]
42
-
43
- // Inject a hook into all URL fields to generate URLs
44
-
45
- let existingURLFieldIndex = -1
46
-
47
- const existingURLField = fields.find((existingField, i) => {
48
- if ('name' in existingField && existingField.name === 'url') {
49
- existingURLFieldIndex = i
50
- return true
51
- }
52
- return false
53
- }) as TextField
54
-
55
- if (existingURLFieldIndex > -1) {
56
- fields.splice(existingURLFieldIndex, 1)
57
- }
58
-
59
- fields.push({
60
- ...baseURLField,
61
- ...(existingURLField || {}),
62
- hooks: {
63
- afterRead: [
64
- getAfterReadHook({ adapter, collection, disablePayloadAccessControl, generateFileURL }),
65
- ...(existingURLField?.hooks?.afterRead || []),
66
- ],
67
- },
68
- })
69
-
70
- if (typeof collection.upload === 'object' && collection.upload.imageSizes) {
71
- let existingSizesFieldIndex = -1
72
-
73
- const existingSizesField = fields.find((existingField, i) => {
74
- if ('name' in existingField && existingField.name === 'sizes') {
75
- existingSizesFieldIndex = i
76
- return true
77
- }
78
-
79
- return false
80
- }) as GroupField
81
-
82
- if (existingSizesFieldIndex > -1) {
83
- fields.splice(existingSizesFieldIndex, 1)
84
- }
85
-
86
- const sizesField: Field = {
87
- ...(existingSizesField || {}),
88
- name: 'sizes',
89
- type: 'group',
90
- admin: {
91
- hidden: true,
92
- },
93
- fields: collection.upload.imageSizes.map(size => {
94
- const existingSizeField = existingSizesField?.fields.find(
95
- existingField => 'name' in existingField && existingField.name === size.name,
96
- ) as GroupField
97
-
98
- const existingSizeURLField = existingSizeField?.fields.find(
99
- existingField => 'name' in existingField && existingField.name === 'url',
100
- ) as GroupField
101
-
102
- return {
103
- ...existingSizeField,
104
- name: size.name,
105
- type: 'group',
106
- fields: [
107
- {
108
- ...(existingSizeURLField || {}),
109
- ...baseURLField,
110
- hooks: {
111
- afterRead: [
112
- getAfterReadHook({
113
- adapter,
114
- collection,
115
- size,
116
- disablePayloadAccessControl,
117
- generateFileURL,
118
- }),
119
- ...(existingSizeURLField?.hooks?.afterRead || []),
120
- ],
121
- },
122
- },
123
- ],
124
- }
125
- }),
126
- }
127
-
128
- fields.push(sizesField)
129
- }
130
-
131
- // If prefix is enabled, save it to db
132
- if (prefix) {
133
- let existingPrefixFieldIndex = -1
134
-
135
- const existingPrefixField = fields.find((existingField, i) => {
136
- if ('name' in existingField && existingField.name === 'prefix') {
137
- existingPrefixFieldIndex = i
138
- return true
139
- }
140
- return false
141
- }) as TextField
142
-
143
- if (existingPrefixFieldIndex > -1) {
144
- fields.splice(existingPrefixFieldIndex, 1)
145
- }
146
-
147
- fields.push({
148
- ...basePrefixField,
149
- ...(existingPrefixField || {}),
150
- defaultValue: path.posix.join(prefix),
151
- })
152
- }
153
-
154
- return fields
155
- }
1
+ import path from 'path'
2
+ import type { GroupField, TextField } from 'payload/dist/fields/config/types'
3
+ import type { CollectionConfig, Field } from 'payload/types'
4
+ import { getAfterReadHook } from '../hooks/afterRead'
5
+ import type { GeneratedAdapter, GenerateFileURL } from '../types'
6
+
7
+ interface Args {
8
+ collection: CollectionConfig
9
+ disablePayloadAccessControl?: true
10
+ generateFileURL?: GenerateFileURL
11
+ prefix?: string
12
+ adapter: GeneratedAdapter
13
+ }
14
+
15
+ export const getFields = ({
16
+ adapter,
17
+ collection,
18
+ disablePayloadAccessControl,
19
+ generateFileURL,
20
+ prefix,
21
+ }: Args): Field[] => {
22
+ const baseURLField: Field = {
23
+ name: 'url',
24
+ label: 'URL',
25
+ type: 'text',
26
+ admin: {
27
+ readOnly: true,
28
+ hidden: true,
29
+ },
30
+ }
31
+
32
+ const basePrefixField: Field = {
33
+ name: 'prefix',
34
+ type: 'text',
35
+ admin: {
36
+ readOnly: true,
37
+ hidden: true,
38
+ },
39
+ }
40
+
41
+ const fields = [...collection.fields]
42
+
43
+ // Inject a hook into all URL fields to generate URLs
44
+
45
+ let existingURLFieldIndex = -1
46
+
47
+ const existingURLField = fields.find((existingField, i) => {
48
+ if ('name' in existingField && existingField.name === 'url') {
49
+ existingURLFieldIndex = i
50
+ return true
51
+ }
52
+ return false
53
+ }) as TextField
54
+
55
+ if (existingURLFieldIndex > -1) {
56
+ fields.splice(existingURLFieldIndex, 1)
57
+ }
58
+
59
+ fields.push({
60
+ ...baseURLField,
61
+ ...(existingURLField || {}),
62
+ hooks: {
63
+ afterRead: [
64
+ getAfterReadHook({ adapter, collection, disablePayloadAccessControl, generateFileURL }),
65
+ ...(existingURLField?.hooks?.afterRead || []),
66
+ ],
67
+ },
68
+ })
69
+
70
+ if (typeof collection.upload === 'object' && collection.upload.imageSizes) {
71
+ let existingSizesFieldIndex = -1
72
+
73
+ const existingSizesField = fields.find((existingField, i) => {
74
+ if ('name' in existingField && existingField.name === 'sizes') {
75
+ existingSizesFieldIndex = i
76
+ return true
77
+ }
78
+
79
+ return false
80
+ }) as GroupField
81
+
82
+ if (existingSizesFieldIndex > -1) {
83
+ fields.splice(existingSizesFieldIndex, 1)
84
+ }
85
+
86
+ const sizesField: Field = {
87
+ ...(existingSizesField || {}),
88
+ name: 'sizes',
89
+ type: 'group',
90
+ admin: {
91
+ hidden: true,
92
+ },
93
+ fields: collection.upload.imageSizes.map(size => {
94
+ const existingSizeField = existingSizesField?.fields.find(
95
+ existingField => 'name' in existingField && existingField.name === size.name,
96
+ ) as GroupField
97
+
98
+ const existingSizeURLField = existingSizeField?.fields.find(
99
+ existingField => 'name' in existingField && existingField.name === 'url',
100
+ ) as GroupField
101
+
102
+ return {
103
+ ...existingSizeField,
104
+ name: size.name,
105
+ type: 'group',
106
+ fields: [
107
+ {
108
+ ...(existingSizeURLField || {}),
109
+ ...baseURLField,
110
+ hooks: {
111
+ afterRead: [
112
+ getAfterReadHook({
113
+ adapter,
114
+ collection,
115
+ size,
116
+ disablePayloadAccessControl,
117
+ generateFileURL,
118
+ }),
119
+ ...(existingSizeURLField?.hooks?.afterRead || []),
120
+ ],
121
+ },
122
+ },
123
+ ],
124
+ }
125
+ }),
126
+ }
127
+
128
+ fields.push(sizesField)
129
+ }
130
+
131
+ // If prefix is enabled, save it to db
132
+ if (prefix) {
133
+ let existingPrefixFieldIndex = -1
134
+
135
+ const existingPrefixField = fields.find((existingField, i) => {
136
+ if ('name' in existingField && existingField.name === 'prefix') {
137
+ existingPrefixFieldIndex = i
138
+ return true
139
+ }
140
+ return false
141
+ }) as TextField
142
+
143
+ if (existingPrefixFieldIndex > -1) {
144
+ fields.splice(existingPrefixFieldIndex, 1)
145
+ }
146
+
147
+ fields.push({
148
+ ...basePrefixField,
149
+ ...(existingPrefixField || {}),
150
+ defaultValue: path.posix.join(prefix),
151
+ })
152
+ }
153
+
154
+ return fields
155
+ }
@@ -1,35 +1,35 @@
1
- import type { TypeWithID } from 'payload/dist/globals/config/types'
2
- import type { FileData } from 'payload/dist/uploads/types'
3
- import type { CollectionAfterDeleteHook, CollectionConfig } from 'payload/types'
4
- import type { GeneratedAdapter, TypeWithPrefix } from '../types'
5
-
6
- interface Args {
7
- collection: CollectionConfig
8
- adapter: GeneratedAdapter
9
- }
10
-
11
- export const getAfterDeleteHook = ({
12
- collection,
13
- adapter,
14
- }: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {
15
- return async ({ req, doc }) => {
16
- try {
17
- const filesToDelete: string[] = [
18
- doc.filename,
19
- ...Object.values(doc?.sizes || []).map(resizedFileData => resizedFileData?.filename),
20
- ]
21
-
22
- const promises = filesToDelete.map(async filename => {
23
- await adapter.handleDelete({ collection, doc, req, filename })
24
- })
25
-
26
- await Promise.all(promises)
27
- } catch (err: unknown) {
28
- req.payload.logger.error(
29
- `There was an error while deleting files corresponding to the ${collection.labels?.singular} with ID ${doc.id}:`,
30
- )
31
- req.payload.logger.error(err)
32
- }
33
- return doc
34
- }
35
- }
1
+ import type { TypeWithID } from 'payload/dist/globals/config/types'
2
+ import type { FileData } from 'payload/dist/uploads/types'
3
+ import type { CollectionAfterDeleteHook, CollectionConfig } from 'payload/types'
4
+ import type { GeneratedAdapter, TypeWithPrefix } from '../types'
5
+
6
+ interface Args {
7
+ collection: CollectionConfig
8
+ adapter: GeneratedAdapter
9
+ }
10
+
11
+ export const getAfterDeleteHook = ({
12
+ collection,
13
+ adapter,
14
+ }: Args): CollectionAfterDeleteHook<FileData & TypeWithID & TypeWithPrefix> => {
15
+ return async ({ req, doc }) => {
16
+ try {
17
+ const filesToDelete: string[] = [
18
+ doc.filename,
19
+ ...Object.values(doc?.sizes || []).map(resizedFileData => resizedFileData?.filename),
20
+ ]
21
+
22
+ const promises = filesToDelete.map(async filename => {
23
+ if (filename) await adapter.handleDelete({ collection, doc, req, filename })
24
+ })
25
+
26
+ await Promise.all(promises)
27
+ } catch (err: unknown) {
28
+ req.payload.logger.error(
29
+ `There was an error while deleting files corresponding to the ${collection.labels?.singular} with ID ${doc.id}:`,
30
+ )
31
+ req.payload.logger.error(err)
32
+ }
33
+ return doc
34
+ }
35
+ }
@@ -1,38 +1,38 @@
1
- import type { ImageSize } from 'payload/dist/uploads/types'
2
- import type { CollectionConfig, FieldHook } from 'payload/types'
3
- import type { GeneratedAdapter, GenerateFileURL } from '../types'
4
-
5
- interface Args {
6
- collection: CollectionConfig
7
- adapter: GeneratedAdapter
8
- disablePayloadAccessControl?: boolean
9
- size?: ImageSize
10
- generateFileURL?: GenerateFileURL
11
- }
12
-
13
- export const getAfterReadHook =
14
- ({ collection, adapter, size, disablePayloadAccessControl, generateFileURL }: Args): FieldHook =>
15
- async ({ data, value }) => {
16
- const filename = size ? data?.sizes?.[size.name]?.filename : data?.filename
17
- const prefix = data?.prefix
18
- let url = value
19
-
20
- if (disablePayloadAccessControl && filename) {
21
- url = await adapter.generateURL({
22
- collection,
23
- filename,
24
- prefix,
25
- })
26
- }
27
-
28
- if (generateFileURL) {
29
- url = await generateFileURL({
30
- collection,
31
- filename,
32
- prefix,
33
- size,
34
- })
35
- }
36
-
37
- return url
38
- }
1
+ import type { ImageSize } from 'payload/dist/uploads/types'
2
+ import type { CollectionConfig, FieldHook } from 'payload/types'
3
+ import type { GeneratedAdapter, GenerateFileURL } from '../types'
4
+
5
+ interface Args {
6
+ collection: CollectionConfig
7
+ adapter: GeneratedAdapter
8
+ disablePayloadAccessControl?: boolean
9
+ size?: ImageSize
10
+ generateFileURL?: GenerateFileURL
11
+ }
12
+
13
+ export const getAfterReadHook =
14
+ ({ collection, adapter, size, disablePayloadAccessControl, generateFileURL }: Args): FieldHook =>
15
+ async ({ data, value }) => {
16
+ const filename = size ? data?.sizes?.[size.name]?.filename : data?.filename
17
+ const prefix = data?.prefix
18
+ let url = value
19
+
20
+ if (disablePayloadAccessControl && filename) {
21
+ url = await adapter.generateURL({
22
+ collection,
23
+ filename,
24
+ prefix,
25
+ })
26
+ }
27
+
28
+ if (generateFileURL) {
29
+ url = await generateFileURL({
30
+ collection,
31
+ filename,
32
+ prefix,
33
+ size,
34
+ })
35
+ }
36
+
37
+ return url
38
+ }