mirror of
https://github.com/directus/directus.git
synced 2026-02-02 17:45:07 -05:00
Setup dynamic storage adapter configuration
This commit is contained in:
@@ -1,11 +1,61 @@
|
||||
import express from 'express';
|
||||
import asyncHandler from 'express-async-handler';
|
||||
import Busboy from 'busboy';
|
||||
import sanitizeQuery from '../middleware/sanitize-query';
|
||||
import validateQuery from '../middleware/validate-query';
|
||||
import * as FilesService from '../services/files';
|
||||
import storage from '../storage';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.post(
|
||||
'/',
|
||||
asyncHandler(async (req, res, next) => {
|
||||
const busboy = new Busboy({ headers: req.headers });
|
||||
|
||||
/**
|
||||
* The order of the fields in multipart/form-data is important. We require that storage is set
|
||||
* before the file contents itself. This allows us to set and use the correct storage adapter
|
||||
* for the file upload.
|
||||
*/
|
||||
|
||||
let disk: string;
|
||||
|
||||
busboy.on('field', (fieldname, val) => {
|
||||
if (fieldname === 'storage') {
|
||||
disk = val;
|
||||
}
|
||||
});
|
||||
|
||||
busboy.on('file', async (fieldname, fileStream, filename, encoding, mimetype) => {
|
||||
if (!disk) {
|
||||
return busboy.emit('error', new Error('no storage provided'));
|
||||
}
|
||||
|
||||
try {
|
||||
await storage.disk(disk).put(filename, fileStream as Readable);
|
||||
} catch (err) {
|
||||
busboy.emit('error', err);
|
||||
}
|
||||
|
||||
fileStream.on('end', () => {
|
||||
console.log(`File ${filename} saved.`);
|
||||
});
|
||||
});
|
||||
|
||||
busboy.on('error', (error: Error) => {
|
||||
next(error);
|
||||
});
|
||||
|
||||
busboy.on('finish', () => {
|
||||
res.status(200).end();
|
||||
});
|
||||
|
||||
return req.pipe(busboy);
|
||||
})
|
||||
);
|
||||
|
||||
/** @TODO This needs to support multipart form-data for file uploads */
|
||||
// router.post(
|
||||
// '/',
|
||||
|
||||
68
src/storage.ts
Normal file
68
src/storage.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import {
|
||||
StorageManager,
|
||||
LocalFileSystemStorage,
|
||||
StorageManagerConfig,
|
||||
Storage,
|
||||
} from '@slynova/flydrive';
|
||||
import camelcase from 'camelcase';
|
||||
|
||||
import { AmazonWebServicesS3Storage } from '@slynova/flydrive-s3';
|
||||
import { GoogleCloudStorage } from '@slynova/flydrive-gcs';
|
||||
|
||||
/** @todo dynamically load storage adapters here */
|
||||
|
||||
console.log(getStorageConfig());
|
||||
const storage = new StorageManager(getStorageConfig());
|
||||
|
||||
registerDrivers(storage);
|
||||
|
||||
export default storage;
|
||||
|
||||
function getStorageConfig(): StorageManagerConfig {
|
||||
const config: any = { disks: {} };
|
||||
|
||||
for (const [key, value] of Object.entries(process.env)) {
|
||||
if (key.startsWith('STORAGE') === false) continue;
|
||||
if (key === 'STORAGE_LOCATIONS') continue;
|
||||
if (key.endsWith('PUBLIC_URL')) continue;
|
||||
|
||||
const disk = key.split('_')[1].toLowerCase();
|
||||
if (!config.disks[disk]) config.disks[disk] = { config: {} };
|
||||
|
||||
if (key.endsWith('DRIVER')) {
|
||||
config.disks[disk].driver = value;
|
||||
continue;
|
||||
}
|
||||
|
||||
const configKey = camelcase(
|
||||
key.split('_').filter((_, index) => [0, 1].includes(index) === false)
|
||||
);
|
||||
config.disks[disk].config[configKey] = value;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function registerDrivers(storage: StorageManager) {
|
||||
const usedDrivers: string[] = [];
|
||||
|
||||
for (const [key, value] of Object.entries(process.env)) {
|
||||
if ((key.startsWith('STORAGE') && key.endsWith('DRIVER')) === false) continue;
|
||||
if (usedDrivers.includes(value) === false) usedDrivers.push(value);
|
||||
}
|
||||
|
||||
usedDrivers.forEach((driver) => {
|
||||
storage.registerDriver<Storage>(driver, getStorageDriver(driver));
|
||||
});
|
||||
}
|
||||
|
||||
function getStorageDriver(driver: string) {
|
||||
switch (driver) {
|
||||
case 'local':
|
||||
return LocalFileSystemStorage;
|
||||
case 's3':
|
||||
return AmazonWebServicesS3Storage;
|
||||
case 'gcs':
|
||||
return GoogleCloudStorage;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user