Added support for FTP uploads
This commit is contained in:
parent
b7dca38786
commit
609bbe5866
10
.env.example
10
.env.example
|
@ -11,4 +11,12 @@ STRAPI_TOKEN=strapisecreta5e6ea45ef4e66eaa151612bdcb599df
|
|||
|
||||
SEEDING_ADMIN_USERNAME=admin_name
|
||||
SEEDING_ADMIN_EMAIL=email@domain.com
|
||||
SEEDING_ADMIN_PASSWORD=somepassword
|
||||
SEEDING_ADMIN_PASSWORD=somepassword
|
||||
|
||||
WEB_HOOK_TOKEN=webhooktoken5e6ea45ef4e66eaa151612bdcb599df
|
||||
WEB_HOOK_URI=https://accords-library.com/some/path
|
||||
|
||||
FTP_USER=someuser
|
||||
FTP_PASSWORD=somepassword
|
||||
FTP_HOST=ftp.host.com
|
||||
FTP_BASE_URL=https://ftp-base-url.com
|
|
@ -12,7 +12,9 @@
|
|||
"@fontsource/vollkorn": "5.0.19",
|
||||
"@payloadcms/bundler-webpack": "1.0.6",
|
||||
"@payloadcms/db-mongodb": "1.4.4",
|
||||
"@payloadcms/plugin-cloud-storage": "^1.1.2",
|
||||
"@payloadcms/richtext-lexical": "0.8.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
"cross-env": "7.0.3",
|
||||
"language-tags": "1.0.9",
|
||||
"luxon": "3.4.4",
|
||||
|
@ -3109,6 +3111,40 @@
|
|||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@payloadcms/plugin-cloud-storage": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@payloadcms/plugin-cloud-storage/-/plugin-cloud-storage-1.1.2.tgz",
|
||||
"integrity": "sha512-wBpEWv4VdfltBqEi5ECSrKQ/TtNvmBWT4DLCrTCOhpNuD8dYD2rp+0Eoj7cF8f6wU7DpS5rvdQ/8gxlqh0Armw==",
|
||||
"dependencies": {
|
||||
"find-node-modules": "^2.1.3",
|
||||
"range-parser": "^1.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.142.0",
|
||||
"@aws-sdk/lib-storage": "^3.267.0",
|
||||
"@azure/abort-controller": "^1.0.0",
|
||||
"@azure/storage-blob": "^12.11.0",
|
||||
"@google-cloud/storage": "^6.4.1",
|
||||
"payload": "^1.7.2 || ^2.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@aws-sdk/client-s3": {
|
||||
"optional": true
|
||||
},
|
||||
"@aws-sdk/lib-storage": {
|
||||
"optional": true
|
||||
},
|
||||
"@azure/abort-controller": {
|
||||
"optional": true
|
||||
},
|
||||
"@azure/storage-blob": {
|
||||
"optional": true
|
||||
},
|
||||
"@google-cloud/storage": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@payloadcms/richtext-lexical": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@payloadcms/richtext-lexical/-/richtext-lexical-0.8.0.tgz",
|
||||
|
@ -5116,6 +5152,14 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/basic-ftp": {
|
||||
"version": "5.0.5",
|
||||
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
|
||||
"integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
"@fontsource/vollkorn": "5.0.19",
|
||||
"@payloadcms/bundler-webpack": "1.0.6",
|
||||
"@payloadcms/db-mongodb": "1.4.4",
|
||||
"@payloadcms/plugin-cloud-storage": "^1.1.2",
|
||||
"@payloadcms/richtext-lexical": "0.8.0",
|
||||
"basic-ftp": "^5.0.5",
|
||||
"cross-env": "7.0.3",
|
||||
"language-tags": "1.0.9",
|
||||
"luxon": "3.4.4",
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
||||
export const Videos = buildCollectionConfig({
|
||||
slug: Collections.Videos,
|
||||
labels: { singular: "Video", plural: "Videos" },
|
||||
admin: { group: CollectionGroups.Media },
|
||||
upload: {
|
||||
mimeTypes: ["video/*"],
|
||||
disableLocalStorage: true,
|
||||
},
|
||||
fields: [],
|
||||
});
|
|
@ -19,6 +19,7 @@ export enum Collections {
|
|||
Collectibles = "collectibles",
|
||||
GenericContents = "generic-contents",
|
||||
HomeFolders = "home-folders",
|
||||
Videos = "videos",
|
||||
}
|
||||
|
||||
export enum CollectionGroups {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { webpackBundler } from "@payloadcms/bundler-webpack";
|
||||
import { mongooseAdapter } from "@payloadcms/db-mongodb";
|
||||
import { cloudStorage } from "@payloadcms/plugin-cloud-storage";
|
||||
import path from "path";
|
||||
import { buildConfig } from "payload/config";
|
||||
import { ChronologyEvents } from "./collections/ChronologyEvents/ChronologyEvents";
|
||||
|
@ -15,12 +16,21 @@ import { Pages } from "./collections/Pages/Pages";
|
|||
import { Recorders } from "./collections/Recorders/Recorders";
|
||||
import { Tags } from "./collections/Tags/Tags";
|
||||
import { TagsGroups } from "./collections/TagsGroups/TagsGroups";
|
||||
import { Videos } from "./collections/Videos/Videos";
|
||||
import { Wordings } from "./collections/Wordings/Wordings";
|
||||
import { Icon } from "./components/Icon";
|
||||
import { Logo } from "./components/Logo";
|
||||
import { Collections } from "./constants";
|
||||
import { ftpAdapter } from "./plugins/ftpAdapter";
|
||||
import { createEditor } from "./utils/editor";
|
||||
|
||||
if (!process.env.PAYLOAD_URI) throw new Error("Missing PAYLOAD_URI in .env");
|
||||
if (!process.env.MONGODB_URI) throw new Error("Missing MONGODB_URI in .env");
|
||||
if (!process.env.FTP_HOST) throw new Error("Missing FTP_HOST in .env");
|
||||
if (!process.env.FTP_USER) throw new Error("Missing FTP_USER in .env");
|
||||
if (!process.env.FTP_PASSWORD) throw new Error("Missing FTP_PASSWORD in .env");
|
||||
if (!process.env.FTP_BASE_URL) throw new Error("Missing FTP_BASE_URL in .env");
|
||||
|
||||
export default buildConfig({
|
||||
serverURL: process.env.PAYLOAD_URI,
|
||||
admin: {
|
||||
|
@ -43,6 +53,7 @@ export default buildConfig({
|
|||
Notes,
|
||||
|
||||
Images,
|
||||
Videos,
|
||||
|
||||
Tags,
|
||||
TagsGroups,
|
||||
|
@ -53,7 +64,7 @@ export default buildConfig({
|
|||
GenericContents,
|
||||
],
|
||||
db: mongooseAdapter({
|
||||
url: process.env.MONGODB_URI ?? "mongodb://mongo:27017/payload",
|
||||
url: process.env.MONGODB_URI,
|
||||
}),
|
||||
globals: [HomeFolders],
|
||||
telemetry: false,
|
||||
|
@ -63,4 +74,21 @@ export default buildConfig({
|
|||
graphQL: {
|
||||
disable: true,
|
||||
},
|
||||
plugins: [
|
||||
cloudStorage({
|
||||
collections: {
|
||||
[Collections.Videos]: {
|
||||
adapter: ftpAdapter({
|
||||
host: process.env.FTP_HOST,
|
||||
user: process.env.FTP_USER,
|
||||
password: process.env.FTP_PASSWORD,
|
||||
secure: false,
|
||||
endpoint: process.env.FTP_BASE_URL,
|
||||
}),
|
||||
disableLocalStorage: true,
|
||||
disablePayloadAccessControl: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
import {
|
||||
Adapter,
|
||||
GenerateURL,
|
||||
HandleDelete,
|
||||
HandleUpload,
|
||||
} from "@payloadcms/plugin-cloud-storage/dist/types";
|
||||
import { Client } from "basic-ftp";
|
||||
import path from "path";
|
||||
import { Readable } from "stream";
|
||||
import type { Configuration as WebpackConfig } from "webpack";
|
||||
|
||||
interface FTPAdapterConfig {
|
||||
host: string;
|
||||
user: string;
|
||||
password: string;
|
||||
secure: boolean;
|
||||
endpoint: string;
|
||||
}
|
||||
|
||||
export const ftpAdapter =
|
||||
({ endpoint, host, password, secure, user }: FTPAdapterConfig): Adapter =>
|
||||
({ collection }) => {
|
||||
const generateURL: GenerateURL = ({ filename }) => `${endpoint}/${collection.slug}/${filename}`;
|
||||
const handleDelete: HandleDelete = async ({ filename }) => {
|
||||
const client = new Client();
|
||||
client.ftp.verbose = true;
|
||||
await client.access({
|
||||
host,
|
||||
user,
|
||||
password,
|
||||
secure,
|
||||
});
|
||||
await client.ensureDir(collection.slug);
|
||||
await client.remove(filename);
|
||||
client.close();
|
||||
};
|
||||
const handleUpload: HandleUpload = async ({ file }) => {
|
||||
const client = new Client();
|
||||
client.ftp.verbose = true;
|
||||
await client.access({
|
||||
host: process.env.FTP_HOST,
|
||||
user: process.env.FTP_USER,
|
||||
password: process.env.FTP_PASSWORD,
|
||||
secure: false,
|
||||
});
|
||||
await client.ensureDir(collection.slug);
|
||||
await client.uploadFrom(Readable.from(file.buffer), file.filename);
|
||||
client.close();
|
||||
};
|
||||
|
||||
const webpack = (existingWebpackConfig: WebpackConfig): WebpackConfig => {
|
||||
const newConfig: WebpackConfig = {
|
||||
...existingWebpackConfig,
|
||||
resolve: {
|
||||
...(existingWebpackConfig.resolve || {}),
|
||||
alias: {
|
||||
...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}),
|
||||
"./plugins/ftpAdapter": path.resolve(__dirname, "./mock.js"),
|
||||
},
|
||||
fallback: {
|
||||
...(existingWebpackConfig.resolve?.fallback
|
||||
? existingWebpackConfig.resolve.fallback
|
||||
: {}),
|
||||
stream: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return newConfig;
|
||||
};
|
||||
|
||||
return {
|
||||
generateURL,
|
||||
handleDelete,
|
||||
handleUpload,
|
||||
staticHandler: () => {},
|
||||
webpack,
|
||||
};
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export const ftpAdapter = () => {};
|
|
@ -49,6 +49,7 @@ export interface Config {
|
|||
"chronology-events": ChronologyEvent;
|
||||
notes: Note;
|
||||
images: Image;
|
||||
videos: Video;
|
||||
tags: Tag;
|
||||
"tags-groups": TagsGroup;
|
||||
recorders: Recorder;
|
||||
|
@ -622,6 +623,21 @@ export interface Note {
|
|||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "videos".
|
||||
*/
|
||||
export interface Video {
|
||||
id: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
url?: string | null;
|
||||
filename?: string | null;
|
||||
mimeType?: string | null;
|
||||
filesize?: number | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "wordings".
|
||||
|
|
Loading…
Reference in New Issue