mirror of
https://github.com/directus/directus.git
synced 2026-01-29 18:27:55 -05:00
Save file with payload in service
This commit is contained in:
@@ -6,6 +6,7 @@ import validateQuery from '../middleware/validate-query';
|
||||
import * as FilesService from '../services/files';
|
||||
import storage from '../storage';
|
||||
import { Readable } from 'stream';
|
||||
import logger from '../logger';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -15,33 +16,44 @@ router.post(
|
||||
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.
|
||||
* The order of the fields in multipart/form-data is important. We require that all fields
|
||||
* are provided _before_ the files. This allows us to set the storage location, and create
|
||||
* the row in directus_files async during the upload of the actual file.
|
||||
*/
|
||||
|
||||
let disk: string;
|
||||
let payload: Record<string, any> = {};
|
||||
|
||||
busboy.on('field', (fieldname, val) => {
|
||||
if (fieldname === 'storage') {
|
||||
disk = val;
|
||||
}
|
||||
|
||||
payload[fieldname] = val;
|
||||
});
|
||||
|
||||
busboy.on('file', async (fieldname, fileStream, filename, encoding, mimetype) => {
|
||||
if (!disk) {
|
||||
// @todo error
|
||||
return busboy.emit('error', new Error('no storage provided'));
|
||||
}
|
||||
|
||||
payload = {
|
||||
...payload,
|
||||
filename_disk: filename,
|
||||
filename_download: filename,
|
||||
type: mimetype,
|
||||
};
|
||||
|
||||
fileStream.on('end', () => {
|
||||
logger.info(`File ${filename} uploaded to ${disk}.`);
|
||||
});
|
||||
|
||||
try {
|
||||
await storage.disk(disk).put(filename, fileStream as Readable);
|
||||
await FilesService.createFile(fileStream, payload);
|
||||
} catch (err) {
|
||||
busboy.emit('error', err);
|
||||
}
|
||||
|
||||
fileStream.on('end', () => {
|
||||
console.log(`File ${filename} saved.`);
|
||||
});
|
||||
});
|
||||
|
||||
busboy.on('error', (error: Error) => {
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
import { Query } from '../types/query';
|
||||
import * as ItemsService from './items';
|
||||
import storage from '../storage';
|
||||
import * as PayloadService from './payload';
|
||||
|
||||
/** @TODO This is a little more involved ofc, circling back later */
|
||||
// export const createFile = async (data: Record<string, any>, query: Query) => {
|
||||
// return await ItemsService.createItem('directus_files', data, query);
|
||||
// };
|
||||
export const createFile = async (
|
||||
stream: NodeJS.ReadableStream,
|
||||
data: Record<string, any>,
|
||||
query?: Query
|
||||
) => {
|
||||
const payload = await PayloadService.processValues('create', 'directus_files', data);
|
||||
|
||||
await ItemsService.createItem('directus_files', payload, query);
|
||||
|
||||
// @todo type of stream in flydrive is wrong: https://github.com/Slynova-Org/flydrive/issues/145
|
||||
await storage.disk(data.storage).put(data.filename_disk, stream as any);
|
||||
};
|
||||
|
||||
export const readFiles = async (query: Query) => {
|
||||
return await ItemsService.readItems('directus_files', query);
|
||||
|
||||
Reference in New Issue
Block a user