@modular-rest/server 1.11.4 → 1.11.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
- const fs = require('file-system');
2
- const pathModule = require('path');
3
- const DataProvider = require('./../data_provider/service')
1
+ const fs = require("file-system");
2
+ const pathModule = require("path");
3
+ const DataProvider = require("./../data_provider/service");
4
+ const triggerService = require("./../../class/trigger_operator");
5
+ const { config } = require("./../../config");
4
6
 
5
7
  class FileService {
6
-
7
8
  constructor() {
8
9
  this.directory = null;
9
10
  }
@@ -13,9 +14,10 @@ class FileService {
13
14
  }
14
15
 
15
16
  /**
16
- *
17
- * @param {string} fileType
18
- *
17
+ *
18
+ * @param {string} fileType
19
+ * @param {string} tag
20
+ *
19
21
  * @returns storedFile
20
22
  * @returns storedFile.fileName
21
23
  * @returns storedFile.directory
@@ -23,119 +25,207 @@ class FileService {
23
25
  * @returns storedFile.fileFormat
24
26
  */
25
27
  createStoredDetail(fileType, tag) {
28
+ const typeParts = fileType.split("/");
29
+ const fileFormat = typeParts[1] || typeParts[0] || "unknown";
30
+
31
+ const time = new Date().getTime();
32
+ const fileName = `${time}.${fileFormat}`;
26
33
 
27
- let time = new Date().getTime();
28
- let fileFormat = fileType.split('/')[1];
29
- let fileName = `${time}.${fileFormat}`;
30
- let fullPath = pathModule.join(this.directory, fileFormat, tag, fileName);
34
+ const fullPath = pathModule.join(
35
+ FileService.instance.directory,
36
+ fileFormat,
37
+ tag,
38
+ fileName
39
+ );
31
40
 
32
41
  return { fileName, fullPath, fileFormat };
33
42
  }
34
43
 
35
-
36
44
  /**
37
- *
38
- * @param args
39
- * @param {file} args.file file object
40
- * @param {string} args.ownerId file object
45
+ * Stores a file, removes the given temporary file, and submits file details into the database.
46
+ *
47
+ * @param {Object} options - The options for storing the file.
48
+ * @param {Object} options.file - The file to be stored.
49
+ * @param {string} options.file.path - The path of the file.
50
+ * @param {string} options.file.type - The type of the file.
51
+ * @param {string} options.file.name - The original name of the file.
52
+ * @param {number} options.file.size - The size of the file.
53
+ * @param {string} options.ownerId - The ID of the owner of the file.
54
+ * @param {string} options.tag - The tag associated with the file.
55
+ * @param {boolean} [options.removeFileAfterStore=true] - Whether to remove the file after storing it.
56
+ *
57
+ * @returns {Promise} A promise that resolves with the document of the stored file.
58
+ *
59
+ * @throws {string} If the upload directory has not been set.
41
60
  */
42
- storeFile({ file, ownerId, tag }) {
43
-
44
- if (!this.directory)
45
- throw 'upload directory has not been set.'
61
+ storeFile({ file, ownerId, tag, removeFileAfterStore = true }) {
62
+ if (!FileService.instance.directory)
63
+ throw "upload directory has not been set.";
46
64
 
47
65
  let storedFile;
48
66
 
49
- return new Promise(async (done, reject) =>
50
- /**
51
- * Store file and remove temp file
52
- */ {
53
-
54
- storedFile = this.createStoredDetail(file.type, tag);
67
+ return (
68
+ new Promise(async (done, reject) => /**
69
+ * Store file and remove temp file
70
+ */ {
71
+ storedFile = FileService.instance.createStoredDetail(file.type, tag);
55
72
 
56
- fs.copyFile(file.path, storedFile.fullPath, {
57
- done: (err) => {
58
- if (err) reject(err);
59
- else done();
73
+ fs.copyFile(file.path, storedFile.fullPath, {
74
+ done: (err) => {
75
+ if (err) reject(err);
76
+ else done();
60
77
 
61
- // remove temp file
62
- fs.fs.unlinkSync(file.path);
63
- }
64
- });
65
- })
66
- /**
67
- * Submit file detail into database
68
- */
69
- .then(() => {
70
-
71
- // Get collection model for access to relative collection
72
- let CollectionModel = DataProvider.getCollection('cms', 'file');
73
-
74
- // Create new document
75
- let doc = new CollectionModel({
76
- owner: ownerId,
77
- fileName: storedFile.fileName,
78
- originalName: file.name,
79
- format: storedFile.fileFormat,
80
- tag,
78
+ // remove temp file
79
+ if (removeFileAfterStore) fs.fs.unlinkSync(file.path);
80
+ },
81
81
  });
82
-
83
- return doc.save().then(() => doc);
84
-
85
- }).catch(err => {
86
-
87
- // remove stored file
88
- fs.fs.unlinkSync(storedFile.fullPath);
89
-
90
- throw err;
91
82
  })
83
+ /**
84
+ * Submit file detail into database
85
+ */
86
+ .then(() => {
87
+ // Get collection model for access to relative collection
88
+ const CollectionModel = DataProvider.getCollection("cms", "file");
89
+
90
+ const data = {
91
+ owner: ownerId,
92
+ fileName: storedFile.fileName,
93
+ originalName: file.name,
94
+ format: storedFile.fileFormat,
95
+ tag,
96
+ size: file.size,
97
+ };
98
+
99
+ // Create new document
100
+ const doc = new CollectionModel(data);
101
+
102
+ return doc.save().then((savedDoc) => {
103
+ triggerService.call("insert-one", "cms", "file", {
104
+ query: null,
105
+ queryResult: savedDoc,
106
+ });
107
+
108
+ return savedDoc;
109
+ });
110
+ })
111
+ .catch((err) => {
112
+ // remove stored file
113
+ fs.fs.unlinkSync(storedFile.fullPath);
114
+
115
+ throw err;
116
+ })
117
+ );
92
118
  }
93
119
 
120
+ /**
121
+ * Removes a file from the disk.
122
+ *
123
+ * @param {string} path - The path of the file to be removed.
124
+ * @returns {Promise} A promise that resolves if the file is successfully removed, and rejects if an error occurs.
125
+ */
94
126
  removeFromDisc(path) {
95
127
  return new Promise((done, reject) => {
96
128
  fs.fs.unlink(path, (err) => {
97
- if (err) reject()
98
- else done()
129
+ if (err) reject();
130
+ else done();
99
131
  });
100
- })
132
+ });
101
133
  }
102
134
 
135
+ /**
136
+ * Removes a file from the database and the disk.
137
+ *
138
+ * @param {string} fileId - The ID of the file to be removed.
139
+ * @returns {Promise} A promise that resolves if the file is successfully removed, and rejects if an error occurs.
140
+ * @throws Will throw an error if upload directory has not been set.
141
+ */
103
142
  removeFile(fileId) {
104
-
105
- if (!this.directory)
106
- throw 'upload directory has not been set.'
143
+ if (!FileService.instance.directory)
144
+ throw "upload directory has not been set.";
107
145
 
108
146
  return new Promise(async (done, reject) => {
109
- let CollectionModel = DataProvider.getCollection('cms', 'file');
147
+ let CollectionModel = DataProvider.getCollection("cms", "file");
110
148
  let fileDoc = await CollectionModel.findOne({ _id: fileId }).exec();
111
149
 
112
150
  if (!fileDoc) {
113
- reject('file not found');
151
+ reject("file not found");
114
152
  return;
115
153
  }
116
154
 
117
- await CollectionModel.deleteOne({ _id: fileId }).exec()
155
+ await CollectionModel.deleteOne({ _id: fileId })
156
+ .exec()
118
157
  .then(() => {
119
-
120
158
  // create file path
121
- let filePath = pathModule.join(this.directory, fileDoc.format, fileDoc.tag, fileDoc.fileName);
159
+ const filePath = pathModule.join(
160
+ FileService.instance.directory,
161
+ fileDoc.format,
162
+ fileDoc.tag,
163
+ fileDoc.fileName
164
+ );
122
165
 
123
166
  // Remove file from disc
124
- return this.removeFromDisc(filePath)
167
+ return FileService.instance
168
+ .removeFromDisc(filePath)
125
169
  .catch(async (err) => {
126
-
127
- // Recreate fileDoc if removing file operation has error
170
+ // Recreate fileDoc if removing file operation has error
128
171
  await new CollectionModel(fileDoc).save();
129
172
 
130
173
  throw err;
131
- })
132
-
174
+ });
175
+ })
176
+ .then(() => {
177
+ triggerService.call("remove-one", "cms", "file", {
178
+ query: { _id: fileId },
179
+ queryResult: null,
180
+ });
133
181
  })
134
182
  .then(done)
135
- .catch(reject)
136
- })
183
+ .catch(reject);
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Retrieves a file from the database.
189
+ *
190
+ * @param {string} fileId - The ID of the file to be retrieved.
191
+ * @returns {Promise} A promise that resolves with the file document, or rejects if an error occurs.
192
+ */
193
+ getFile(fileId) {
194
+ const CollectionModel = DataProvider.getCollection("cms", "file");
195
+
196
+ return CollectionModel.findOne({ _id: fileId }).exec();
197
+ }
198
+
199
+ /**
200
+ * Retrieves the link of a file.
201
+ *
202
+ * @param {string} fileId - The ID of the file to get the link for.
203
+ * @returns {Promise} A promise that resolves with the file link, or rejects if an error occurs.
204
+ */
205
+ async getFileLink(fileId) {
206
+ const fileDoc = await FileService.instance.getFile(fileId);
207
+
208
+ const link =
209
+ config.staticPath.rootPath +
210
+ `/${fileDoc.format}/${fileDoc.tag}/` +
211
+ fileDoc.fileName;
212
+
213
+ return link;
214
+ }
215
+
216
+ async getFilePath(fileId) {
217
+ const { fileName, format, tag } = await FileService.instance.getFile(
218
+ fileId
219
+ );
220
+ const fullPath = pathModule.join(
221
+ FileService.instance.directory,
222
+ format,
223
+ tag,
224
+ fileName
225
+ );
226
+ return fullPath;
137
227
  }
138
228
  }
139
229
 
140
- FileService.instance = new FileService()
141
- module.exports = FileService.instance;
230
+ FileService.instance = new FileService();
231
+ module.exports = FileService.instance;
@@ -13,7 +13,10 @@ functionRouter.use("/", middleware.auth, async (ctx, next) => {
13
13
 
14
14
  // fields validation
15
15
  if (!bodyValidated.isValid) {
16
- ctx.throw(412, JSON.stringify(reply("e", { e: bodyValidated.requires })));
16
+ ctx.throw(
17
+ 412,
18
+ JSON.stringify(reply("e", { error: bodyValidated.requires }))
19
+ );
17
20
  }
18
21
 
19
22
  await next();
@@ -26,7 +29,7 @@ functionRouter.post(`/run`, middleware.auth, async (ctx) => {
26
29
  const result = await service.runFunction(name, args, ctx.state.user);
27
30
  ctx.body = JSON.stringify(reply("s", { data: result }));
28
31
  } catch (e) {
29
- ctx.throw(400, JSON.stringify(reply("e", { e: e.message })));
32
+ ctx.throw(400, JSON.stringify(reply("e", { error: e.message })));
30
33
  }
31
34
  });
32
35
 
@@ -14,18 +14,21 @@ class UserManager {
14
14
  }
15
15
 
16
16
  /**
17
- * Set a custom method for generating verification codes.
18
- * @param {function} method - A method that returns a random verification code.
17
+ * Sets a custom method for generating verification codes.
18
+ *
19
+ * @param {Function} generatorMethod - A function that returns a random verification code.
20
+ * @returns {void}
19
21
  */
20
- setCustomVerificationCodeGeneratorMethod(method) {
21
- this.verificationCodeGeneratorMethod = method;
22
+ setCustomVerificationCodeGeneratorMethod(generatorMethod) {
23
+ this.verificationCodeGeneratorMethod = generatorMethod;
22
24
  }
23
25
 
24
26
  /**
25
- * Generate a verification code.
26
- * @param {string} id - The ID for which to generate the verification code.
27
- * @param {string} idType - The type of the ID.
28
- * @returns {string} The generated verification code.
27
+ * Get a user by their ID.
28
+ *
29
+ * @param {string} id - The ID of the user.
30
+ * @returns {Promise<User>} A promise that resolves to the user.
31
+ * @throws {Error} If the user is not found.
29
32
  */
30
33
  generateVerificationCode(id, idType) {
31
34
  if (this.verificationCodeGeneratorMethod)
@@ -37,6 +40,7 @@ class UserManager {
37
40
 
38
41
  /**
39
42
  * Get a user by their ID.
43
+ *
40
44
  * @param {string} id - The ID of the user.
41
45
  * @returns {Promise<User>} A promise that resolves to the user.
42
46
  * @throws {string} If the user is not found.
@@ -63,6 +67,7 @@ class UserManager {
63
67
 
64
68
  /**
65
69
  * Get a user by their identity.
70
+ *
66
71
  * @param {string} id - The identity of the user.
67
72
  * @param {string} idType - The type of the identity (phone or email).
68
73
  * @returns {Promise<User>} A promise that resolves to the user.
@@ -95,6 +100,7 @@ class UserManager {
95
100
 
96
101
  /**
97
102
  * Get a user by their token.
103
+ *
98
104
  * @param {string} token - The token of the user.
99
105
  * @returns {Promise<User>} A promise that resolves to the user.
100
106
  */
@@ -105,6 +111,7 @@ class UserManager {
105
111
 
106
112
  /**
107
113
  * Check if a verification code is valid.
114
+ *
108
115
  * @param {string} id - The ID of the user.
109
116
  * @param {string} code - The verification code.
110
117
  * @returns {boolean} Whether the verification code is valid.
@@ -123,6 +130,7 @@ class UserManager {
123
130
 
124
131
  /**
125
132
  * Login a user and return their token.
133
+ *
126
134
  * @param {string} id - The ID of the user.
127
135
  * @param {string} idType - The type of the ID (phone or email).
128
136
  * @param {string} password - The password of the user.
@@ -172,6 +180,7 @@ class UserManager {
172
180
 
173
181
  /**
174
182
  * Issue a token for a user.
183
+ *
175
184
  * @param {string} email - The email of the user.
176
185
  * @returns {Promise<string>} A promise that resolves to the token of the user.
177
186
  * @throws {string} If the user is not found.
@@ -199,6 +208,7 @@ class UserManager {
199
208
 
200
209
  /**
201
210
  * Login as an anonymous user.
211
+ *
202
212
  * @returns {Promise<string>} A promise that resolves to the token of the anonymous user.
203
213
  * @throws {string} If the anonymous user is not found.
204
214
  */
@@ -245,6 +255,7 @@ class UserManager {
245
255
 
246
256
  /**
247
257
  * Register a temporary ID.
258
+ *
248
259
  * @param {string} id - The ID to register.
249
260
  * @param {string} type - The type of the ID.
250
261
  * @param {string} code - The verification code.
@@ -255,6 +266,7 @@ class UserManager {
255
266
 
256
267
  /**
257
268
  * Submit a password for a temporary ID.
269
+ *
258
270
  * @param {string} id - The ID.
259
271
  * @param {string} password - The password.
260
272
  * @param {string} code - The verification code.
@@ -285,6 +297,7 @@ class UserManager {
285
297
 
286
298
  /**
287
299
  * Change the password for a temporary ID.
300
+ *
288
301
  * @param {string} id - The ID.
289
302
  * @param {string} password - The new password.
290
303
  * @param {string} code - The verification code.
@@ -310,6 +323,7 @@ class UserManager {
310
323
 
311
324
  /**
312
325
  * Register a user.
326
+ *
313
327
  * @param {Object} detail - The details of the user.
314
328
  * @returns {Promise<string>} A promise that resolves to the ID of the new user.
315
329
  * @throws {string} If the user could not be registered.
@@ -342,6 +356,7 @@ class UserManager {
342
356
 
343
357
  /**
344
358
  * Change the password of a user.
359
+ *
345
360
  * @param {Object} query - The query to find the user.
346
361
  * @param {string} newPass - The new password.
347
362
  * @returns {Promise<void>} A promise that resolves when the operation is complete.