1 | /*
|
2 | * Copyright (c) 2018 One Hill Technologies, LLC
|
3 | *
|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | * you may not use this file except in compliance with the License.
|
6 | * You may obtain a copy of the License at
|
7 | *
|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
9 | *
|
10 | * Unless required by applicable law or agreed to in writing, software
|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 | * See the License for the specific language governing permissions and
|
14 | * limitations under the License.
|
15 | */
|
16 |
|
17 | const multer = require ('multer');
|
18 | const Action = require ('./action');
|
19 | const framework = require ('./-framework');
|
20 | const { resolve } = require ('path');
|
21 | const { merge, get } = require ('lodash');
|
22 | const { computed } = require ('base-object');
|
23 | const { ensureDirSync } = require ('fs-extra');
|
24 |
|
25 | /**
|
26 | * @class UploadAction
|
27 | *
|
28 | * Base class for all upload actions. This action will initialize a new instance
|
29 | * of multer, and store it internally for subclasses to use.
|
30 | */
|
31 | module.exports = Action.extend ({
|
32 | /// The default upload path for all files. This will default to [appPath]/uploads,
|
33 | /// if nothing is provided.
|
34 | uploadPath: null,
|
35 |
|
36 | /// The other options for multer.
|
37 | uploadOptions: null,
|
38 |
|
39 | _middleware: null,
|
40 |
|
41 | storageType: computed ({
|
42 | get () { return this._options.dest ? 'disk' : 'memory'; }
|
43 | }),
|
44 |
|
45 | init () {
|
46 | this._super.call (this, ...arguments);
|
47 |
|
48 | if (!this.uploadPath)
|
49 | this.uploadPath = resolve (framework.app.tempPath, 'uploads');
|
50 |
|
51 | let baseOptions = {};
|
52 | let storage = get (this.uploadOptions, 'storage');
|
53 |
|
54 | if (!storage) {
|
55 | // Configure the upload path, and make sure the directory exists.
|
56 | baseOptions.dest = this.uploadPath;
|
57 | ensureDirSync (this.uploadPath);
|
58 | }
|
59 |
|
60 | this._options = merge (baseOptions, this.uploadOptions);
|
61 | this._upload = multer (this._options);
|
62 | },
|
63 |
|
64 | /**
|
65 | * Execute the action.
|
66 | *
|
67 | * @param req The request object.
|
68 | * @param res The response object.
|
69 | */
|
70 | execute (req, res) {
|
71 | return this._uploadFile (req, res).then (() => this.onUploadComplete (req, res));
|
72 | },
|
73 |
|
74 | /**
|
75 | * Upload the file.
|
76 | *
|
77 | * @param req The request object.
|
78 | * @param res The response object.
|
79 | */
|
80 | _uploadFile (req, res) {
|
81 | return new Promise ((resolve,reject) => {
|
82 | this._middleware (req, res, err => {
|
83 | return !err ? resolve () : reject (err);
|
84 | })
|
85 | });
|
86 | },
|
87 |
|
88 | /**
|
89 | * Notify the subclass the upload is complete.
|
90 | *
|
91 | * @param req The request object.
|
92 | * @param res The response object.
|
93 | * @returns {null}
|
94 | */
|
95 | onUploadComplete (req, res) {
|
96 | return null;
|
97 | }
|
98 | });
|