@modular-rest/server 1.11.13 → 1.12.1

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.
Files changed (181) hide show
  1. package/.nvmrc +1 -0
  2. package/.prettierrc.json +9 -0
  3. package/.releaserc.json +24 -0
  4. package/README.md +79 -94
  5. package/dist/application.d.ts +29 -0
  6. package/dist/application.js +217 -0
  7. package/dist/class/cms_trigger.d.ts +61 -0
  8. package/dist/class/cms_trigger.js +47 -0
  9. package/dist/class/collection_definition.d.ts +112 -0
  10. package/dist/class/collection_definition.js +87 -0
  11. package/dist/class/combinator.d.ts +43 -0
  12. package/dist/class/combinator.js +174 -0
  13. package/dist/class/database_trigger.d.ts +84 -0
  14. package/dist/class/database_trigger.js +64 -0
  15. package/dist/class/db_schemas.d.ts +25 -0
  16. package/dist/class/db_schemas.js +28 -0
  17. package/dist/class/directory.d.ts +20 -0
  18. package/dist/class/directory.js +87 -0
  19. package/dist/class/paginator.d.ts +31 -0
  20. package/dist/class/paginator.js +43 -0
  21. package/dist/class/reply.d.ts +29 -0
  22. package/dist/class/reply.js +44 -0
  23. package/dist/class/security.d.ts +186 -0
  24. package/dist/class/security.js +178 -0
  25. package/dist/class/trigger_operator.d.ts +92 -0
  26. package/dist/class/trigger_operator.js +99 -0
  27. package/dist/class/user.d.ts +81 -0
  28. package/dist/class/user.js +151 -0
  29. package/dist/class/validator.d.ts +19 -0
  30. package/dist/class/validator.js +101 -0
  31. package/dist/config.d.ts +112 -0
  32. package/dist/config.js +26 -0
  33. package/dist/defult-permissions.d.ts +2 -0
  34. package/dist/defult-permissions.js +31 -0
  35. package/dist/events.d.ts +23 -0
  36. package/dist/events.js +47 -0
  37. package/dist/helper/data_insertion.d.ts +38 -0
  38. package/dist/helper/data_insertion.js +110 -0
  39. package/dist/helper/presetup_services.d.ts +60 -0
  40. package/dist/helper/presetup_services.js +108 -0
  41. package/dist/index.d.ts +118 -0
  42. package/dist/index.js +79 -0
  43. package/dist/middlewares.d.ts +53 -0
  44. package/dist/middlewares.js +106 -0
  45. package/dist/play-test.d.ts +1 -0
  46. package/dist/play-test.js +9 -0
  47. package/dist/services/data_provider/router.d.ts +4 -0
  48. package/dist/services/data_provider/router.js +187 -0
  49. package/dist/services/data_provider/service.d.ts +131 -0
  50. package/dist/services/data_provider/service.js +252 -0
  51. package/dist/services/data_provider/typeCasters.d.ts +9 -0
  52. package/dist/services/data_provider/typeCasters.js +18 -0
  53. package/dist/services/file/db.d.ts +1 -0
  54. package/dist/services/file/db.js +31 -0
  55. package/dist/services/file/router.d.ts +4 -0
  56. package/dist/services/file/router.js +115 -0
  57. package/dist/services/file/service.d.ts +204 -0
  58. package/dist/services/file/service.js +341 -0
  59. package/dist/services/functions/router.d.ts +4 -0
  60. package/dist/services/functions/router.js +67 -0
  61. package/dist/services/functions/service.d.ts +132 -0
  62. package/dist/services/functions/service.js +159 -0
  63. package/dist/services/jwt/router.d.ts +4 -0
  64. package/dist/services/jwt/router.js +99 -0
  65. package/dist/services/jwt/service.d.ts +97 -0
  66. package/dist/services/jwt/service.js +135 -0
  67. package/dist/services/user_manager/db.d.ts +1 -0
  68. package/dist/services/user_manager/db.js +75 -0
  69. package/dist/services/user_manager/permissionManager.d.ts +19 -0
  70. package/dist/services/user_manager/permissionManager.js +42 -0
  71. package/dist/services/user_manager/router.d.ts +4 -0
  72. package/dist/services/user_manager/router.js +195 -0
  73. package/dist/services/user_manager/service.d.ts +317 -0
  74. package/dist/services/user_manager/service.js +628 -0
  75. package/docs/.keep +0 -0
  76. package/docs/system-access-type.md +26 -0
  77. package/package.json +58 -45
  78. package/src/application.ts +206 -0
  79. package/src/class/cms_trigger.ts +68 -0
  80. package/src/class/collection_definition.ts +134 -0
  81. package/src/class/combinator.ts +176 -0
  82. package/src/class/database_trigger.ts +99 -0
  83. package/src/class/db_schemas.ts +44 -0
  84. package/src/class/{directory.js → directory.ts} +40 -18
  85. package/src/class/paginator.ts +51 -0
  86. package/src/class/reply.ts +59 -0
  87. package/src/class/security.ts +250 -0
  88. package/src/class/trigger_operator.ts +142 -0
  89. package/src/class/user.ts +199 -0
  90. package/src/class/validator.ts +123 -0
  91. package/src/config.ts +121 -0
  92. package/src/defult-permissions.ts +31 -0
  93. package/src/events.ts +59 -0
  94. package/src/helper/data_insertion.ts +94 -0
  95. package/src/helper/presetup_services.ts +96 -0
  96. package/src/index.ts +146 -0
  97. package/src/middlewares.ts +75 -0
  98. package/src/play-test.ts +8 -0
  99. package/src/services/data_provider/router.ts +191 -0
  100. package/src/services/data_provider/service.ts +305 -0
  101. package/src/services/data_provider/typeCasters.ts +15 -0
  102. package/src/services/file/db.ts +29 -0
  103. package/src/services/file/router.ts +88 -0
  104. package/src/services/file/service.ts +387 -0
  105. package/src/services/functions/router.ts +34 -0
  106. package/src/services/functions/service.ts +203 -0
  107. package/src/services/jwt/router.ts +73 -0
  108. package/src/services/jwt/service.ts +139 -0
  109. package/src/services/user_manager/db.ts +87 -0
  110. package/src/services/user_manager/permissionManager.ts +49 -0
  111. package/src/services/user_manager/router.ts +193 -0
  112. package/src/services/user_manager/service.ts +698 -0
  113. package/tsconfig.json +16 -9
  114. package/typedoc.mjs +41 -0
  115. package/LICENSE +0 -21
  116. package/package-lock.json +0 -1373
  117. package/src/application.js +0 -239
  118. package/src/class/cms_trigger.js +0 -20
  119. package/src/class/collection_definition.js +0 -33
  120. package/src/class/combinator.js +0 -133
  121. package/src/class/database_trigger.js +0 -20
  122. package/src/class/db_schemas.js +0 -18
  123. package/src/class/paginator.js +0 -31
  124. package/src/class/reply.js +0 -37
  125. package/src/class/security.js +0 -141
  126. package/src/class/trigger_operator.js +0 -39
  127. package/src/class/user.js +0 -112
  128. package/src/class/validator.js +0 -91
  129. package/src/config.js +0 -67
  130. package/src/events.js +0 -15
  131. package/src/helper/data_insertion.js +0 -64
  132. package/src/helper/presetup_services.js +0 -31
  133. package/src/index.js +0 -66
  134. package/src/middlewares.js +0 -44
  135. package/src/services/data_provider/router.js +0 -552
  136. package/src/services/data_provider/service.js +0 -262
  137. package/src/services/data_provider/typeCasters.js +0 -10
  138. package/src/services/file/db.js +0 -29
  139. package/src/services/file/router.js +0 -92
  140. package/src/services/file/service.js +0 -231
  141. package/src/services/functions/router.js +0 -37
  142. package/src/services/functions/service.js +0 -74
  143. package/src/services/jwt/router.js +0 -82
  144. package/src/services/jwt/service.js +0 -37
  145. package/src/services/user_manager/db.js +0 -83
  146. package/src/services/user_manager/permissionManager.js +0 -43
  147. package/src/services/user_manager/router.js +0 -176
  148. package/src/services/user_manager/service.js +0 -377
  149. package/types/application.d.ts +0 -97
  150. package/types/class/cms_trigger.d.ts +0 -24
  151. package/types/class/collection_definition.d.ts +0 -36
  152. package/types/class/combinator.d.ts +0 -30
  153. package/types/class/database_trigger.d.ts +0 -28
  154. package/types/class/db_schemas.d.ts +0 -2
  155. package/types/class/directory.d.ts +0 -2
  156. package/types/class/paginator.d.ts +0 -8
  157. package/types/class/reply.d.ts +0 -8
  158. package/types/class/security.d.ts +0 -109
  159. package/types/class/trigger_operator.d.ts +0 -19
  160. package/types/class/user.d.ts +0 -24
  161. package/types/class/validator.d.ts +0 -9
  162. package/types/config.d.ts +0 -101
  163. package/types/events.d.ts +0 -7
  164. package/types/helper/data_insertion.d.ts +0 -4
  165. package/types/helper/presetup_services.d.ts +0 -5
  166. package/types/index.d.ts +0 -72
  167. package/types/middlewares.d.ts +0 -10
  168. package/types/services/data_provider/router.d.ts +0 -3
  169. package/types/services/data_provider/service.d.ts +0 -40
  170. package/types/services/data_provider/typeCasters.d.ts +0 -3
  171. package/types/services/file/db.d.ts +0 -3
  172. package/types/services/file/router.d.ts +0 -3
  173. package/types/services/file/service.d.ts +0 -81
  174. package/types/services/functions/router.d.ts +0 -3
  175. package/types/services/functions/service.d.ts +0 -23
  176. package/types/services/jwt/router.d.ts +0 -3
  177. package/types/services/jwt/service.d.ts +0 -10
  178. package/types/services/user_manager/db.d.ts +0 -3
  179. package/types/services/user_manager/permissionManager.d.ts +0 -3
  180. package/types/services/user_manager/router.d.ts +0 -3
  181. package/types/services/user_manager/service.d.ts +0 -131
