mirror of
https://github.com/codex-team/codex.docs.git
synced 2025-07-30 18:49:42 +02:00
Transport controller and file model (#42)
* Transport controller and file model * Use randomBytes intead of pseudoRandomBytes * Cover all lines with tests * Update code style * Update code style * View for image block * Fix serving static files * Mkdir -p for uploads dirs * Add default secret param * Add image Tool * Update src/utils/objects.js Co-Authored-By: talyguryn <vitalik7tv@yandex.ru> * Use vars for image tool colors * Revert var * Remove --color-gray-border var * Update src/controllers/transport.js Co-Authored-By: talyguryn <vitalik7tv@yandex.ru> * Add mp4 support for Image Tool
This commit is contained in:
parent
82a81ce96a
commit
404fb4642e
34 changed files with 1135 additions and 41 deletions
119
src/controllers/transport.js
Normal file
119
src/controllers/transport.js
Normal file
|
@ -0,0 +1,119 @@
|
|||
const fileType = require('file-type');
|
||||
const fetch = require('node-fetch');
|
||||
const fs = require('fs');
|
||||
const nodePath = require('path');
|
||||
|
||||
const Model = require('../models/file');
|
||||
const { random16 } = require('../utils/crypto');
|
||||
const { deepMerge } = require('../utils/objects');
|
||||
const config = require('../../config');
|
||||
|
||||
/**
|
||||
* @class Transport
|
||||
* @classdesc Transport controller
|
||||
*
|
||||
* Allows to save files from client or fetch them by URL
|
||||
*/
|
||||
class Transport {
|
||||
/**
|
||||
* Saves file passed from client
|
||||
* @param {object} multerData - file data from multer
|
||||
* @param {string} multerData.originalname - original name of the file
|
||||
* @param {string} multerData.filename - name of the uploaded file
|
||||
* @param {string} multerData.path - path to the uploaded file
|
||||
* @param {number} multerData.size - size of the uploaded file
|
||||
* @param {string} multerData.mimetype - MIME type of the uploaded file
|
||||
*
|
||||
* @param {object} map - object that represents how should fields of File object should be mapped to response
|
||||
* @return {Promise<FileData>}
|
||||
*/
|
||||
static async save(multerData, map) {
|
||||
const { originalname: name, path, filename, size, mimetype } = multerData;
|
||||
|
||||
const file = new Model({ name, filename, path, size, mimetype });
|
||||
|
||||
await file.save();
|
||||
|
||||
let response = file.data;
|
||||
|
||||
if (map) {
|
||||
response = Transport.composeResponse(file, map);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches file by passed URL
|
||||
* @param {string} url - URL of the file
|
||||
* @param {object} map - object that represents how should fields of File object should be mapped to response
|
||||
* @return {Promise<FileData>}
|
||||
*/
|
||||
static async fetch(url, map) {
|
||||
const fetchedFile = await fetch(url);
|
||||
const buffer = await fetchedFile.buffer();
|
||||
const filename = await random16();
|
||||
|
||||
const type = fileType(buffer);
|
||||
const ext = type ? type.ext : nodePath.extname(url).slice(1);
|
||||
|
||||
fs.writeFileSync(`${config.uploads}/${filename}.${ext}`, buffer);
|
||||
|
||||
const file = new Model({
|
||||
name: url,
|
||||
filename: `${filename}.${ext}`,
|
||||
path: `${config.uploads}/${filename}.${ext}`,
|
||||
size: buffer.length,
|
||||
mimetype: type ? type.mime : fetchedFile.headers.get('content-type')
|
||||
});
|
||||
|
||||
await file.save();
|
||||
|
||||
let response = file.data;
|
||||
|
||||
if (map) {
|
||||
response = Transport.composeResponse(file, map);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map fields of File object to response by provided map object
|
||||
*
|
||||
* @param {File} file
|
||||
* @param {object} map - object that represents how should fields of File object should be mapped to response
|
||||
*
|
||||
*/
|
||||
static composeResponse(file, map) {
|
||||
const response = {};
|
||||
const { data } = file;
|
||||
|
||||
Object.entries(map).forEach(([name, path]) => {
|
||||
const fields = path.split(':');
|
||||
|
||||
if (fields.length > 1) {
|
||||
let object = {};
|
||||
let result = object;
|
||||
|
||||
fields.forEach((field, i) => {
|
||||
if (i === fields.length - 1) {
|
||||
object[field] = data[name];
|
||||
return;
|
||||
}
|
||||
|
||||
object[field] = {};
|
||||
object = object[field];
|
||||
});
|
||||
|
||||
deepMerge(response, result);
|
||||
} else {
|
||||
response[fields[0]] = data[name];
|
||||
}
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transport;
|
Loading…
Add table
Add a link
Reference in a new issue