@modular-rest/server 1.11.12 → 1.12.0

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 -70
  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 -9
  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,305 @@
1
+ import mongoose, { Connection, Model, PopulateOptions, Query } from 'mongoose';
2
+ import { AccessTypes, AccessDefinition } from '../../class/security';
3
+ import triggerOperator from '../../class/trigger_operator';
4
+ import TypeCasters from './typeCasters';
5
+ import { config } from '../../config';
6
+ import { CollectionDefinition } from '../../class/collection_definition';
7
+ import { User } from '../../class/user';
8
+
9
+ /**
10
+ * Service name constant
11
+ * @constant {string}
12
+ */
13
+ export const name = 'dataProvider';
14
+
15
+ // Set mongoose options
16
+ mongoose.set('useCreateIndex', true);
17
+
18
+ // Database connections and collections storage
19
+ const connections: Record<string, Connection> = {};
20
+ const collections: Record<string, Record<string, Model<any>>> = {};
21
+ const permissionDefinitions: Record<string, Record<string, AccessDefinition>> = {};
22
+
23
+ /**
24
+ * MongoDB connection options
25
+ * @interface MongoOption
26
+ * @property {string} [dbPrefix] - Prefix for database names
27
+ * @property {string} mongoBaseAddress - MongoDB connection URL
28
+ */
29
+ export interface MongoOption {
30
+ dbPrefix?: string;
31
+ mongoBaseAddress: string;
32
+ }
33
+
34
+ /**
35
+ * Collection definition options
36
+ * @interface CollectionDefinitionOption
37
+ * @property {CollectionDefinition[]} list - List of collection definitions
38
+ * @property {MongoOption} mongoOption - MongoDB connection options
39
+ */
40
+ interface CollectionDefinitionListOption {
41
+ list: CollectionDefinition[];
42
+ mongoOption: MongoOption;
43
+ }
44
+
45
+ /**
46
+ * Connects to a database and sets up collections based on collection definitions
47
+ * @function connectToDatabaseByCollectionDefinitionList
48
+ * @param {string} dbName - Name of the database to connect to
49
+ * @param {CollectionDefinition[]} [collectionDefinitionList=[]] - List of collection definitions
50
+ * @param {MongoOption} mongoOption - MongoDB connection options
51
+ * @returns {Promise<void>} A promise that resolves when the connection is established
52
+ * @throws {Error} If triggers are not properly configured
53
+ * @private
54
+ */
55
+ function connectToDatabaseByCollectionDefinitionList(
56
+ dbName: string,
57
+ collectionDefinitionList: CollectionDefinition[] = [],
58
+ mongoOption: MongoOption
59
+ ): Promise<void> {
60
+ return new Promise((done, reject) => {
61
+ // Create db connection
62
+ const fullDbName = (mongoOption.dbPrefix || '') + dbName;
63
+ const connectionString = mongoOption.mongoBaseAddress;
64
+
65
+ console.info(`- Connecting to database: ${fullDbName}`);
66
+
67
+ const connection = mongoose.createConnection(connectionString, {
68
+ useUnifiedTopology: true,
69
+ useNewUrlParser: true,
70
+ dbName: fullDbName,
71
+ });
72
+
73
+ // Store connection
74
+ connections[dbName] = connection;
75
+
76
+ // add db models from schemas
77
+ collectionDefinitionList.forEach(collectionDefinition => {
78
+ const collection = collectionDefinition.collection;
79
+ const schema = collectionDefinition.schema;
80
+
81
+ if (collections[dbName] == undefined) collections[dbName] = {};
82
+
83
+ if (permissionDefinitions[dbName] == undefined) permissionDefinitions[dbName] = {};
84
+
85
+ // create model from schema
86
+ // and store in on global collection object
87
+ const model = connection.model(collection, schema);
88
+ collections[dbName][collection] = model;
89
+
90
+ // define Access Definition from component permissions
91
+ // and store it on global access definition object
92
+ permissionDefinitions[dbName][collection] = new AccessDefinition({
93
+ database: dbName,
94
+ collection: collection,
95
+ permissionList: collectionDefinition.permissions,
96
+ });
97
+
98
+ // add trigger
99
+ if (collectionDefinition.triggers != undefined) {
100
+ if (!Array.isArray(collectionDefinition.triggers)) {
101
+ throw new Error('Triggers must be an array');
102
+ }
103
+
104
+ collectionDefinition.triggers.forEach(trigger => {
105
+ triggerOperator.addTrigger({
106
+ ...trigger,
107
+ database: collectionDefinition.database,
108
+ collection: collectionDefinition.collection,
109
+ });
110
+ });
111
+ }
112
+ });
113
+
114
+ connection.on('connected', () => {
115
+ console.info(`- ${fullDbName} database has been connected`);
116
+ done();
117
+ });
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Adds collection definitions and connects to their respective databases
123
+ * @function addCollectionDefinitionByList
124
+ * @param {CollectionDefinitionListOption} options - Collection definition options
125
+ * @returns {Promise<void>} A promise that resolves when all collections are set up
126
+ * @example
127
+ * ```typescript
128
+ * await addCollectionDefinitionByList({
129
+ * list: [
130
+ * new CollectionDefinition({
131
+ * database: 'myapp',
132
+ * collection: 'users',
133
+ * schema: userSchema,
134
+ * permissions: [new Permission({ type: 'user_access', read: true })]
135
+ * })
136
+ * ],
137
+ * mongoOption: {
138
+ * mongoBaseAddress: 'mongodb://localhost:27017',
139
+ * dbPrefix: 'myapp_'
140
+ * }
141
+ * });
142
+ * ```
143
+ */
144
+ export async function addCollectionDefinitionByList({
145
+ list,
146
+ mongoOption,
147
+ }: CollectionDefinitionListOption): Promise<void> {
148
+ // Group collection definitions by database
149
+ const dbGroups: Record<string, CollectionDefinition[]> = {};
150
+ list.forEach(collectionDefinition => {
151
+ if (!dbGroups[collectionDefinition.database]) {
152
+ dbGroups[collectionDefinition.database] = [];
153
+ }
154
+ dbGroups[collectionDefinition.database].push(collectionDefinition);
155
+ });
156
+
157
+ // Connect to each database
158
+ const connectionPromises = Object.entries(dbGroups).map(([dbName, collectionDefinitionList]) =>
159
+ connectToDatabaseByCollectionDefinitionList(dbName, collectionDefinitionList, mongoOption)
160
+ );
161
+
162
+ await Promise.all(connectionPromises);
163
+ }
164
+
165
+ /**
166
+ * Gets a Mongoose model for a specific collection
167
+ * @function getCollection
168
+ * @param {string} db - Database name
169
+ * @param {string} collection - Collection name
170
+ * @returns {Model<T>} Mongoose model for the collection
171
+ * @throws {Error} If the collection doesn't exist
172
+ * @example
173
+ * ```typescript
174
+ * const userModel = getCollection('myapp', 'users');
175
+ * const users = await userModel.find();
176
+ * ```
177
+ */
178
+ export function getCollection<T>(db: string, collection: string): Model<T> {
179
+ if (!collections[db] || !collections[db][collection]) {
180
+ throw new Error(`Collection ${collection} not found in database ${db}`);
181
+ }
182
+ return collections[db][collection];
183
+ }
184
+
185
+ /**
186
+ * Gets the permission list for a specific operation on a collection
187
+ * @function _getPermissionList
188
+ * @param {string} db - Database name
189
+ * @param {string} collection - Collection name
190
+ * @param {string} operationType - Type of operation (read/write)
191
+ * @returns {any[]} List of permissions
192
+ * @private
193
+ */
194
+ function _getPermissionList(db: string, collection: string, operationType: string): any[] {
195
+ if (!permissionDefinitions[db] || !permissionDefinitions[db][collection]) {
196
+ return [];
197
+ }
198
+ return permissionDefinitions[db][collection].permissionList;
199
+ }
200
+
201
+ /**
202
+ * Checks if a user has access to perform an operation on a collection
203
+ * @function checkAccess
204
+ * @param {string} db - Database name
205
+ * @param {string} collection - Collection name
206
+ * @param {string} operationType - Type of operation (read/write)
207
+ * @param {Record<string, any>} queryOrDoc - Query or document being accessed
208
+ * @param {User} user - User performing the operation
209
+ * @returns {boolean} Whether the user has access
210
+ * @example
211
+ * ```typescript
212
+ * const hasAccess = checkAccess('myapp', 'users', 'read', {}, currentUser);
213
+ * if (hasAccess) {
214
+ * const users = await getCollection('myapp', 'users').find();
215
+ * }
216
+ * ```
217
+ */
218
+ export function checkAccess(
219
+ db: string,
220
+ collection: string,
221
+ operationType: string,
222
+ queryOrDoc: Record<string, any>,
223
+ user: User
224
+ ): boolean {
225
+ const permissionList = _getPermissionList(db, collection, operationType);
226
+ return permissionList.some(permission => {
227
+ if (permission.type === 'god_access') return true;
228
+ if (permission.type === 'anonymous_access' && user.type === 'anonymous') return true;
229
+ if (permission.type === 'user_access' && user.type === 'user') return true;
230
+ return false;
231
+ });
232
+ }
233
+
234
+ /**
235
+ * Converts a string ID to a MongoDB ObjectId
236
+ * @function getAsID
237
+ * @param {string} strId - String ID to convert
238
+ * @returns {mongoose.Types.ObjectId | undefined} MongoDB ObjectId or undefined if invalid
239
+ * @example
240
+ * ```typescript
241
+ * const id = getAsID('507f1f77bcf86cd799439011');
242
+ * if (id) {
243
+ * const doc = await collection.findById(id);
244
+ * }
245
+ * ```
246
+ */
247
+ export function getAsID(strId: string): mongoose.Types.ObjectId | undefined {
248
+ try {
249
+ return mongoose.Types.ObjectId(strId);
250
+ } catch (e) {
251
+ return undefined;
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Applies populate options to a Mongoose query
257
+ * @function performPopulateToQueryObject
258
+ * @param {Query<T, any>} queryObj - Mongoose query object
259
+ * @param {PopulateOptions[]} [popArr=[]] - Array of populate options
260
+ * @returns {Query<T, any>} Query with populate options applied
261
+ * @example
262
+ * ```typescript
263
+ * const query = collection.find();
264
+ * const populatedQuery = performPopulateToQueryObject(query, [
265
+ * { path: 'author', select: 'name email' }
266
+ * ]);
267
+ * ```
268
+ */
269
+ export function performPopulateToQueryObject<T = any>(
270
+ queryObj: Query<T, any>,
271
+ popArr: PopulateOptions[] = []
272
+ ): Query<T, any> {
273
+ popArr.forEach(pop => {
274
+ queryObj.populate(pop);
275
+ });
276
+ return queryObj;
277
+ }
278
+
279
+ /**
280
+ * Applies additional options to a Mongoose query
281
+ * @function performAdditionalOptionsToQueryObject
282
+ * @param {Query<T, any>} queryObj - Mongoose query object
283
+ * @param {Record<string, any>} options - Additional query options
284
+ * @returns {Query<T, any>} Query with additional options applied
285
+ * @example
286
+ * ```typescript
287
+ * const query = collection.find();
288
+ * const queryWithOptions = performAdditionalOptionsToQueryObject(query, {
289
+ * sort: { createdAt: -1 },
290
+ * limit: 10
291
+ * });
292
+ * ```
293
+ */
294
+ export function performAdditionalOptionsToQueryObject<T = any>(
295
+ queryObj: Query<T, any>,
296
+ options: Record<string, any>
297
+ ): Query<T, any> {
298
+ Object.entries(options).forEach(([key, value]) => {
299
+ // @ts-ignore
300
+ queryObj[key](value);
301
+ });
302
+ return queryObj;
303
+ }
304
+
305
+ export { TypeCasters };
@@ -0,0 +1,15 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ /**
4
+ * Type casting functions for MongoDB types
5
+ */
6
+ const TypeCasters = {
7
+ ObjectId: mongoose.Types.ObjectId,
8
+ Date: (dateValue: string | Date): Date => {
9
+ const strDate = dateValue.toString();
10
+ const mongoDateFormateInString = new Date(strDate).toISOString().split('T')[0];
11
+ return new Date(mongoDateFormateInString);
12
+ },
13
+ };
14
+
15
+ export default TypeCasters;
@@ -0,0 +1,29 @@
1
+ import mongoose from 'mongoose';
2
+ import schemas from '../../class/db_schemas';
3
+ import { CollectionDefinition } from '../../class/collection_definition';
4
+ import { Permission, PermissionTypes } from '../../class/security';
5
+ import { config } from '../../config';
6
+ import { Schema } from 'mongoose';
7
+
8
+ module.exports = [
9
+ new CollectionDefinition({
10
+ database: 'cms',
11
+ collection: 'file',
12
+ schema: schemas.file as unknown as Schema,
13
+ permissions: [
14
+ new Permission({
15
+ accessType: PermissionTypes.upload_file_access,
16
+ read: true,
17
+ write: true,
18
+ onlyOwnData: false,
19
+ }),
20
+ new Permission({
21
+ accessType: PermissionTypes.remove_file_access,
22
+ read: true,
23
+ write: true,
24
+ onlyOwnData: false,
25
+ }),
26
+ ],
27
+ triggers: config.fileTriggers || [],
28
+ }),
29
+ ];
@@ -0,0 +1,88 @@
1
+ import Router from 'koa-router';
2
+ import { validateObject } from '../../class/validator';
3
+ import { create as reply } from '../../class/reply';
4
+ import { Context, Next } from 'koa';
5
+ import { AccessTypes } from './../../class/security';
6
+ import * as DataService from './../data_provider/service';
7
+ import { main as service } from './service';
8
+ import * as middleware from '../../middlewares';
9
+
10
+ const name = 'file';
11
+ const fileRouter = new Router();
12
+
13
+ fileRouter.use('/', middleware.auth, async (ctx: Context, next: Next) => {
14
+ await next();
15
+ });
16
+
17
+ fileRouter.post('/', async (ctx: Context) => {
18
+ const body = ctx.request.body;
19
+
20
+ // validate result
21
+ const bodyValidate = validateObject(body, 'tag');
22
+
23
+ // fields validation
24
+ if (!bodyValidate.isValid) {
25
+ ctx.status = 412;
26
+ ctx.body = reply('e', { e: bodyValidate.requires });
27
+ return;
28
+ }
29
+
30
+ // Access validation
31
+ const hasAccess = DataService.checkAccess('cms', 'file', AccessTypes.write, body, ctx.state.user);
32
+ if (!hasAccess) {
33
+ ctx.throw(403, 'access denied');
34
+ return;
35
+ }
36
+
37
+ const files = ctx.request.files;
38
+ const file = files && files.file;
39
+ let result;
40
+
41
+ if (!file) {
42
+ ctx.status = 412;
43
+ result = reply('f', { message: 'file field required' });
44
+ } else {
45
+ await service
46
+ .storeFile({
47
+ file: file as any,
48
+ ownerId: ctx.state.user.id,
49
+ tag: body.tag,
50
+ })
51
+ .then(file => {
52
+ result = reply('s', { file });
53
+ })
54
+ .catch(error => {
55
+ ctx.status = 412;
56
+ result = reply('e', error);
57
+ });
58
+ }
59
+
60
+ ctx.body = result;
61
+ });
62
+
63
+ fileRouter.delete('/', async (ctx: Context) => {
64
+ const body = ctx.request.query;
65
+ // validate
66
+ const bodyValidate = validateObject(body as Record<string, any>, 'id');
67
+
68
+ let result;
69
+
70
+ if (!bodyValidate.isValid) {
71
+ ctx.status = 412;
72
+ result = reply('f', { message: 'some fields required.', error: bodyValidate.requires });
73
+ } else {
74
+ await service
75
+ .removeFile(body.id as string)
76
+ .then(() => {
77
+ result = reply('s');
78
+ })
79
+ .catch(e => {
80
+ ctx.status = 412;
81
+ result = reply('e', { error: e });
82
+ });
83
+ }
84
+
85
+ ctx.body = result;
86
+ });
87
+
88
+ export { name, fileRouter as main };