@@ -0,0 +1,341 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.main = exports.name = void 0;
40
+ const fs_1 = __importDefault(require("fs"));
41
+ const path_1 = __importDefault(require("path"));
42
+ const DataProvider = __importStar(require("../data_provider/service"));
43
+ const trigger_operator_1 = __importDefault(require("../../class/trigger_operator"));
44
+ const config_1 = require("../../config");
45
+ /**
46
+ * Service name constant
47
+ * @constant {string}
48
+ */
49
+ exports.name = 'file';
50
+ /**
51
+ * File service for handling file storage and retrieval.
52
+ *
53
+ * This service provides functionality for storing, retrieving, and managing files.
54
+ * It handles file storage on disk and maintains file metadata in the database.
55
+ * Files are organized by format and tag in the upload directory.
56
+ */
57
+ class FileService {
58
+ /**
59
+ * @hidden
60
+ */
61
+ constructor() {
62
+ /**
63
+ * @hidden
64
+ */
65
+ this.directory = null;
66
+ }
67
+ /**
68
+ * @hidden
69
+ *
70
+ * Sets the upload directory for file storage
71
+ * @param {string} directory - Directory path for file storage
72
+ * @throws {Error} If directory is invalid or not writable
73
+ * @example
74
+ * ```typescript
75
+ * import { fileService } from '@modular-rest/server';
76
+ *
77
+ * fileService.setUploadDirectory('/path/to/uploads');
78
+ * ```
79
+ */
80
+ setUploadDirectory(directory) {
81
+ if (!fs_1.default.existsSync(directory)) {
82
+ fs_1.default.mkdirSync(directory, { recursive: true });
83
+ }
84
+ this.directory = directory;
85
+ }
86
+ /**
87
+ * @hidden
88
+ *
89
+ * Creates stored file details with unique filename
90
+ * @param {string} fileType - MIME type of the file
91
+ * @param {string} tag - Tag for file organization
92
+ * @returns {StoredFileDetail} Storage details including filename and path
93
+ * @throws {Error} If upload directory is not set
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * import { fileService } from '@modular-rest/server';
98
+ *
99
+ * const details = fileService.createStoredDetail('image/jpeg', 'profile');
100
+ * // Returns: { fileName: '1234567890.jpeg', fullPath: '/uploads/jpeg/profile/1234567890.jpeg', fileFormat: 'jpeg' }
101
+ * ```
102
+ */
103
+ createStoredDetail(fileType, tag) {
104
+ const typeParts = fileType.split('/');
105
+ const fileFormat = typeParts[1] || typeParts[0] || 'unknown';
106
+ const time = new Date().getTime();
107
+ const fileName = `${time}.${fileFormat}`;
108
+ if (!FileService.instance.directory) {
109
+ throw new Error('Upload directory has not been set');
110
+ }
111
+ const fullPath = path_1.default.join(FileService.instance.directory, fileFormat, tag, fileName);
112
+ return { fileName, fullPath, fileFormat };
113
+ }
114
+ /**
115
+ * @hidden
116
+ *
117
+ * Stores a file, removes the temporary file, and saves metadata to database
118
+ * @param {StoreFileOptions} options - File storage options
119
+ * @returns {Promise<IFile>} Promise resolving to stored file document
120
+ * @throws {Error} If upload directory is not set or storage fails
121
+ * @example
122
+ * ```typescript
123
+ * import { fileService } from '@modular-rest/server';
124
+ *
125
+ * const file = await fileService.storeFile({
126
+ * file: {
127
+ * path: '/tmp/upload.jpg',
128
+ * type: 'image/jpeg',
129
+ * name: 'profile.jpg',
130
+ * size: 1024
131
+ * },
132
+ * ownerId: 'user123',
133
+ * tag: 'profile',
134
+ * removeFileAfterStore: true
135
+ * });
136
+ * ```
137
+ */
138
+ storeFile({ file, ownerId, tag, removeFileAfterStore = true }) {
139
+ if (!FileService.instance.directory) {
140
+ throw new Error('Upload directory has not been set');
141
+ }
142
+ let storedFile;
143
+ return new Promise(async (done, reject) => {
144
+ storedFile = FileService.instance.createStoredDetail(file.type, tag);
145
+ fs_1.default.copyFile(file.path, storedFile.fullPath, (err) => {
146
+ if (err) {
147
+ reject(err);
148
+ }
149
+ else {
150
+ done(null);
151
+ }
152
+ // remove temp file
153
+ if (removeFileAfterStore) {
154
+ fs_1.default.unlinkSync(file.path);
155
+ }
156
+ });
157
+ })
158
+ .then(() => {
159
+ // Get collection model for access to relative collection
160
+ const CollectionModel = DataProvider.getCollection('cms', 'file');
161
+ if (!CollectionModel) {
162
+ throw new Error('Collection model not found');
163
+ }
164
+ const data = {
165
+ owner: ownerId,
166
+ fileName: storedFile.fileName,
167
+ originalName: file.name,
168
+ format: storedFile.fileFormat,
169
+ tag,
170
+ size: file.size,
171
+ };
172
+ // Create new document
173
+ const doc = new CollectionModel(data);
174
+ return doc.save().then(savedDoc => {
175
+ trigger_operator_1.default.call('insert-one', 'cms', 'file', {
176
+ query: null,
177
+ queryResult: savedDoc,
178
+ });
179
+ return savedDoc;
180
+ });
181
+ })
182
+ .catch(err => {
183
+ // remove stored file
184
+ fs_1.default.unlinkSync(storedFile.fullPath);
185
+ throw err;
186
+ });
187
+ }
188
+ /**
189
+ * @hidden
190
+ *
191
+ * Removes a file from the disk
192
+ * @param {string} path - File path to remove
193
+ * @returns {Promise<void>} Promise resolving when file is removed
194
+ * @throws {Error} If file removal fails
195
+ * @example
196
+ * ```typescript
197
+ * import { fileService } from '@modular-rest/server';
198
+ *
199
+ * await fileService.removeFromDisc('/uploads/jpeg/profile/1234567890.jpeg');
200
+ * ```
201
+ */
202
+ removeFromDisc(path) {
203
+ return new Promise((done, reject) => {
204
+ fs_1.default.unlink(path, (err) => {
205
+ if (err)
206
+ reject(err);
207
+ else
208
+ done();
209
+ });
210
+ });
211
+ }
212
+ /**
213
+ * Removes a file from both database and disk
214
+ *
215
+ * @param {string} fileId - File ID to remove
216
+ * @returns {Promise<void>} Promise resolving when file is removed
217
+ * @throws {Error} If file is not found or removal fails
218
+ * @example
219
+ * ```typescript
220
+ * import { fileService } from '@modular-rest/server';
221
+ *
222
+ * try {
223
+ * await fileService.removeFile('file123');
224
+ * console.log('File removed successfully');
225
+ * } catch (error) {
226
+ * console.error('Failed to remove file:', error);
227
+ * }
228
+ * ```
229
+ */
230
+ removeFile(fileId) {
231
+ if (!FileService.instance.directory) {
232
+ throw new Error('Upload directory has not been set');
233
+ }
234
+ return new Promise(async (done, reject) => {
235
+ const CollectionModel = DataProvider.getCollection('cms', 'file');
236
+ if (!CollectionModel) {
237
+ return reject(new Error('Collection model not found'));
238
+ }
239
+ const fileDoc = await CollectionModel.findOne({ _id: fileId }).exec();
240
+ if (!fileDoc) {
241
+ return reject(new Error('File not found'));
242
+ }
243
+ await CollectionModel.deleteOne({ _id: fileId })
244
+ .exec()
245
+ .then(() => {
246
+ // create file path
247
+ const filePath = path_1.default.join(FileService.instance.directory, fileDoc.format, fileDoc.tag, fileDoc.fileName);
248
+ // Remove file from disc
249
+ return FileService.instance.removeFromDisc(filePath).catch(async (err) => {
250
+ // Recreate fileDoc if removing file operation has error
251
+ await new CollectionModel(fileDoc).save();
252
+ throw err;
253
+ });
254
+ })
255
+ .then(() => {
256
+ trigger_operator_1.default.call('remove-one', 'cms', 'file', {
257
+ query: { _id: fileId },
258
+ queryResult: null,
259
+ });
260
+ })
261
+ .then(done)
262
+ .catch(reject);
263
+ });
264
+ }
265
+ /**
266
+ * Retrieves a file document from the database
267
+ *
268
+ * @param {string} fileId - File ID to retrieve
269
+ * @returns {Promise<IFile>} Promise resolving to file document
270
+ * @throws {Error} If collection model is not found or file is not found
271
+ * @example
272
+ * ```typescript
273
+ * import { fileService } from '@modular-rest/server';
274
+ *
275
+ * const fileDoc = await fileService.getFile('file123');
276
+ * console.log('File details:', fileDoc);
277
+ * ```
278
+ */
279
+ getFile(fileId) {
280
+ const CollectionModel = DataProvider.getCollection('cms', 'file');
281
+ if (!CollectionModel) {
282
+ throw new Error('Collection model not found');
283
+ }
284
+ return CollectionModel.findOne({ _id: fileId })
285
+ .exec()
286
+ .then(doc => {
287
+ if (!doc) {
288
+ throw new Error('File not found');
289
+ }
290
+ return doc;
291
+ });
292
+ }
293
+ /**
294
+ * Retrieves the public URL link for a file
295
+ *
296
+ * @param {string} fileId - File ID to get link for
297
+ * @returns {Promise<string>} Promise resolving to file URL
298
+ * @throws {Error} If static path root is not defined or file is not found
299
+ * @example
300
+ * ```typescript
301
+ * import { fileService } from '@modular-rest/server';
302
+ *
303
+ * const link = await fileService.getFileLink('file123');
304
+ * // Returns: '/static/jpeg/profile/1234567890.jpeg'
305
+ * ```
306
+ */
307
+ async getFileLink(fileId) {
308
+ const fileDoc = await FileService.instance.getFile(fileId);
309
+ if (!config_1.config.staticPath?.actualPath) {
310
+ throw new Error('Static path root is not defined');
311
+ }
312
+ const link = config_1.config.staticPath.actualPath + `/${fileDoc.format}/${fileDoc.tag}/` + fileDoc.fileName;
313
+ return link;
314
+ }
315
+ /**
316
+ * Gets the full filesystem path for a file
317
+ *
318
+ * @param {string} fileId - File ID to get path for
319
+ * @returns {Promise<string>} Promise resolving to full file path
320
+ * @throws {Error} If upload directory is not set or file is not found
321
+ * @example
322
+ * ```typescript
323
+ * import { fileService } from '@modular-rest/server';
324
+ *
325
+ * const path = await fileService.getFilePath('file123');
326
+ * // Returns: '/uploads/jpeg/profile/1234567890.jpeg'
327
+ * ```
328
+ */
329
+ async getFilePath(fileId) {
330
+ const { fileName, format, tag } = await FileService.instance.getFile(fileId);
331
+ if (!FileService.instance.directory) {
332
+ throw new Error('Upload directory has not been set');
333
+ }
334
+ return path_1.default.join(FileService.instance.directory, format, tag, fileName);
335
+ }
336
+ }
337
+ /**
338
+ * Main file service instance
339
+ * @constant {FileService}
340
+ */
341
+ exports.main = new FileService();
@@ -0,0 +1,4 @@
1
+ import Router from 'koa-router';
2
+ declare const functionRouter: Router<any, {}>;
3
+ declare const name = "function";
4
+ export { name, functionRouter as main };
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.main = exports.name = void 0;
40
+ const koa_router_1 = __importDefault(require("koa-router"));
41
+ const service = __importStar(require("./service"));
42
+ const middleware = __importStar(require("../../middlewares"));
43
+ const validator_1 = require("../../class/validator");
44
+ const reply_1 = require("../../class/reply");
45
+ const functionRouter = new koa_router_1.default();
46
+ exports.main = functionRouter;
47
+ const name = 'function';
48
+ exports.name = name;
49
+ functionRouter.use('/', middleware.auth, async (ctx, next) => {
50
+ const body = ctx.request.body;
51
+ const bodyValidated = (0, validator_1.validateObject)(body, 'name args');
52
+ // fields validation
53
+ if (!bodyValidated.isValid) {
54
+ ctx.throw(412, JSON.stringify((0, reply_1.create)('e', { error: bodyValidated.requires })));
55
+ }
56
+ await next();
57
+ });
58
+ functionRouter.post('/run', middleware.auth, async (ctx) => {
59
+ const { name, args } = ctx.request.body;
60
+ try {
61
+ const result = await service.runFunction(name, args, ctx.state.user);
62
+ ctx.body = JSON.stringify((0, reply_1.create)('s', { data: result }));
63
+ }
64
+ catch (e) {
65
+ ctx.throw(400, JSON.stringify((0, reply_1.create)('e', { error: e.message })));
66
+ }
67
+ });
@@ -0,0 +1,132 @@
1
+ import { AccessType } from '../../class/security';
2
+ import { User } from '../../class/user';
3
+ /**
4
+ * Service name constant
5
+ * @constant {string}
6
+ */
7
+ export declare const name = "functions";
8
+ /**
9
+ * Interface for defined functions.
10
+ *
11
+ * @interface DefinedFunction
12
+ * @inline
13
+ * @example
14
+ * ```typescript
15
+ * const myFunction: DefinedFunction = {
16
+ * name: 'calculateTotal',
17
+ * permissionTypes: ['user_access'],
18
+ * callback: (args) => args.items.reduce((sum, item) => sum + item.price, 0)
19
+ * };
20
+ * ```
21
+ */
22
+ export interface DefinedFunction {
23
+ /**
24
+ * Unique name of the function
25
+ * @type {string}
26
+ */
27
+ name: string;
28
+ /**
29
+ * List of permission types required to run the function
30
+ * @type {AccessType[]}
31
+ */
32
+ permissionTypes: AccessType[];
33
+ /**
34
+ * The actual function implementation
35
+ * @type {(args: any) => any}
36
+ */
37
+ callback: (args: any) => any;
38
+ }
39
+ /**
40
+ * To define a function you need to create a `functions.[js|ts]` in each module of your app and return am array called `functions`, and then define all your functions with calling the `defineFunction` method.
41
+ *
42
+ * The `defineFunction` method serves as a core utility for creating custom functions dynamically. This method allows you to specify various parameters, including the name of the function, the permissions required for access, and the corresponding logic that should be executed when the function is invoked.
43
+ *
44
+ * @summary
45
+ * Define a server function to be called by clients.
46
+ *
47
+ * @param {DefinedFunction} options - The function definition options. See {@link DefinedFunction} for detailed parameter descriptions.
48
+ * @expandType DefinedFunction
49
+ *
50
+ * @returns {Object} The defined function object which system will use to generate a router for the function, generall the client library will use the router to call the function.
51
+ * @throws {Error} If function name already exists, permission types are missing, or callback is invalid
52
+ *
53
+ * @example
54
+ * Here is an example illustrating how to use the `defineFunction` method effectively:
55
+ * ```typescript
56
+ * // /modules/myModule/functions.ts
57
+ *
58
+ * import { defineFunction } from "@modular-rest/server";
59
+ *
60
+ * const getServerTime = defineFunction({
61
+ * name: "getServerTime",
62
+ * permissionTypes: ["anonymous_access"],
63
+ * callback: (params) => {
64
+ * // return your data only
65
+ * return `
66
+ * Welcome, ${params.username}!
67
+ * The current server time is ${new Date().toLocaleString()}.
68
+ * `;
69
+ *
70
+ * // error handling,
71
+ * // client gets error code 400, and the message
72
+ * // throw new Error('An error occurred');
73
+ * },
74
+ * });
75
+ *
76
+ * module.exports.functions = [getServerTime];
77
+ * ```
78
+ * In this example, we define a function named `getServerTime` that requires the `user` permission type to access. When the function is called, it will return a message containing the current server time and the username of the user who invoked the function.
79
+ *
80
+ * ---
81
+ *
82
+ * By utilizing the `defineFunction` method, developers are empowered to create custom functionality effortlessly within the Modular REST framework, enhancing both the versatility and security of their applications.
83
+ */
84
+ export declare function defineFunction(options: DefinedFunction): DefinedFunction;
85
+ /**
86
+ * Runs a function by name with arguments and user context
87
+ *
88
+ * @param {string} name - Name of the function to run
89
+ * @param {any} args - Arguments to pass to the function
90
+ * @param {User} user - User attempting to run the function
91
+ * @returns {Promise<any>} Promise resolving to function result
92
+ * @throws {Error} If function not found or user lacks required permissions
93
+ *
94
+ * @private
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * try {
99
+ * const result = await runFunction('calculateTotal', {
100
+ * items: [
101
+ * { price: 10 },
102
+ * { price: 20 }
103
+ * ]
104
+ * }, currentUser);
105
+ * console.log('Total:', result); // 30
106
+ * } catch (error) {
107
+ * console.error('Function execution failed:', error);
108
+ * }
109
+ * ```
110
+ */
111
+ export declare function runFunction(name: string, args: any, user: User): Promise<any>;
112
+ /**
113
+ * Adds a function to the registry, this method is used for internal use only,
114
+ * it will add all defined functions to the registry.
115
+ *
116
+ * @param {DefinedFunction} func - Function to add
117
+ * @throws {Error} If function name already exists
118
+ *
119
+ * @private
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * const myFunction = defineFunction({
124
+ * name: 'myFunction',
125
+ * permissionTypes: ['user_access'],
126
+ * callback: (args) => args.value * 2
127
+ * });
128
+ *
129
+ * addFunction(myFunction);
130
+ * ```
131
+ */
132
+ export declare function addFunction(func: DefinedFunction): void;