@payloadcms/plugin-cloud-storage 1.0.16 → 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.
- package/.editorconfig +10 -0
- package/.gitignore +248 -0
- package/.prettierignore +1 -0
- package/.prettierrc.js +8 -0
- package/.vscode/launch.json +40 -0
- package/.vscode/settings.json +9 -0
- package/README.md +20 -2
- package/dev/.env +21 -0
- package/dev/.env.example +21 -0
- package/dev/nodemon.json +8 -0
- package/dev/package.json +34 -0
- package/dev/src/collections/Media.ts +56 -0
- package/dev/src/collections/Users.ts +23 -0
- package/dev/src/mocks/fsMock.js +1 -0
- package/dev/src/mocks/promisifyMock.js +1 -0
- package/dev/src/payload.config.ts +111 -0
- package/dev/src/server.ts +26 -0
- package/dev/tsconfig.json +20 -0
- package/dist/plugin.d.ts +1 -1
- package/dist/plugin.js +10 -4
- package/dist/plugin.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/docs/local-dev.md +47 -0
- package/eslint-config/index.js +15 -0
- package/eslint-config/rules/import.js +38 -0
- package/eslint-config/rules/prettier.js +7 -0
- package/eslint-config/rules/style.js +21 -0
- package/eslint-config/rules/typescript.js +628 -0
- package/package.json +1 -1
- package/src/adapters/azure/emulator/docker-compose.yml +16 -0
- package/src/adapters/azure/fileStub.js +1 -0
- package/src/adapters/azure/generateURL.ts +13 -0
- package/src/adapters/azure/handleDelete.ts +16 -0
- package/src/adapters/azure/handleUpload.ts +41 -0
- package/src/adapters/azure/index.ts +48 -0
- package/src/adapters/azure/mock.js +13 -0
- package/src/adapters/azure/staticHandler.ts +38 -0
- package/src/adapters/azure/webpack.ts +24 -0
- package/src/adapters/gcs/emulator/docker-compose.yml +15 -0
- package/src/adapters/gcs/generateURL.ts +16 -0
- package/src/adapters/gcs/handleDelete.ts +16 -0
- package/src/adapters/gcs/handleUpload.ts +34 -0
- package/src/adapters/gcs/index.ts +37 -0
- package/src/adapters/gcs/mock.js +3 -0
- package/src/adapters/gcs/staticHandler.ts +34 -0
- package/src/adapters/gcs/webpack.ts +21 -0
- package/src/adapters/s3/emulator/.localstack/cache/machine.json +1 -0
- package/src/adapters/s3/emulator/.localstack/cache/server.test.pem +127 -0
- package/src/adapters/s3/emulator/.localstack/cache/server.test.pem.crt +99 -0
- package/src/adapters/s3/emulator/.localstack/cache/server.test.pem.key +28 -0
- package/src/adapters/s3/emulator/.localstack/cache/service-catalog-2_1_1_dev-1_29_149.pickle +0 -0
- package/src/adapters/s3/emulator/docker-compose.yml +15 -0
- package/src/adapters/s3/fileStub.js +1 -0
- package/src/adapters/s3/generateURL.ts +14 -0
- package/src/adapters/s3/handleDelete.ts +17 -0
- package/src/adapters/s3/handleUpload.ts +62 -0
- package/src/adapters/s3/index.ts +38 -0
- package/src/adapters/s3/mock.js +9 -0
- package/src/adapters/s3/staticHandler.ts +41 -0
- package/src/adapters/s3/webpack.ts +23 -0
- package/src/fields/getFields.ts +155 -0
- package/src/hooks/afterDelete.ts +35 -0
- package/src/hooks/afterRead.ts +38 -0
- package/src/hooks/beforeChange.ts +59 -0
- package/src/index.ts +1 -0
- package/src/plugin.ts +101 -0
- package/src/types.ts +79 -0
- package/src/utilities/getFilePrefix.ts +26 -0
- package/src/utilities/getIncomingFiles.ts +44 -0
- package/src/utilities/getRangeFromHeader.ts +27 -0
- package/src/webpack.ts +46 -0
- package/tsconfig.json +23 -0
- package/yarn-error.log +8163 -0
- package/yarn.lock +8062 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { NextFunction, Response } from 'express'
|
|
2
|
+
import type { TypeWithID } from 'payload/dist/collections/config/types'
|
|
3
|
+
import type { FileData, ImageSize } from 'payload/dist/uploads/types'
|
|
4
|
+
import type { CollectionConfig, PayloadRequest } from 'payload/types'
|
|
5
|
+
import type { Configuration as WebpackConfig } from 'webpack'
|
|
6
|
+
|
|
7
|
+
export interface File {
|
|
8
|
+
buffer: Buffer
|
|
9
|
+
filename: string
|
|
10
|
+
filesize: number
|
|
11
|
+
mimeType: string
|
|
12
|
+
tempFilePath?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type HandleUpload = (args: {
|
|
16
|
+
collection: CollectionConfig
|
|
17
|
+
req: PayloadRequest
|
|
18
|
+
data: any
|
|
19
|
+
file: File
|
|
20
|
+
}) => Promise<void> | void
|
|
21
|
+
|
|
22
|
+
export interface TypeWithPrefix {
|
|
23
|
+
prefix?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type HandleDelete = (args: {
|
|
27
|
+
collection: CollectionConfig
|
|
28
|
+
req: PayloadRequest
|
|
29
|
+
doc: TypeWithID & FileData & TypeWithPrefix
|
|
30
|
+
filename: string
|
|
31
|
+
}) => Promise<void> | void
|
|
32
|
+
|
|
33
|
+
export type GenerateURL = (args: {
|
|
34
|
+
filename: string
|
|
35
|
+
collection: CollectionConfig
|
|
36
|
+
prefix?: string
|
|
37
|
+
}) => string | Promise<string>
|
|
38
|
+
|
|
39
|
+
export type StaticHandler = (
|
|
40
|
+
req: PayloadRequest,
|
|
41
|
+
res: Response,
|
|
42
|
+
next: NextFunction,
|
|
43
|
+
) => Promise<unknown> | unknown
|
|
44
|
+
|
|
45
|
+
export interface GeneratedAdapter {
|
|
46
|
+
handleUpload: HandleUpload
|
|
47
|
+
handleDelete: HandleDelete
|
|
48
|
+
generateURL: GenerateURL
|
|
49
|
+
staticHandler: StaticHandler
|
|
50
|
+
webpack?: (config: WebpackConfig) => WebpackConfig
|
|
51
|
+
onInit?: () => void
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type Adapter = (args: { collection: CollectionConfig; prefix?: string }) => GeneratedAdapter
|
|
55
|
+
|
|
56
|
+
export type GenerateFileURL = (args: {
|
|
57
|
+
collection: CollectionConfig
|
|
58
|
+
filename: string
|
|
59
|
+
prefix?: string
|
|
60
|
+
size?: ImageSize
|
|
61
|
+
}) => Promise<string> | string
|
|
62
|
+
|
|
63
|
+
export interface CollectionOptions {
|
|
64
|
+
disableLocalStorage?: boolean
|
|
65
|
+
disablePayloadAccessControl?: true
|
|
66
|
+
generateFileURL?: GenerateFileURL
|
|
67
|
+
prefix?: string
|
|
68
|
+
adapter: Adapter | null
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface PluginOptions {
|
|
72
|
+
/**
|
|
73
|
+
* Whether or not to enable the plugin
|
|
74
|
+
*
|
|
75
|
+
* Default: true
|
|
76
|
+
*/
|
|
77
|
+
enabled?: boolean
|
|
78
|
+
collections: Record<string, CollectionOptions>
|
|
79
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CollectionConfig, PayloadRequest } from 'payload/types'
|
|
2
|
+
import { IncomingUploadType } from 'payload/dist/uploads/types'
|
|
3
|
+
|
|
4
|
+
export async function getFilePrefix({
|
|
5
|
+
req,
|
|
6
|
+
collection,
|
|
7
|
+
}: {
|
|
8
|
+
req: PayloadRequest
|
|
9
|
+
collection: CollectionConfig
|
|
10
|
+
}): Promise<string> {
|
|
11
|
+
const imageSizes = (collection?.upload as IncomingUploadType)?.imageSizes || []
|
|
12
|
+
const files = await req.payload.find({
|
|
13
|
+
collection: collection.slug,
|
|
14
|
+
where: {
|
|
15
|
+
or: [
|
|
16
|
+
{
|
|
17
|
+
filename: { equals: req.params.filename },
|
|
18
|
+
},
|
|
19
|
+
...imageSizes.map(imageSize => ({
|
|
20
|
+
[`sizes.${imageSize.name}.filename`]: { equals: req.params.filename },
|
|
21
|
+
})),
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
return files?.docs?.[0]?.prefix || ''
|
|
26
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { FileData } from 'payload/dist/uploads/types'
|
|
2
|
+
import type { PayloadRequest } from 'payload/types'
|
|
3
|
+
import type { File } from '../types'
|
|
4
|
+
|
|
5
|
+
export function getIncomingFiles({
|
|
6
|
+
req,
|
|
7
|
+
data,
|
|
8
|
+
}: {
|
|
9
|
+
data: Partial<FileData>
|
|
10
|
+
req: PayloadRequest
|
|
11
|
+
}): File[] {
|
|
12
|
+
const file = req.files?.file
|
|
13
|
+
|
|
14
|
+
let files: File[] = []
|
|
15
|
+
|
|
16
|
+
if (file && data.filename && data.mimeType) {
|
|
17
|
+
const mainFile: File = {
|
|
18
|
+
filename: data.filename,
|
|
19
|
+
mimeType: data.mimeType,
|
|
20
|
+
buffer: file.data,
|
|
21
|
+
tempFilePath: file.tempFilePath,
|
|
22
|
+
filesize: file.size,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
files = [mainFile]
|
|
26
|
+
|
|
27
|
+
if (data?.sizes) {
|
|
28
|
+
Object.entries(data.sizes).forEach(([key, resizedFileData]) => {
|
|
29
|
+
if (req.payloadUploadSizes?.[key] && data.mimeType) {
|
|
30
|
+
files = files.concat([
|
|
31
|
+
{
|
|
32
|
+
filename: `${resizedFileData.filename}`,
|
|
33
|
+
mimeType: data.mimeType,
|
|
34
|
+
buffer: req.payloadUploadSizes[key],
|
|
35
|
+
filesize: req.payloadUploadSizes[key].length,
|
|
36
|
+
},
|
|
37
|
+
])
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return files
|
|
44
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { BlockBlobClient } from '@azure/storage-blob'
|
|
2
|
+
import parseRange from 'range-parser'
|
|
3
|
+
|
|
4
|
+
const getRangeFromHeader = async (
|
|
5
|
+
blockBlobClient: BlockBlobClient,
|
|
6
|
+
rangeHeader?: string,
|
|
7
|
+
): Promise<{ start: number; end: number | undefined }> => {
|
|
8
|
+
const fullRange = { start: 0, end: undefined }
|
|
9
|
+
|
|
10
|
+
if (!rangeHeader) {
|
|
11
|
+
return fullRange
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const size = await blockBlobClient.getProperties().then(props => props.contentLength)
|
|
15
|
+
if (size === undefined) {
|
|
16
|
+
return fullRange
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const range = parseRange(size, rangeHeader)
|
|
20
|
+
if (range === -1 || range === -2 || range.type !== 'bytes' || range.length !== 1) {
|
|
21
|
+
return fullRange
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return range[0]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default getRangeFromHeader
|
package/src/webpack.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Config } from 'payload/config'
|
|
2
|
+
import type { Configuration as WebpackConfig } from 'webpack'
|
|
3
|
+
import type { GeneratedAdapter, PluginOptions } from './types'
|
|
4
|
+
|
|
5
|
+
interface Args {
|
|
6
|
+
config: Config
|
|
7
|
+
options: PluginOptions
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const extendWebpackConfig =
|
|
11
|
+
({ config, options }: Args): ((webpackConfig: WebpackConfig) => WebpackConfig) =>
|
|
12
|
+
webpackConfig => {
|
|
13
|
+
const existingWebpackConfig =
|
|
14
|
+
typeof config.admin?.webpack === 'function'
|
|
15
|
+
? config.admin.webpack(webpackConfig)
|
|
16
|
+
: webpackConfig
|
|
17
|
+
|
|
18
|
+
const newConfig: WebpackConfig = {
|
|
19
|
+
...existingWebpackConfig,
|
|
20
|
+
resolve: {
|
|
21
|
+
...(existingWebpackConfig.resolve || {}),
|
|
22
|
+
alias: {
|
|
23
|
+
...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return Object.entries(options.collections).reduce(
|
|
29
|
+
(resultingWebpackConfig, [slug, collectionOptions]) => {
|
|
30
|
+
const matchedCollection = config.collections?.find(coll => coll.slug === slug)
|
|
31
|
+
|
|
32
|
+
if (matchedCollection && typeof collectionOptions.adapter === 'function') {
|
|
33
|
+
const adapter: GeneratedAdapter = collectionOptions.adapter({
|
|
34
|
+
collection: matchedCollection,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
if (adapter.webpack) {
|
|
38
|
+
return adapter.webpack(resultingWebpackConfig)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return resultingWebpackConfig
|
|
43
|
+
},
|
|
44
|
+
newConfig,
|
|
45
|
+
)
|
|
46
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"lib": [
|
|
4
|
+
"dom",
|
|
5
|
+
"dom.iterable",
|
|
6
|
+
"esnext"
|
|
7
|
+
],
|
|
8
|
+
"target": "es5",
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"allowJs": true,
|
|
11
|
+
"module": "commonjs",
|
|
12
|
+
"sourceMap": true,
|
|
13
|
+
"jsx": "react",
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"declaration": true,
|
|
16
|
+
"declarationDir": "./dist",
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"strict": true,
|
|
19
|
+
},
|
|
20
|
+
"include": [
|
|
21
|
+
"src/**/*"
|
|
22
|
+
],
|
|
23
|
+
}
|