|
- const fs = require('fs-extra');
- const debug = require('debug')('server-connect:upload');
- const { join, basename, extname } = require('path');
- const { toAppPath, toSystemPath, toSiteUrl, parseTemplate, getUniqFile } = require('../core/path');
- const diacritics = require('../core/diacritics');
-
- module.exports = {
-
- upload: async function(options) {
- let self = this;
- let fields = this.parse(options.fields || this.parse('{{$_POST}}'));
- let path = this.parseOptional(options.path, 'string', '/uploads');
- let overwrite = this.parseOptional(options.overwrite, 'boolean', false);
- let createPath = this.parseOptional(options.createPath, 'boolean', true);
- let throwErrors = this.parseOptional(options.throwErrors, 'boolean', false);
- let template = typeof options.template == 'string' ? options.template : false; //this.parseOptional(options.template, 'string', '');
- let replaceSpace = this.parseOptional(options.replaceSpace, 'boolean', false);
- let asciiOnly = this.parseOptional(options.asciiOnly, 'boolean', false);
- let replaceDiacritics = this.parseOptional(options.replaceDiacritics, 'boolean', false);
-
- if (throwErrors) {
- for (let field in this.req.files) {
- if (Array.isArray(this.req.files[field])) {
- for (let file of this.req.files[field]) {
- if (file.truncated) {
- throw new Error('Some files failed to upload.');
- }
- }
- } else {
- let file = this.req.files[field];
- if (file.truncated) {
- throw new Error('Some files failed to upload.');
- }
- }
- }
- }
-
- path = toSystemPath(path);
-
- if (!fs.existsSync(path)) {
- if (createPath) {
- await fs.ensureDir(path);
- } else {
- throw new Error(`Upload path doesn't exist.`);
- }
- }
-
- let files = this.req.files;
- let uploaded = [];
-
- if (files) {
- await processFields(fields);
- }
-
- return typeof fields == 'string' ? (uploaded.length ? uploaded[0] : null) : uploaded;
-
- async function processFields(fields) {
- debug('Process fields: %O', fields);
-
- if (typeof fields == 'object') {
- for (let i in fields) {
- await processFields(fields[i]);
- }
- } else if (typeof fields == 'string' && files[fields]) {
- let processing = files[fields];
-
- if (!Array.isArray(processing)) processing = [processing];
-
- for (let file of processing) {
- debug('Processing file: %O', file);
-
- if (!file.processed) {
- let name = file.name.replace(/[\x00-\x1f\x7f!%&#@$*()?:,;"'<>^`|+={}\[\]\\\/]/g, '');
-
- if (replaceSpace) name = name.replace(/\s+/g, '_');
- if (replaceDiacritics) name = diacritics.replace(name);
- if (asciiOnly) name = name.replace(/[^\x00-\x7e]/g, '');
-
- let filepath = join(path, name);
-
- if (template) {
- let _template = self.parse(template, self.scope.create({
- file: basename(filepath),
- name: basename(filepath, extname(filepath)),
- ext: extname(filepath)
- }));
- filepath = parseTemplate(filepath, _template);
- }
-
- if (fs.existsSync(filepath)) {
- if (overwrite) {
- await fs.unlink(filepath);
- } else {
- filepath = getUniqFile(filepath);
- }
- }
-
- await file.mv(filepath);
-
- uploaded.push({
- name: basename(filepath),
- path: toAppPath(filepath),
- url: toSiteUrl(filepath),
- type: file.mimetype,
- size: file.size
- });
-
- file.processed = true;
- }
- }
- }
-
- return uploaded;
- }
-
- }
-
- };
|