From caa8d9c0ed0fb743739fd603d4e8a0af559f89c2 Mon Sep 17 00:00:00 2001 From: Alessio Gravili Date: Mon, 4 Mar 2024 14:08:43 -0500 Subject: [PATCH] feat: working @payloadcms/plugin-cloud-storage --- packages/next/src/next-stream-file/index.ts | 4 +- .../[collection]/file/[filename]/route.ts | 14 +- .../payload/src/config/createClientConfig.ts | 6 + packages/payload/src/uploads/types.ts | 6 +- packages/plugin-cloud-storage/.eslintrc.js | 1 - packages/plugin-cloud-storage/package.json | 18 +- .../src/adapters/azure/index.ts | 2 - .../src/adapters/azure/mock.js | 1 - .../src/adapters/azure/staticHandler.ts | 34 +- .../src/adapters/azure/webpack.ts | 22 - .../src/adapters/gcs/index.ts | 2 - .../src/adapters/gcs/mock.js | 1 - .../src/adapters/gcs/staticHandler.ts | 38 +- .../src/adapters/gcs/webpack.ts | 22 - .../src/adapters/s3/index.ts | 2 - .../src/adapters/s3/mock.js | 1 - .../src/adapters/s3/staticHandler.ts | 43 +- .../src/adapters/s3/webpack.ts | 44 -- packages/plugin-cloud-storage/src/plugin.ts | 8 - packages/plugin-cloud-storage/src/types.ts | 8 +- packages/plugin-cloud-storage/src/webpack.ts | 52 -- pnpm-lock.yaml | 485 ++++++++++++++++-- test/plugin-cloud-storage/.env.emulated | 4 +- .../plugin-cloud-storage/collections/Media.ts | 2 +- test/plugin-cloud-storage/config.ts | 53 +- tsconfig.json | 79 ++- 26 files changed, 631 insertions(+), 321 deletions(-) delete mode 100644 packages/plugin-cloud-storage/src/adapters/azure/mock.js delete mode 100644 packages/plugin-cloud-storage/src/adapters/azure/webpack.ts delete mode 100644 packages/plugin-cloud-storage/src/adapters/gcs/mock.js delete mode 100644 packages/plugin-cloud-storage/src/adapters/gcs/webpack.ts delete mode 100644 packages/plugin-cloud-storage/src/adapters/s3/mock.js delete mode 100644 packages/plugin-cloud-storage/src/adapters/s3/webpack.ts delete mode 100644 packages/plugin-cloud-storage/src/webpack.ts diff --git a/packages/next/src/next-stream-file/index.ts b/packages/next/src/next-stream-file/index.ts index fa2696cecc..3f1d8729f4 100644 --- a/packages/next/src/next-stream-file/index.ts +++ b/packages/next/src/next-stream-file/index.ts @@ -1,6 +1,6 @@ import fs from 'fs' -function iteratorToStream(iterator) { +export function iteratorToStream(iterator) { return new ReadableStream({ async pull(controller) { const { done, value } = await iterator.next() @@ -13,7 +13,7 @@ function iteratorToStream(iterator) { }) } -async function* nodeStreamToIterator(stream: fs.ReadStream) { +export async function* nodeStreamToIterator(stream: fs.ReadStream) { for await (const chunk of stream) { yield new Uint8Array(chunk) } diff --git a/packages/next/src/routes/rest/[collection]/file/[filename]/route.ts b/packages/next/src/routes/rest/[collection]/file/[filename]/route.ts index c23fd669cc..3348c37152 100644 --- a/packages/next/src/routes/rest/[collection]/file/[filename]/route.ts +++ b/packages/next/src/routes/rest/[collection]/file/[filename]/route.ts @@ -77,6 +77,7 @@ export const GET = params: { collection: collectionSlug }, request, }) + collection = req.payload.collections?.[collectionSlug] if (!collection) { @@ -90,7 +91,7 @@ export const GET = ) } - if (collection.config.upload.disableLocalStorage) { + if (collection.config.upload.disableLocalStorage && !collection.config.upload.handlers) { throw new APIError( `This collection has local storage disabled: ${collectionSlug}`, httpStatus.BAD_REQUEST, @@ -103,10 +104,21 @@ export const GET = req, }) + let response: Response = null + if (collection.config.upload.handlers?.length) { + for (const handler of collection.config.upload.handlers) { + response = await handler(req, { params }) + } + + return response + } + const fileDir = collection.config.upload?.staticDir || collection.config.slug const filePath = path.resolve(`${fileDir}/${filename}`) + const stats = await fsPromises.stat(filePath) const data = streamFile(filePath) + return new Response(data, { headers: new Headers({ 'content-length': stats.size + '', diff --git a/packages/payload/src/config/createClientConfig.ts b/packages/payload/src/config/createClientConfig.ts index 0e8222053e..c3283aff2b 100644 --- a/packages/payload/src/config/createClientConfig.ts +++ b/packages/payload/src/config/createClientConfig.ts @@ -62,6 +62,11 @@ const sanitizeCollections = ( if ('editor' in sanitized) delete sanitized.editor + if ('upload' in sanitized && typeof sanitized.upload === 'object') { + sanitized.upload = { ...sanitized.upload } + delete sanitized.upload.handlers + } + if ('admin' in sanitized) { sanitized.admin = { ...sanitized.admin } @@ -119,6 +124,7 @@ export const createClientConfig = async ( delete clientConfig.endpoints delete clientConfig.db delete clientConfig.editor + delete clientConfig.plugins 'localization' in clientConfig && clientConfig.localization && diff --git a/packages/payload/src/uploads/types.ts b/packages/payload/src/uploads/types.ts index 3f07d0e1b5..29e53c0752 100644 --- a/packages/payload/src/uploads/types.ts +++ b/packages/payload/src/uploads/types.ts @@ -1,4 +1,5 @@ import type express from 'express' +import type { PayloadRequest } from 'payload/types' import type serveStatic from 'serve-static' import type { ResizeOptions, Sharp } from 'sharp' @@ -82,7 +83,10 @@ export type UploadConfig = { focalPoint?: boolean /** Options for original upload file only. For sizes, set each formatOptions individually. */ formatOptions?: ImageUploadFormatOptions - handlers?: any[] + handlers?: (( + req: PayloadRequest, + args2: { params: { collection: string; filename: string } }, + ) => Promise | Response)[] imageSizes?: ImageSize[] mimeTypes?: string[] resizeOptions?: ResizeOptions diff --git a/packages/plugin-cloud-storage/.eslintrc.js b/packages/plugin-cloud-storage/.eslintrc.js index c1b1716e71..3097f2cd3b 100644 --- a/packages/plugin-cloud-storage/.eslintrc.js +++ b/packages/plugin-cloud-storage/.eslintrc.js @@ -1,4 +1,3 @@ -/** @type {import('prettier').Config} */ module.exports = { extends: ['@payloadcms'], overrides: [ diff --git a/packages/plugin-cloud-storage/package.json b/packages/plugin-cloud-storage/package.json index 7fb9fa4c72..f0858ebd3d 100644 --- a/packages/plugin-cloud-storage/package.json +++ b/packages/plugin-cloud-storage/package.json @@ -14,12 +14,12 @@ "test": "echo \"No tests available.\"" }, "peerDependencies": { - "@aws-sdk/client-s3": "^3.142.0", - "@aws-sdk/lib-storage": "^3.267.0", + "@aws-sdk/client-s3": "^3.525.0", + "@aws-sdk/lib-storage": "^3.525.0", "@azure/abort-controller": "^1.0.0", "@azure/storage-blob": "^12.11.0", "@google-cloud/storage": "^7.7.0", - "payload": "^1.7.2 || ^2.0.0" + "payload": "workspace:*" }, "peerDependenciesMeta": { "@aws-sdk/client-s3": { @@ -44,18 +44,12 @@ "*.d.ts" ], "devDependencies": { - "@aws-sdk/client-s3": "^3.142.0", - "@aws-sdk/lib-storage": "^3.267.0", + "@aws-sdk/client-s3": "^3.525.0", + "@aws-sdk/lib-storage": "^3.525.0", "@azure/storage-blob": "^12.11.0", "@google-cloud/storage": "^7.7.0", - "@types/express": "^4.17.9", "@types/find-node-modules": "^2.1.2", - "cross-env": "^7.0.3", - "dotenv": "^8.2.0", - "nodemon": "3.0.3", - "payload": "workspace:*", - "rimraf": "^4.1.2", - "webpack": "^5.78.0" + "payload": "workspace:*" }, "dependencies": { "find-node-modules": "^2.1.3", diff --git a/packages/plugin-cloud-storage/src/adapters/azure/index.ts b/packages/plugin-cloud-storage/src/adapters/azure/index.ts index 9e77f2236b..ebed8c65e0 100644 --- a/packages/plugin-cloud-storage/src/adapters/azure/index.ts +++ b/packages/plugin-cloud-storage/src/adapters/azure/index.ts @@ -8,7 +8,6 @@ import { getGenerateURL } from './generateURL' import { getHandleDelete } from './handleDelete' import { getHandleUpload } from './handleUpload' import { getHandler } from './staticHandler' -import { extendWebpackConfig } from './webpack' export interface Args { allowContainerCreate: boolean @@ -44,7 +43,6 @@ export const azureBlobStorageAdapter = ({ prefix, }), staticHandler: getHandler({ collection, getStorageClient }), - webpack: extendWebpackConfig, ...(allowContainerCreate && { onInit: createContainerIfNotExists }), } } diff --git a/packages/plugin-cloud-storage/src/adapters/azure/mock.js b/packages/plugin-cloud-storage/src/adapters/azure/mock.js deleted file mode 100644 index e9b08f0e74..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/azure/mock.js +++ /dev/null @@ -1 +0,0 @@ -export const azureBlobStorageAdapter = () => {} diff --git a/packages/plugin-cloud-storage/src/adapters/azure/staticHandler.ts b/packages/plugin-cloud-storage/src/adapters/azure/staticHandler.ts index f1ef1c3f79..24d4a3721b 100644 --- a/packages/plugin-cloud-storage/src/adapters/azure/staticHandler.ts +++ b/packages/plugin-cloud-storage/src/adapters/azure/staticHandler.ts @@ -14,13 +14,11 @@ interface Args { } export const getHandler = ({ collection, getStorageClient }: Args): StaticHandler => { - return async (req, res, next) => { + return async (req, { params }) => { try { const prefix = await getFilePrefix({ collection, req }) const blockBlobClient = getStorageClient().getBlockBlobClient( - // WARNING: - // TODO: Untested for 3.0 - path.posix.join(prefix, req.routeParams.filename as string), + path.posix.join(prefix, params.filename), ) const { end, start } = await getRangeFromHeader(blockBlobClient, req.headers.get('range')) @@ -28,16 +26,30 @@ export const getHandler = ({ collection, getStorageClient }: Args): StaticHandle const blob = await blockBlobClient.download(start, end) // eslint-disable-next-line no-underscore-dangle const response = blob._response - res.header(response.headers.rawHeaders()) - res.status(response.status) - if (blob?.readableStreamBody) { - return blob.readableStreamBody.pipe(res) - } + // Manually create a ReadableStream for the web from a Node.js stream. + const readableStream = new ReadableStream({ + start(controller) { + const nodeStream = blob.readableStreamBody + nodeStream.on('data', (chunk) => { + controller.enqueue(new Uint8Array(chunk)) + }) + nodeStream.on('end', () => { + controller.close() + }) + nodeStream.on('error', (err) => { + controller.error(err) + }) + }, + }) - return next() + return new Response(readableStream, { + headers: response.headers.rawHeaders(), + status: response.status, + }) } catch (err: unknown) { - return next() + req.payload.logger.error(err) + return new Response('Internal Server Error', { status: 500 }) } } } diff --git a/packages/plugin-cloud-storage/src/adapters/azure/webpack.ts b/packages/plugin-cloud-storage/src/adapters/azure/webpack.ts deleted file mode 100644 index 2d551b6a3a..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/azure/webpack.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack' - -import path from 'path' - -export const extendWebpackConfig = (existingWebpackConfig: WebpackConfig): WebpackConfig => { - const newConfig: WebpackConfig = { - ...existingWebpackConfig, - resolve: { - ...(existingWebpackConfig.resolve || {}), - alias: { - ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}), - '@payloadcms/plugin-cloud-storage/azure': path.resolve(__dirname, './mock.js'), - }, - fallback: { - ...(existingWebpackConfig.resolve?.fallback ? existingWebpackConfig.resolve.fallback : {}), - stream: false, - }, - }, - } - - return newConfig -} diff --git a/packages/plugin-cloud-storage/src/adapters/gcs/index.ts b/packages/plugin-cloud-storage/src/adapters/gcs/index.ts index ebb00d0d40..49a5c9edaf 100644 --- a/packages/plugin-cloud-storage/src/adapters/gcs/index.ts +++ b/packages/plugin-cloud-storage/src/adapters/gcs/index.ts @@ -8,7 +8,6 @@ import { getGenerateURL } from './generateURL' import { getHandleDelete } from './handleDelete' import { getHandleUpload } from './handleUpload' import { getHandler } from './staticHandler' -import { extendWebpackConfig } from './webpack' export interface Args { acl?: 'Private' | 'Public' @@ -38,6 +37,5 @@ export const gcsAdapter = prefix, }), staticHandler: getHandler({ bucket, collection, getStorageClient }), - webpack: extendWebpackConfig, } } diff --git a/packages/plugin-cloud-storage/src/adapters/gcs/mock.js b/packages/plugin-cloud-storage/src/adapters/gcs/mock.js deleted file mode 100644 index 16fad7a840..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/gcs/mock.js +++ /dev/null @@ -1 +0,0 @@ -export const gcsAdapter = () => {} diff --git a/packages/plugin-cloud-storage/src/adapters/gcs/staticHandler.ts b/packages/plugin-cloud-storage/src/adapters/gcs/staticHandler.ts index 4335c989cd..082457966a 100644 --- a/packages/plugin-cloud-storage/src/adapters/gcs/staticHandler.ts +++ b/packages/plugin-cloud-storage/src/adapters/gcs/staticHandler.ts @@ -14,26 +14,40 @@ interface Args { } export const getHandler = ({ bucket, collection, getStorageClient }: Args): StaticHandler => { - return async (req, res, next) => { + return async (req, { params }) => { try { const prefix = await getFilePrefix({ collection, req }) - const file = getStorageClient() - .bucket(bucket) - // WARNING: - // TODO: Untested for 3.0 - .file(path.posix.join(prefix, req.routeParams.filename as string)) + const file = getStorageClient().bucket(bucket).file(path.posix.join(prefix, params.filename)) const [metadata] = await file.getMetadata() - res.set({ - 'Content-Length': metadata.size, - 'Content-Type': metadata.contentType, - ETag: metadata.etag, + // Manually create a ReadableStream for the web from a Node.js stream. + const readableStream = new ReadableStream({ + start(controller) { + const nodeStream = file.createReadStream() + nodeStream.on('data', (chunk) => { + controller.enqueue(new Uint8Array(chunk)) + }) + nodeStream.on('end', () => { + controller.close() + }) + nodeStream.on('error', (err) => { + controller.error(err) + }) + }, }) - return file.createReadStream().pipe(res) + return new Response(readableStream, { + headers: new Headers({ + 'Content-Length': String(metadata.size), + 'Content-Type': metadata.contentType, + ETag: metadata.etag, + }), + status: 200, + }) } catch (err: unknown) { - return next() + req.payload.logger.error(err) + return new Response('Internal Server Error', { status: 500 }) } } } diff --git a/packages/plugin-cloud-storage/src/adapters/gcs/webpack.ts b/packages/plugin-cloud-storage/src/adapters/gcs/webpack.ts deleted file mode 100644 index a2ba9ec0d3..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/gcs/webpack.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack' - -import path from 'path' - -export const extendWebpackConfig = (existingWebpackConfig: WebpackConfig): WebpackConfig => { - const newConfig: WebpackConfig = { - ...existingWebpackConfig, - resolve: { - ...(existingWebpackConfig.resolve || {}), - alias: { - ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}), - '@google-cloud/storage': path.resolve(__dirname, './mock.js'), - }, - fallback: { - ...(existingWebpackConfig.resolve?.fallback ? existingWebpackConfig.resolve.fallback : {}), - stream: false, - }, - }, - } - - return newConfig -} diff --git a/packages/plugin-cloud-storage/src/adapters/s3/index.ts b/packages/plugin-cloud-storage/src/adapters/s3/index.ts index 0f29744e42..9c627ae5fd 100644 --- a/packages/plugin-cloud-storage/src/adapters/s3/index.ts +++ b/packages/plugin-cloud-storage/src/adapters/s3/index.ts @@ -6,7 +6,6 @@ import { getGenerateURL } from './generateURL' import { getHandleDelete } from './handleDelete' import { getHandleUpload } from './handleUpload' import { getHandler } from './staticHandler' -import { extendWebpackConfig } from './webpack' export interface Args { acl?: 'private' | 'public-read' @@ -45,6 +44,5 @@ export const s3Adapter = prefix, }), staticHandler: getHandler({ bucket, collection, getStorageClient }), - webpack: extendWebpackConfig, } } diff --git a/packages/plugin-cloud-storage/src/adapters/s3/mock.js b/packages/plugin-cloud-storage/src/adapters/s3/mock.js deleted file mode 100644 index 680d6772d9..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/s3/mock.js +++ /dev/null @@ -1 +0,0 @@ -export const s3Adapter = () => {} diff --git a/packages/plugin-cloud-storage/src/adapters/s3/staticHandler.ts b/packages/plugin-cloud-storage/src/adapters/s3/staticHandler.ts index edbd657a73..a2df930532 100644 --- a/packages/plugin-cloud-storage/src/adapters/s3/staticHandler.ts +++ b/packages/plugin-cloud-storage/src/adapters/s3/staticHandler.ts @@ -1,6 +1,5 @@ import type * as AWS from '@aws-sdk/client-s3' import type { CollectionConfig } from 'payload/types' -import type { Readable } from 'stream' import path from 'path' @@ -14,33 +13,43 @@ interface Args { getStorageClient: () => AWS.S3 } +// Convert a stream into a promise that resolves with a Buffer +const streamToBuffer = async (readableStream) => { + const chunks = [] + for await (const chunk of readableStream) { + chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk) + } + return Buffer.concat(chunks) +} + export const getHandler = ({ bucket, collection, getStorageClient }: Args): StaticHandler => { - return async (req, res, next) => { + return async (req, { params }) => { try { const prefix = await getFilePrefix({ collection, req }) const object = await getStorageClient().getObject({ Bucket: bucket, - // WARNING: - // TODO: Untested for 3.0 - Key: path.posix.join(prefix, req.routeParams.filename as string), + Key: path.posix.join(prefix, params.filename), }) - res.set({ - 'Accept-Ranges': object.AcceptRanges, - 'Content-Length': object.ContentLength, - 'Content-Type': object.ContentType, - ETag: object.ETag, - }) - - if (object?.Body) { - return (object.Body as Readable).pipe(res) + if (!object.Body) { + return new Response(null, { status: 404, statusText: 'Not Found' }) } - return next() - } catch (err: unknown) { + const bodyBuffer = await streamToBuffer(object.Body) + + return new Response(bodyBuffer, { + headers: new Headers({ + 'Accept-Ranges': object.AcceptRanges, + 'Content-Length': String(object.ContentLength), + 'Content-Type': object.ContentType, + ETag: object.ETag, + }), + status: 200, + }) + } catch (err) { req.payload.logger.error(err) - return next() + return new Response('Internal Server Error', { status: 500 }) } } } diff --git a/packages/plugin-cloud-storage/src/adapters/s3/webpack.ts b/packages/plugin-cloud-storage/src/adapters/s3/webpack.ts deleted file mode 100644 index 3b0ca11301..0000000000 --- a/packages/plugin-cloud-storage/src/adapters/s3/webpack.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { Configuration as WebpackConfig } from 'webpack' - -import findNodeModules from 'find-node-modules' -import fs from 'fs' -import path from 'path' - -const packageName = '@payloadcms/plugin-cloud-storage' - -const nodeModulesPaths = findNodeModules({ cwd: __dirname, relative: false }) - -export const extendWebpackConfig = (existingWebpackConfig: WebpackConfig): WebpackConfig => { - let nodeModulesPath = nodeModulesPaths.find((p) => { - const guess = path.resolve(p, `${packageName}/dist`) - - if (fs.existsSync(guess)) { - return true - } - return false - }) - - if (!nodeModulesPath) { - nodeModulesPath = process.cwd() - } - - const newConfig: WebpackConfig = { - ...existingWebpackConfig, - resolve: { - ...(existingWebpackConfig.resolve || {}), - alias: { - ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}), - '@payloadcms/plugin-cloud-storage/s3$': path.resolve( - nodeModulesPath, - `./${packageName}/dist/adapters/s3/mock.js`, - ), - }, - fallback: { - ...(existingWebpackConfig.resolve?.fallback ? existingWebpackConfig.resolve.fallback : {}), - stream: false, - }, - }, - } - - return newConfig -} diff --git a/packages/plugin-cloud-storage/src/plugin.ts b/packages/plugin-cloud-storage/src/plugin.ts index dc710247ee..de2b6575d9 100644 --- a/packages/plugin-cloud-storage/src/plugin.ts +++ b/packages/plugin-cloud-storage/src/plugin.ts @@ -5,7 +5,6 @@ import type { PluginOptions } from './types' import { getFields } from './fields/getFields' import { getAfterDeleteHook } from './hooks/afterDelete' import { getBeforeChangeHook } from './hooks/beforeChange' -import { extendWebpackConfig } from './webpack' // This plugin extends all targeted collections by offloading uploaded files // to cloud storage instead of solely storing files locally. @@ -22,13 +21,6 @@ export const cloudStorage = const { collections: allCollectionOptions, enabled } = pluginOptions const config = { ...incomingConfig } - const webpack = extendWebpackConfig({ config: incomingConfig, options: pluginOptions }) - - config.admin = { - ...(config.admin || {}), - webpack, - } - // Return early if disabled. Only webpack config mods are applied. if (enabled === false) { return config diff --git a/packages/plugin-cloud-storage/src/types.ts b/packages/plugin-cloud-storage/src/types.ts index 4d902ff44f..4871cb51e7 100644 --- a/packages/plugin-cloud-storage/src/types.ts +++ b/packages/plugin-cloud-storage/src/types.ts @@ -1,8 +1,6 @@ -import type { NextFunction, Response } from 'express' import type { FileData, ImageSize } from 'payload/types' import type { TypeWithID } from 'payload/types' import type { CollectionConfig, PayloadRequest } from 'payload/types' -import type { Configuration as WebpackConfig } from 'webpack' export interface File { buffer: Buffer @@ -38,9 +36,8 @@ export type GenerateURL = (args: { export type StaticHandler = ( req: PayloadRequest, - res: Response, - next: NextFunction, -) => Promise | unknown + args2: { params: { collection: string; filename: string } }, +) => Promise | Response export interface GeneratedAdapter { generateURL: GenerateURL @@ -48,7 +45,6 @@ export interface GeneratedAdapter { handleUpload: HandleUpload onInit?: () => void staticHandler: StaticHandler - webpack?: (config: WebpackConfig) => WebpackConfig } export type Adapter = (args: { collection: CollectionConfig; prefix?: string }) => GeneratedAdapter diff --git a/packages/plugin-cloud-storage/src/webpack.ts b/packages/plugin-cloud-storage/src/webpack.ts deleted file mode 100644 index 4fa997aede..0000000000 --- a/packages/plugin-cloud-storage/src/webpack.ts +++ /dev/null @@ -1,52 +0,0 @@ -import type { Config } from 'payload/config' -import type { Configuration as WebpackConfig } from 'webpack' - -import path from 'path' - -import type { GeneratedAdapter, PluginOptions } from './types' - -interface Args { - config: Config - options: PluginOptions -} - -export const extendWebpackConfig = - ({ config, options }: Args): ((webpackConfig: WebpackConfig) => WebpackConfig) => - (webpackConfig) => { - const existingWebpackConfig = - typeof config.admin?.webpack === 'function' - ? config.admin.webpack(webpackConfig) - : webpackConfig - - const newConfig: WebpackConfig = { - ...existingWebpackConfig, - resolve: { - ...(existingWebpackConfig.resolve || {}), - alias: { - ...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}), - '@payloadcms/plugin-cloud-storage$': path.resolve(__dirname, './admin/index.js'), - }, - }, - } - - const modifiedConfig = Object.entries(options.collections).reduce( - (resultingWebpackConfig, [slug, collectionOptions]) => { - const matchedCollection = config.collections?.find((coll) => coll.slug === slug) - - if (matchedCollection && typeof collectionOptions.adapter === 'function') { - const adapter: GeneratedAdapter = collectionOptions.adapter({ - collection: matchedCollection, - }) - - if (adapter.webpack) { - return adapter.webpack(resultingWebpackConfig) - } - } - - return resultingWebpackConfig - }, - newConfig, - ) - - return modifiedConfig - } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a37ca06d46..94948050b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -900,41 +900,23 @@ importers: version: 1.2.1 devDependencies: '@aws-sdk/client-s3': - specifier: ^3.142.0 - version: 3.523.0 + specifier: ^3.525.0 + version: 3.525.0 '@aws-sdk/lib-storage': - specifier: ^3.267.0 - version: 3.523.0(@aws-sdk/client-s3@3.523.0) + specifier: ^3.525.0 + version: 3.525.1(@aws-sdk/client-s3@3.525.0) '@azure/storage-blob': specifier: ^12.11.0 version: 12.17.0 '@google-cloud/storage': specifier: ^7.7.0 version: 7.7.0 - '@types/express': - specifier: ^4.17.9 - version: 4.17.21 '@types/find-node-modules': specifier: ^2.1.2 version: 2.1.2 - cross-env: - specifier: 7.0.3 - version: 7.0.3 - dotenv: - specifier: 8.6.0 - version: 8.6.0 - nodemon: - specifier: 3.0.3 - version: 3.0.3 payload: specifier: workspace:* version: link:../payload - rimraf: - specifier: ^4.1.2 - version: 4.4.1 - webpack: - specifier: ^5.78.0 - version: 5.90.3(@swc/core@1.4.2)(webpack-cli@5.1.4) packages/plugin-form-builder: dependencies: @@ -1610,6 +1592,72 @@ packages: transitivePeerDependencies: - aws-crt + /@aws-sdk/client-s3@3.525.0: + resolution: {integrity: sha512-hoMGH8G9rezZDiJPsMjsyRVNfVHHa4u6lcZ09SQMmtFHWK0FUcC0DIKR5ripV5qGDbnV54i2JotXlLzAv0aNCQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha1-browser': 3.0.0 + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-bucket-endpoint': 3.525.0 + '@aws-sdk/middleware-expect-continue': 3.523.0 + '@aws-sdk/middleware-flexible-checksums': 3.523.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-location-constraint': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-sdk-s3': 3.525.0 + '@aws-sdk/middleware-signing': 3.523.0 + '@aws-sdk/middleware-ssec': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/signature-v4-multi-region': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@aws-sdk/xml-builder': 3.523.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/eventstream-serde-browser': 2.1.3 + '@smithy/eventstream-serde-config-resolver': 2.1.3 + '@smithy/eventstream-serde-node': 2.1.3 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-blob-browser': 2.1.3 + '@smithy/hash-node': 2.1.3 + '@smithy/hash-stream-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/md5-js': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-retry': 2.1.3 + '@smithy/util-stream': 2.1.3 + '@smithy/util-utf8': 2.1.1 + '@smithy/util-waiter': 2.1.3 + fast-xml-parser: 4.2.5 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: true + /@aws-sdk/client-sso-oidc@3.523.0(@aws-sdk/credential-provider-node@3.523.0): resolution: {integrity: sha512-OktkdiuJ5DtYgNrJlo53Tf7pJ+UWfOt7V7or0ije6MysLP18GwlTkbg2UE4EUtfOxt/baXxHMlExB1vmRtlATw==} engines: {node: '>=14.0.0'} @@ -1660,6 +1708,56 @@ packages: transitivePeerDependencies: - aws-crt + /@aws-sdk/client-sso-oidc@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-zz13k/6RkjPSLmReSeGxd8wzGiiZa4Odr2Tv3wTcxClM4wOjD+zOgGv4Fe32b9AMqaueiCdjbvdu7AKcYxFA4A==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.525.0 + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: true + /@aws-sdk/client-sso@3.523.0: resolution: {integrity: sha512-vob/Tk9bIr6VIyzScBWsKpP92ACI6/aOXBL2BITgvRWl5Umqi1jXFtfssj/N2UJHM4CBMRwxIJ33InfN0gPxZw==} engines: {node: '>=14.0.0'} @@ -1706,6 +1804,52 @@ packages: transitivePeerDependencies: - aws-crt + /@aws-sdk/client-sso@3.525.0: + resolution: {integrity: sha512-6KwGQWFoNLH1UupdWPFdKPfTgjSz1kN8/r8aCzuvvXBe4Pz+iDUZ6FEJzGWNc9AapjvZDNO1hs23slomM9rTaA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/core': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: true + /@aws-sdk/client-sts@3.523.0(@aws-sdk/credential-provider-node@3.523.0): resolution: {integrity: sha512-ggAkL8szaJkqD8oOsS68URJ9XMDbLA/INO/NPZJqv9BhmftecJvfy43uUVWGNs6n4YXNzfF0Y+zQ3DT0fZkv9g==} engines: {node: '>=14.0.0'} @@ -1756,6 +1900,56 @@ packages: transitivePeerDependencies: - aws-crt + /@aws-sdk/client-sts@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-a8NUGRvO6rkfTZCbMaCsjDjLbERCwIUU9dIywFYcRgbFhkupJ7fSaZz3Het98U51M9ZbTEpaTa3fz0HaJv8VJw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/credential-provider-node': ^3.525.0 + dependencies: + '@aws-crypto/sha256-browser': 3.0.0 + '@aws-crypto/sha256-js': 3.0.0 + '@aws-sdk/core': 3.525.0 + '@aws-sdk/credential-provider-node': 3.525.0 + '@aws-sdk/middleware-host-header': 3.523.0 + '@aws-sdk/middleware-logger': 3.523.0 + '@aws-sdk/middleware-recursion-detection': 3.523.0 + '@aws-sdk/middleware-user-agent': 3.525.0 + '@aws-sdk/region-config-resolver': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@aws-sdk/util-user-agent-browser': 3.523.0 + '@aws-sdk/util-user-agent-node': 3.525.0 + '@smithy/config-resolver': 2.1.4 + '@smithy/core': 1.3.5 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/hash-node': 2.1.3 + '@smithy/invalid-dependency': 2.1.3 + '@smithy/middleware-content-length': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/middleware-retry': 2.1.4 + '@smithy/middleware-serde': 2.1.3 + '@smithy/middleware-stack': 2.1.3 + '@smithy/node-config-provider': 2.2.4 + '@smithy/node-http-handler': 2.4.1 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/url-parser': 2.1.3 + '@smithy/util-base64': 2.1.1 + '@smithy/util-body-length-browser': 2.1.1 + '@smithy/util-body-length-node': 2.2.1 + '@smithy/util-defaults-mode-browser': 2.1.4 + '@smithy/util-defaults-mode-node': 2.2.3 + '@smithy/util-endpoints': 1.1.4 + '@smithy/util-middleware': 2.1.3 + '@smithy/util-retry': 2.1.3 + '@smithy/util-utf8': 2.1.1 + fast-xml-parser: 4.2.5 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: true + /@aws-sdk/core@3.523.0: resolution: {integrity: sha512-JHa3ngEWkTzZ2YTn6EavcADC8gv6zZU4U9WBAleClh6ioXH0kGMBawZje3y0F0mKyLTfLhFqFUlCV5sngI/Qcw==} engines: {node: '>=14.0.0'} @@ -1768,6 +1962,18 @@ packages: '@smithy/types': 2.10.1 tslib: 2.6.2 + /@aws-sdk/core@3.525.0: + resolution: {integrity: sha512-E3LtEtMWCriQOFZpVKpLYzbdw/v2PAOEAMhn2VRRZ1g0/g1TXzQrfhEU2yd8l/vQEJaCJ82ooGGg7YECviBUxA==} + engines: {node: '>=14.0.0'} + dependencies: + '@smithy/core': 1.3.5 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/credential-provider-cognito-identity@3.523.0: resolution: {integrity: sha512-HmVtNZdo0JKBkJB00Az11ST5uPMeoIVNKdmOxcmPpdbVV+9OJK3IrlNmXAgoqmltke/KZEcdxOzd8ApQo8kx2Q==} engines: {node: '>=14.0.0'} @@ -1806,6 +2012,21 @@ packages: '@smithy/util-stream': 2.1.3 tslib: 2.6.2 + /@aws-sdk/credential-provider-http@3.525.0: + resolution: {integrity: sha512-RNWQGuSBQZhl3iqklOslUEfQ4br1V3DCPboMpeqFtddUWJV3m2u2extFur9/4Uy+1EHVF120IwZUKtd8dF+ibw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@smithy/fetch-http-handler': 2.4.3 + '@smithy/node-http-handler': 2.4.1 + '@smithy/property-provider': 2.1.3 + '@smithy/protocol-http': 3.2.1 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-stream': 2.1.3 + tslib: 2.6.2 + dev: true + /@aws-sdk/credential-provider-ini@3.523.0(@aws-sdk/credential-provider-node@3.523.0): resolution: {integrity: sha512-dRch5Ts67FFRZY5r9DpiC3PM6BVHv1tRcy1b26hoqfFkxP9xYH3dsTSPBog1azIqaJa2GcXqEvKCqhghFTt4Xg==} engines: {node: '>=14.0.0'} @@ -1826,6 +2047,26 @@ packages: - '@aws-sdk/credential-provider-node' - aws-crt + /@aws-sdk/credential-provider-ini@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-JDnccfK5JRb9jcgpc9lirL9PyCwGIqY0nKdw3LlX5WL5vTpTG4E1q7rLAlpNh7/tFD1n66Itarfv2tsyHMIqCw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-env': 3.523.0 + '@aws-sdk/credential-provider-process': 3.523.0 + '@aws-sdk/credential-provider-sso': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-web-identity': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/credential-provider-imds': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt + dev: true + /@aws-sdk/credential-provider-node@3.523.0: resolution: {integrity: sha512-0aW5ylA8pZmvv/8qA/+iel4acEyzSlHRiaHYL3L0qu9SSoe2a92+RHjrxKl6+Sb55eA2mRfQjaN8oOa5xiYyKA==} engines: {node: '>=14.0.0'} @@ -1846,6 +2087,26 @@ packages: transitivePeerDependencies: - aws-crt + /@aws-sdk/credential-provider-node@3.525.0: + resolution: {integrity: sha512-RJXlO8goGXpnoHQAyrCcJ0QtWEOFa34LSbfdqBIjQX/fwnjUuEmiGdXTV3AZmwYQ7juk49tfBneHbtOP3AGqsQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/credential-provider-env': 3.523.0 + '@aws-sdk/credential-provider-http': 3.525.0 + '@aws-sdk/credential-provider-ini': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-process': 3.523.0 + '@aws-sdk/credential-provider-sso': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/credential-provider-web-identity': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/credential-provider-imds': 2.2.4 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + transitivePeerDependencies: + - aws-crt + dev: true + /@aws-sdk/credential-provider-process@3.523.0: resolution: {integrity: sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q==} engines: {node: '>=14.0.0'} @@ -1873,6 +2134,22 @@ packages: - '@aws-sdk/credential-provider-node' - aws-crt + /@aws-sdk/credential-provider-sso@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-7V7ybtufxdD3plxeIeB6aqHZeFIUlAyPphXIUgXrGY10iNcosL970rQPBeggsohe4gCM6UvY2TfMeEcr+ZE8FA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sso': 3.525.0 + '@aws-sdk/token-providers': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt + dev: true + /@aws-sdk/credential-provider-web-identity@3.523.0(@aws-sdk/credential-provider-node@3.523.0): resolution: {integrity: sha512-EyBwVoTNZrhLRIHly3JnLzy86deT2hHGoxSCrT3+cVcF1Pq3FPp6n9fUkHd6Yel+wFrjpXCRggLddPvajUoXtQ==} engines: {node: '>=14.0.0'} @@ -1887,6 +2164,20 @@ packages: - '@aws-sdk/credential-provider-node' - aws-crt + /@aws-sdk/credential-provider-web-identity@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-sAukOjR1oKb2JXG4nPpuBFpSwGUhrrY17PG/xbTy8NAoLLhrqRwnErcLfdTfmj6tH+3094k6ws/Sh8a35ae7fA==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sts': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt + dev: true + /@aws-sdk/credential-providers@3.523.0: resolution: {integrity: sha512-A6uIcr4CuIq6+HTcho8soRmwDzXLVX2cs4U/WbHNOiD9rbLs/3kc4c/kkuGsMcq/pFm2dULxav0YuKyOAi3DEA==} engines: {node: '>=14.0.0'} @@ -1925,6 +2216,23 @@ packages: events: 3.3.0 stream-browserify: 3.0.0 tslib: 2.6.2 + dev: false + + /@aws-sdk/lib-storage@3.525.1(@aws-sdk/client-s3@3.525.0): + resolution: {integrity: sha512-q0y4+bc5GsE10F1HyA1D24maRyy2H3Ph3o+1eK7/kzKrk0nBbISLGbZ8XNqtWwi+9KdsqWNKMoN9+zsDaE6d/w==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@aws-sdk/client-s3': ^3.0.0 + dependencies: + '@aws-sdk/client-s3': 3.525.0 + '@smithy/abort-controller': 2.1.3 + '@smithy/middleware-endpoint': 2.4.4 + '@smithy/smithy-client': 2.4.2 + buffer: 5.6.0 + events: 3.3.0 + stream-browserify: 3.0.0 + tslib: 2.6.2 + dev: true /@aws-sdk/middleware-bucket-endpoint@3.523.0: resolution: {integrity: sha512-mrZbixWjk0d9NqxC4xBnKtfwErum0we4Uk2O4fgvDVI+XxAimUlZ9c4o/QJ2+TzeQ/8QclT2k4WidsQdWtPNvg==} @@ -1938,6 +2246,19 @@ packages: '@smithy/util-config-provider': 2.2.1 tslib: 2.6.2 + /@aws-sdk/middleware-bucket-endpoint@3.525.0: + resolution: {integrity: sha512-nYfQ2Xspfef7j8mZO7varUWLPH6HQlXateH7tBVtBNUAazyQE4UJEvC0fbQ+Y01e+FKlirim/m2umkdMXqAlTg==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-arn-parser': 3.495.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/middleware-expect-continue@3.523.0: resolution: {integrity: sha512-E5DyRAHU39VHaAlQLqXYS/IKpgk3vsryuU6kkOcIIK8Dgw0a2tjoh5AOCaNa8pD+KgAGrFp35JIMSX1zui5diA==} engines: {node: '>=14.0.0'} @@ -2011,6 +2332,21 @@ packages: '@smithy/util-config-provider': 2.2.1 tslib: 2.6.2 + /@aws-sdk/middleware-sdk-s3@3.525.0: + resolution: {integrity: sha512-ewFyyFM6wdFTOqCiId5GQNi7owDdLEonQhB4h8tF6r3HV52bRlDvZA4aDos+ft6N/XY2J6L0qlFTFq+/oiurXw==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-arn-parser': 3.495.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/smithy-client': 2.4.2 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/middleware-signing@3.523.0: resolution: {integrity: sha512-pFXV4don6qcmew/OvEjLUr2foVjzoJ8o5k57Oz9yAHz8INx3RHK8MP/K4mVhHo6n0SquRcWrm4kY/Tw+89gkEA==} engines: {node: '>=14.0.0'} @@ -2042,6 +2378,17 @@ packages: '@smithy/types': 2.10.1 tslib: 2.6.2 + /@aws-sdk/middleware-user-agent@3.525.0: + resolution: {integrity: sha512-4al/6uO+t/QIYXK2OgqzDKQzzLAYJza1vWFS+S0lJ3jLNGyLB5BMU5KqWjDzevYZ4eCnz2Nn7z0FveUTNz8YdQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@aws-sdk/util-endpoints': 3.525.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/region-config-resolver@3.523.0: resolution: {integrity: sha512-IypIAecBc8b4jM0uVBEj90NYaIsc0vuLdSFyH4LPO7is4rQUet4CkkD+S036NvDdcdxBsQ4hJZBmWrqiizMHhQ==} engines: {node: '>=14.0.0'} @@ -2054,6 +2401,18 @@ packages: '@smithy/util-middleware': 2.1.3 tslib: 2.6.2 + /@aws-sdk/region-config-resolver@3.525.0: + resolution: {integrity: sha512-8kFqXk6UyKgTMi7N7QlhA6qM4pGPWbiUXqEY2RgUWngtxqNFGeM9JTexZeuavQI+qLLe09VPShPNX71fEDcM6w==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 + '@smithy/util-config-provider': 2.2.1 + '@smithy/util-middleware': 2.1.3 + tslib: 2.6.2 + dev: true + /@aws-sdk/signature-v4-multi-region@3.523.0: resolution: {integrity: sha512-TU1AfF6YlihdMy4H5YtkmFYmA/Zrh7sqk2V6tPiR2Vu6idc+9xm1R0UE/2V/DKgMIkxfr4+cAojtp2kqYuuF/A==} engines: {node: '>=14.0.0'} @@ -2065,6 +2424,18 @@ packages: '@smithy/types': 2.10.1 tslib: 2.6.2 + /@aws-sdk/signature-v4-multi-region@3.525.0: + resolution: {integrity: sha512-j8gkdfiokaherRgokfZBl2azYBMHlegT7pOnR/3Y79TSz6G+bJeIkuNk8aUbJArr6R8nvAM1j4dt1rBM+efolQ==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.525.0 + '@aws-sdk/types': 3.523.0 + '@smithy/protocol-http': 3.2.1 + '@smithy/signature-v4': 2.1.3 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/token-providers@3.523.0(@aws-sdk/credential-provider-node@3.523.0): resolution: {integrity: sha512-m3sPEnLuGV3JY9A8ytcz90SogVtjxEyIxUDFeswxY4C5wP/36yOq3ivenRu07dH+QIJnBhsQdjnHwJfrIetG6g==} engines: {node: '>=14.0.0'} @@ -2080,6 +2451,21 @@ packages: - '@aws-sdk/credential-provider-node' - aws-crt + /@aws-sdk/token-providers@3.525.0(@aws-sdk/credential-provider-node@3.525.0): + resolution: {integrity: sha512-puVjbxuK0Dq7PTQ2HdddHy2eQjOH8GZbump74yWJa6JVpRW84LlOcNmP+79x4Kscvz2ldWB8XDFw/pcCiSDe5A==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/client-sso-oidc': 3.525.0(@aws-sdk/credential-provider-node@3.525.0) + '@aws-sdk/types': 3.523.0 + '@smithy/property-provider': 2.1.3 + '@smithy/shared-ini-file-loader': 2.3.4 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + transitivePeerDependencies: + - '@aws-sdk/credential-provider-node' + - aws-crt + dev: true + /@aws-sdk/types@3.523.0: resolution: {integrity: sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A==} engines: {node: '>=14.0.0'} @@ -2104,6 +2490,16 @@ packages: '@smithy/util-endpoints': 1.1.4 tslib: 2.6.2 + /@aws-sdk/util-endpoints@3.525.0: + resolution: {integrity: sha512-DIW7WWU5tIGkeeKX6NJUyrEIdWMiqjLQG3XBzaUj+ufIENwNjdAHhlD8l2vX7Yr3JZRT6yN/84wBCj7Tw1xd1g==} + engines: {node: '>=14.0.0'} + dependencies: + '@aws-sdk/types': 3.523.0 + '@smithy/types': 2.10.1 + '@smithy/util-endpoints': 1.1.4 + tslib: 2.6.2 + dev: true + /@aws-sdk/util-locate-window@3.495.0: resolution: {integrity: sha512-MfaPXT0kLX2tQaR90saBT9fWQq2DHqSSJRzW+MZWsmF+y5LGCOhO22ac/2o6TKSQm7h0HRc2GaADqYYYor62yg==} engines: {node: '>=14.0.0'} @@ -2135,6 +2531,21 @@ packages: '@smithy/types': 2.10.1 tslib: 2.6.2 + /@aws-sdk/util-user-agent-node@3.525.0: + resolution: {integrity: sha512-88Wjt4efyUSBGcyIuh1dvoMqY1k15jpJc5A/3yi67clBQEFsu9QCodQCQPqmRjV3VRcMtBOk+jeCTiUzTY5dRQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + dependencies: + '@aws-sdk/types': 3.523.0 + '@smithy/node-config-provider': 2.2.4 + '@smithy/types': 2.10.1 + tslib: 2.6.2 + dev: true + /@aws-sdk/util-utf8-browser@3.259.0: resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} requiresBuild: true @@ -10434,16 +10845,6 @@ packages: minimatch: 5.1.6 once: 1.4.0 - /glob@9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.10.1 - dev: true - /global-dirs@3.0.1: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} @@ -12900,13 +13301,6 @@ packages: brace-expansion: 2.0.1 dev: false - /minimatch@8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimatch@9.0.1: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} engines: {node: '>=16 || 14 >=14.17'} @@ -12923,11 +13317,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - /minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - dev: true - /minipass@7.0.4: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} @@ -15484,14 +15873,6 @@ packages: dependencies: glob: 7.2.3 - /rimraf@4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} - hasBin: true - dependencies: - glob: 9.3.5 - dev: true - /run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} diff --git a/test/plugin-cloud-storage/.env.emulated b/test/plugin-cloud-storage/.env.emulated index 0c9398273a..84e6b5045b 100644 --- a/test/plugin-cloud-storage/.env.emulated +++ b/test/plugin-cloud-storage/.env.emulated @@ -3,7 +3,7 @@ MONGODB_URI=mongodb://localhost/payload-plugin-cloud-storage PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000 PAYLOAD_SECRET=45ligj345ligj4wl5igj4lw5igj45ligj45wlijl -PAYLOAD_CONFIG_PATH=src/payload.config.ts +PAYLOAD_CONFIG_PATH=config.ts AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://localhost:10000/devstoreaccount1;QueueEndpoint=http://localhost:10001/devstoreaccount1; AZURE_STORAGE_CONTAINER_NAME=az-media @@ -15,6 +15,7 @@ S3_ACCESS_KEY_ID=payloadAccessKey S3_SECRET_ACCESS_KEY=alwiejglaiwhewlihgawe S3_BUCKET=payload-bucket S3_FORCE_PATH_STYLE=true +S3_REGION=us-east-1 GCS_ENDPOINT=http://localhost:4443 GCS_PROJECT_ID=test @@ -28,3 +29,4 @@ R2_BUCKET=payload-bucket R2_FORCE_PATH_STYLE= PAYLOAD_DROP_DATABASE=true +PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER=s3 diff --git a/test/plugin-cloud-storage/collections/Media.ts b/test/plugin-cloud-storage/collections/Media.ts index 4c8d72ce6f..055daa1287 100644 --- a/test/plugin-cloud-storage/collections/Media.ts +++ b/test/plugin-cloud-storage/collections/Media.ts @@ -3,7 +3,7 @@ import type { CollectionConfig } from '../../../packages/payload/src/collections export const Media: CollectionConfig = { slug: 'media', upload: { - disableLocalStorage: false, // don't save me + disableLocalStorage: true, // don't save me resizeOptions: { position: 'center', width: 200, diff --git a/test/plugin-cloud-storage/config.ts b/test/plugin-cloud-storage/config.ts index ec8952c89a..2c60f02a26 100644 --- a/test/plugin-cloud-storage/config.ts +++ b/test/plugin-cloud-storage/config.ts @@ -1,3 +1,4 @@ +import * as AWS from '@aws-sdk/client-s3' import dotenv from 'dotenv' import path from 'path' @@ -16,9 +17,13 @@ let adapter: Adapter let uploadOptions dotenv.config({ - path: path.resolve(__dirname, '.env.emulated'), + path: path.resolve(process.cwd(), './test/plugin-cloud-storage/.env.emulated'), }) +console.log( + `Using plugin-cloud-storage adapter: ${process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER}`, +) + if (process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER === 'azure') { adapter = azureBlobStorageAdapter({ connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING, @@ -79,37 +84,9 @@ if (process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER === 'r2') { }) } -console.log( - `Using plugin-cloud-storage adapter: ${process.env.PAYLOAD_PUBLIC_CLOUD_STORAGE_ADAPTER}`, -) - export default buildConfigWithDefaults({ collections: [Media, Users], upload: uploadOptions, - admin: { - webpack: (config) => ({ - ...config, - resolve: { - ...config.resolve, - alias: { - ...config?.resolve?.alias, - [path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/index')]: path.resolve( - __dirname, - '../../packages/plugin-cloud-storage/src/admin/mock.js', - ), - [path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/adapters/s3/index')]: - path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/adapters/s3/mock.js'), - [path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/adapters/gcs/index')]: - path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/adapters/gcs/mock.js'), - [path.resolve(__dirname, '../../packages/plugin-cloud-storage/src/adapters/azure/index')]: - path.resolve( - __dirname, - '../../packages/plugin-cloud-storage/src/adapters/azure/mock.js', - ), - }, - }, - }), - }, plugins: [ cloudStorage({ collections: { @@ -120,6 +97,24 @@ export default buildConfigWithDefaults({ }), ], onInit: async (payload) => { + /*const client = new AWS.S3({ + endpoint: process.env.S3_ENDPOINT, + forcePathStyle: process.env.S3_FORCE_PATH_STYLE === 'true', + region: process.env.S3_REGION, + credentials: { + accessKeyId: process.env.S3_ACCESS_KEY_ID, + secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, + }, + }) + + const makeBucketRes = await client.send( + new AWS.CreateBucketCommand({ Bucket: 'payload-bucket' }), + ) + + if (makeBucketRes.$metadata.httpStatusCode !== 200) { + throw new Error(`Failed to create bucket. ${makeBucketRes.$metadata.httpStatusCode}`) + }*/ + await payload.create({ collection: 'users', data: { diff --git a/tsconfig.json b/tsconfig.json index e305bb54d1..c8e62940d1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,11 @@ "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "jsx": "preserve", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "noEmit": true, "outDir": "./dist", "resolveJsonModule": true, @@ -18,7 +22,11 @@ "skipLibCheck": true, "sourceMap": true, "strict": false, - "types": ["jest", "node", "@types/jest"], + "types": [ + "jest", + "node", + "@types/jest" + ], "incremental": true, "isolatedModules": true, "plugins": [ @@ -27,27 +35,62 @@ } ], "paths": { - "payload": ["./packages/payload/src"], - "payload/*": ["./packages/payload/src/exports/*"], - "@payloadcms/db-mongodb": ["./packages/db-mongodb/src"], - "@payloadcms/richtext-lexical": ["./packages/richtext-lexical/src"], - "@payloadcms/plugin-cloud-storage": ["./packages/plugin-cloud-storage/src"], - "@payloadcms/ui": ["./packages/ui/src/exports/index.ts"], - "@payloadcms/ui/*": ["./packages/ui/src/exports/*"], - "@payloadcms/ui/scss": ["./packages/ui/src/scss/styles.scss"], - "@payloadcms/ui/scss/app.scss": ["./packages/ui/src/scss/app.scss"], - "@payloadcms/translations": ["./packages/translations/src/exports/index.ts"], + "payload": [ + "./packages/payload/src" + ], + "payload/*": [ + "./packages/payload/src/exports/*" + ], + "@payloadcms/db-mongodb": [ + "./packages/db-mongodb/src" + ], + "@payloadcms/richtext-lexical": [ + "./packages/richtext-lexical/src" + ], + "@payloadcms/plugin-cloud-storage": [ + "./packages/plugin-cloud-storage/src" + ], + "@payloadcms/ui": [ + "./packages/ui/src/exports/index.ts" + ], + "@payloadcms/ui/*": [ + "./packages/ui/src/exports/*" + ], + "@payloadcms/ui/scss": [ + "./packages/ui/src/scss/styles.scss" + ], + "@payloadcms/ui/scss/app.scss": [ + "./packages/ui/src/scss/app.scss" + ], + "@payloadcms/translations": [ + "./packages/translations/src/exports/index.ts" + ], "@payloadcms/translations/client": [ "./packages/translations/src/_generatedFiles_/client/index.ts" ], - "@payloadcms/translations/api": ["./packages/translations/src/_generatedFiles_/api/index.ts"], - "@payloadcms/next/*": ["./packages/next/src/*"], - "@payloadcms/next": ["./packages/next/src/exports/*"], - "@payloadcms/graphql": ["./packages/graphql/src"], - "@payload-config": ["./test/_community/config.ts"] + "@payloadcms/translations/api": [ + "./packages/translations/src/_generatedFiles_/api/index.ts" + ], + "@payloadcms/next/*": [ + "./packages/next/src/*" + ], + "@payloadcms/next": [ + "./packages/next/src/exports/*" + ], + "@payloadcms/graphql": [ + "./packages/graphql/src" + ], + "@payload-config": [ + "./test/plugin-cloud-storage/config.ts" + ] } }, - "exclude": ["dist", "build", "temp", "node_modules"], + "exclude": [ + "dist", + "build", + "temp", + "node_modules" + ], "composite": true, "references": [ {