@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.
- package/.nvmrc +1 -0
- package/.prettierrc.json +9 -0
- package/.releaserc.json +24 -0
- package/README.md +79 -94
- package/dist/application.d.ts +29 -0
- package/dist/application.js +217 -0
- package/dist/class/cms_trigger.d.ts +61 -0
- package/dist/class/cms_trigger.js +47 -0
- package/dist/class/collection_definition.d.ts +112 -0
- package/dist/class/collection_definition.js +87 -0
- package/dist/class/combinator.d.ts +43 -0
- package/dist/class/combinator.js +174 -0
- package/dist/class/database_trigger.d.ts +84 -0
- package/dist/class/database_trigger.js +64 -0
- package/dist/class/db_schemas.d.ts +25 -0
- package/dist/class/db_schemas.js +28 -0
- package/dist/class/directory.d.ts +20 -0
- package/dist/class/directory.js +87 -0
- package/dist/class/paginator.d.ts +31 -0
- package/dist/class/paginator.js +43 -0
- package/dist/class/reply.d.ts +29 -0
- package/dist/class/reply.js +44 -0
- package/dist/class/security.d.ts +186 -0
- package/dist/class/security.js +178 -0
- package/dist/class/trigger_operator.d.ts +92 -0
- package/dist/class/trigger_operator.js +99 -0
- package/dist/class/user.d.ts +81 -0
- package/dist/class/user.js +151 -0
- package/dist/class/validator.d.ts +19 -0
- package/dist/class/validator.js +101 -0
- package/dist/config.d.ts +112 -0
- package/dist/config.js +26 -0
- package/dist/defult-permissions.d.ts +2 -0
- package/dist/defult-permissions.js +31 -0
- package/dist/events.d.ts +23 -0
- package/dist/events.js +47 -0
- package/dist/helper/data_insertion.d.ts +38 -0
- package/dist/helper/data_insertion.js +110 -0
- package/dist/helper/presetup_services.d.ts +60 -0
- package/dist/helper/presetup_services.js +108 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +79 -0
- package/dist/middlewares.d.ts +53 -0
- package/dist/middlewares.js +106 -0
- package/dist/play-test.d.ts +1 -0
- package/dist/play-test.js +9 -0
- package/dist/services/data_provider/router.d.ts +4 -0
- package/dist/services/data_provider/router.js +187 -0
- package/dist/services/data_provider/service.d.ts +131 -0
- package/dist/services/data_provider/service.js +252 -0
- package/dist/services/data_provider/typeCasters.d.ts +9 -0
- package/dist/services/data_provider/typeCasters.js +18 -0
- package/dist/services/file/db.d.ts +1 -0
- package/dist/services/file/db.js +31 -0
- package/dist/services/file/router.d.ts +4 -0
- package/dist/services/file/router.js +115 -0
- package/dist/services/file/service.d.ts +204 -0
- package/dist/services/file/service.js +341 -0
- package/dist/services/functions/router.d.ts +4 -0
- package/dist/services/functions/router.js +67 -0
- package/dist/services/functions/service.d.ts +132 -0
- package/dist/services/functions/service.js +159 -0
- package/dist/services/jwt/router.d.ts +4 -0
- package/dist/services/jwt/router.js +99 -0
- package/dist/services/jwt/service.d.ts +97 -0
- package/dist/services/jwt/service.js +135 -0
- package/dist/services/user_manager/db.d.ts +1 -0
- package/dist/services/user_manager/db.js +75 -0
- package/dist/services/user_manager/permissionManager.d.ts +19 -0
- package/dist/services/user_manager/permissionManager.js +42 -0
- package/dist/services/user_manager/router.d.ts +4 -0
- package/dist/services/user_manager/router.js +195 -0
- package/dist/services/user_manager/service.d.ts +317 -0
- package/dist/services/user_manager/service.js +628 -0
- package/docs/.keep +0 -0
- package/docs/system-access-type.md +26 -0
- package/package.json +58 -45
- package/src/application.ts +206 -0
- package/src/class/cms_trigger.ts +68 -0
- package/src/class/collection_definition.ts +134 -0
- package/src/class/combinator.ts +176 -0
- package/src/class/database_trigger.ts +99 -0
- package/src/class/db_schemas.ts +44 -0
- package/src/class/{directory.js → directory.ts} +40 -18
- package/src/class/paginator.ts +51 -0
- package/src/class/reply.ts +59 -0
- package/src/class/security.ts +250 -0
- package/src/class/trigger_operator.ts +142 -0
- package/src/class/user.ts +199 -0
- package/src/class/validator.ts +123 -0
- package/src/config.ts +121 -0
- package/src/defult-permissions.ts +31 -0
- package/src/events.ts +59 -0
- package/src/helper/data_insertion.ts +94 -0
- package/src/helper/presetup_services.ts +96 -0
- package/src/index.ts +146 -0
- package/src/middlewares.ts +75 -0
- package/src/play-test.ts +8 -0
- package/src/services/data_provider/router.ts +191 -0
- package/src/services/data_provider/service.ts +305 -0
- package/src/services/data_provider/typeCasters.ts +15 -0
- package/src/services/file/db.ts +29 -0
- package/src/services/file/router.ts +88 -0
- package/src/services/file/service.ts +387 -0
- package/src/services/functions/router.ts +34 -0
- package/src/services/functions/service.ts +203 -0
- package/src/services/jwt/router.ts +73 -0
- package/src/services/jwt/service.ts +139 -0
- package/src/services/user_manager/db.ts +87 -0
- package/src/services/user_manager/permissionManager.ts +49 -0
- package/src/services/user_manager/router.ts +193 -0
- package/src/services/user_manager/service.ts +698 -0
- package/tsconfig.json +16 -9
- package/typedoc.mjs +41 -0
- package/LICENSE +0 -21
- package/package-lock.json +0 -1373
- package/src/application.js +0 -239
- package/src/class/cms_trigger.js +0 -20
- package/src/class/collection_definition.js +0 -33
- package/src/class/combinator.js +0 -133
- package/src/class/database_trigger.js +0 -20
- package/src/class/db_schemas.js +0 -18
- package/src/class/paginator.js +0 -31
- package/src/class/reply.js +0 -37
- package/src/class/security.js +0 -141
- package/src/class/trigger_operator.js +0 -39
- package/src/class/user.js +0 -112
- package/src/class/validator.js +0 -91
- package/src/config.js +0 -67
- package/src/events.js +0 -15
- package/src/helper/data_insertion.js +0 -64
- package/src/helper/presetup_services.js +0 -31
- package/src/index.js +0 -66
- package/src/middlewares.js +0 -44
- package/src/services/data_provider/router.js +0 -552
- package/src/services/data_provider/service.js +0 -262
- package/src/services/data_provider/typeCasters.js +0 -10
- package/src/services/file/db.js +0 -29
- package/src/services/file/router.js +0 -92
- package/src/services/file/service.js +0 -231
- package/src/services/functions/router.js +0 -37
- package/src/services/functions/service.js +0 -74
- package/src/services/jwt/router.js +0 -82
- package/src/services/jwt/service.js +0 -37
- package/src/services/user_manager/db.js +0 -83
- package/src/services/user_manager/permissionManager.js +0 -43
- package/src/services/user_manager/router.js +0 -176
- package/src/services/user_manager/service.js +0 -377
- package/types/application.d.ts +0 -97
- package/types/class/cms_trigger.d.ts +0 -24
- package/types/class/collection_definition.d.ts +0 -36
- package/types/class/combinator.d.ts +0 -30
- package/types/class/database_trigger.d.ts +0 -28
- package/types/class/db_schemas.d.ts +0 -2
- package/types/class/directory.d.ts +0 -2
- package/types/class/paginator.d.ts +0 -8
- package/types/class/reply.d.ts +0 -8
- package/types/class/security.d.ts +0 -109
- package/types/class/trigger_operator.d.ts +0 -19
- package/types/class/user.d.ts +0 -24
- package/types/class/validator.d.ts +0 -9
- package/types/config.d.ts +0 -101
- package/types/events.d.ts +0 -7
- package/types/helper/data_insertion.d.ts +0 -4
- package/types/helper/presetup_services.d.ts +0 -5
- package/types/index.d.ts +0 -72
- package/types/middlewares.d.ts +0 -10
- package/types/services/data_provider/router.d.ts +0 -3
- package/types/services/data_provider/service.d.ts +0 -40
- package/types/services/data_provider/typeCasters.d.ts +0 -3
- package/types/services/file/db.d.ts +0 -3
- package/types/services/file/router.d.ts +0 -3
- package/types/services/file/service.d.ts +0 -81
- package/types/services/functions/router.d.ts +0 -3
- package/types/services/functions/service.d.ts +0 -23
- package/types/services/jwt/router.d.ts +0 -3
- package/types/services/jwt/service.d.ts +0 -10
- package/types/services/user_manager/db.d.ts +0 -3
- package/types/services/user_manager/permissionManager.d.ts +0 -3
- package/types/services/user_manager/router.d.ts +0 -3
- 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,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;
|