@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,142 @@
1
+ import { DatabaseOperation } from './database_trigger';
2
+
3
+ /**
4
+ * Interface defining a database trigger
5
+ * @interface Trigger
6
+ * @property {DatabaseOperation} operation - The database operation that triggers this callback
7
+ * @property {string} database - The database name to monitor
8
+ * @property {string} collection - The collection name to monitor
9
+ * @property {(data: any) => void} callback - Function to execute when trigger conditions are met
10
+ * @example
11
+ * ```typescript
12
+ * const trigger: Trigger = {
13
+ * operation: 'insert',
14
+ * database: 'myDB',
15
+ * collection: 'users',
16
+ * callback: (data) => {
17
+ * console.log('New user inserted:', data);
18
+ * }
19
+ * };
20
+ * ```
21
+ */
22
+ interface Trigger {
23
+ operation: DatabaseOperation;
24
+ database: string;
25
+ collection: string;
26
+ callback: (data: any) => void;
27
+ }
28
+
29
+ /**
30
+ * Singleton class for managing database triggers
31
+ * Provides functionality to add and execute triggers based on database operations
32
+ * @class TriggerOperator
33
+ * @example
34
+ * ```typescript
35
+ * // Add a trigger for user insertions
36
+ * TriggerOperator.instance.addTrigger({
37
+ * operation: 'insert',
38
+ * database: 'myDB',
39
+ * collection: 'users',
40
+ * callback: (data) => {
41
+ * console.log('New user inserted:', data);
42
+ * }
43
+ * });
44
+ * ```
45
+ */
46
+ class TriggerOperator {
47
+ private triggers: Trigger[] = [];
48
+ private static _instance: TriggerOperator | null = null;
49
+
50
+ private constructor() {}
51
+
52
+ /**
53
+ * Gets the singleton instance of TriggerOperator
54
+ * @static
55
+ * @returns {TriggerOperator} The singleton instance
56
+ */
57
+ static get instance(): TriggerOperator {
58
+ if (!TriggerOperator._instance) {
59
+ TriggerOperator._instance = new TriggerOperator();
60
+ }
61
+ return TriggerOperator._instance;
62
+ }
63
+
64
+ /**
65
+ * Adds a new trigger to the registry
66
+ * @param {Trigger} trigger - The trigger configuration to add
67
+ * @throws {Error} If trigger is invalid or already exists
68
+ * @example
69
+ * ```typescript
70
+ * // Add a trigger for document updates
71
+ * TriggerOperator.instance.addTrigger({
72
+ * operation: 'update',
73
+ * database: 'myDB',
74
+ * collection: 'documents',
75
+ * callback: (data) => {
76
+ * console.log('Document updated:', data);
77
+ * }
78
+ * });
79
+ * ```
80
+ */
81
+ addTrigger(trigger: Trigger): void {
82
+ // Validate trigger
83
+ if (!trigger.operation || !trigger.database || !trigger.collection || !trigger.callback) {
84
+ throw new Error('Invalid trigger configuration');
85
+ }
86
+
87
+ // Check for duplicate triggers
88
+ const exists = this.triggers.some(
89
+ t =>
90
+ t.operation === trigger.operation &&
91
+ t.database === trigger.database &&
92
+ t.collection === trigger.collection
93
+ );
94
+
95
+ if (exists) {
96
+ throw new Error(
97
+ `Trigger already exists for operation ${trigger.operation} on ${trigger.database}.${trigger.collection}`
98
+ );
99
+ }
100
+
101
+ this.triggers.push(trigger);
102
+ }
103
+
104
+ /**
105
+ * Executes all matching triggers for a given database operation
106
+ * @param {DatabaseOperation} operation - The database operation that occurred
107
+ * @param {string} database - The database where the operation occurred
108
+ * @param {string} collection - The collection where the operation occurred
109
+ * @param {any} data - The data associated with the operation
110
+ * @example
111
+ * ```typescript
112
+ * // This would typically be called by the database layer
113
+ * TriggerOperator.instance.call(
114
+ * 'insert',
115
+ * 'myDB',
116
+ * 'users',
117
+ * { id: 1, name: 'John' }
118
+ * );
119
+ * ```
120
+ */
121
+ call(operation: DatabaseOperation, database: string, collection: string, data: any): void {
122
+ this.triggers.forEach(trigger => {
123
+ if (
124
+ operation === trigger.operation &&
125
+ database === trigger.database &&
126
+ collection === trigger.collection &&
127
+ trigger.callback
128
+ ) {
129
+ try {
130
+ trigger.callback(data);
131
+ } catch (error) {
132
+ console.error(
133
+ `Error executing trigger for ${operation} on ${database}.${collection}:`,
134
+ error
135
+ );
136
+ }
137
+ }
138
+ });
139
+ }
140
+ }
141
+
142
+ export = TriggerOperator.instance;
@@ -0,0 +1,199 @@
1
+ import { config } from '../config';
2
+ import { PermissionGroup, AccessType } from './security';
3
+ import { validator as validateObject } from './validator';
4
+ import { Document, Model } from 'mongoose';
5
+
6
+ /**
7
+ * User detail interface
8
+ */
9
+ interface UserDetail {
10
+ permissionGroup?: string | PermissionGroup;
11
+ phone?: string;
12
+ email?: string;
13
+ password?: string;
14
+ fullname?: string;
15
+ type?: string;
16
+ [key: string]: any;
17
+ }
18
+
19
+ /**
20
+ * User class representing a user in the system
21
+ *
22
+ * @public
23
+ */
24
+ export class User {
25
+ id: string;
26
+ permissionGroup: string;
27
+ phone: string;
28
+ email: string;
29
+ password: string;
30
+ type: string;
31
+ dbModel: any;
32
+
33
+ /**
34
+ * Create a user
35
+ * @param id - User ID
36
+ * @param permissionGroup - Permission group name
37
+ * @param phone - User phone
38
+ * @param email - User email
39
+ * @param password - User password
40
+ * @param type - User type
41
+ * @param model - Database model
42
+ *
43
+ * @hidden
44
+ */
45
+ constructor(
46
+ id: string,
47
+ permissionGroup: string,
48
+ phone: string,
49
+ email: string,
50
+ password: string,
51
+ type: string,
52
+ model: any
53
+ ) {
54
+ this.id = id;
55
+ this.permissionGroup = permissionGroup;
56
+ this.email = email;
57
+ this.phone = phone;
58
+ this.password = password;
59
+ this.type = type;
60
+ this.dbModel = model;
61
+ }
62
+
63
+ /**
64
+ * Get brief user information
65
+ * @returns Brief user info object
66
+ */
67
+ getBrief(): UserDetail {
68
+ const permissionGroup = config.permissionGroups?.find(
69
+ group => group.title === this.permissionGroup
70
+ );
71
+
72
+ if (!permissionGroup) {
73
+ throw new Error('Permission group not found on user object');
74
+ }
75
+
76
+ const brief: UserDetail = {
77
+ id: this.id,
78
+ permissionGroup: permissionGroup,
79
+ phone: this.phone,
80
+ email: this.email,
81
+ type: this.type,
82
+ };
83
+
84
+ return brief;
85
+ }
86
+
87
+ /**
88
+ * Update user details
89
+ * @param detail - Object containing user details to update
90
+ */
91
+ setNewDetail(detail: UserDetail): void {
92
+ if (detail.phone) this.phone = detail.phone;
93
+ if (detail.email) this.email = detail.email;
94
+ if (detail.password) this.password = detail.password;
95
+ }
96
+
97
+ /**
98
+ * Check if user has a specific permission
99
+ * @param accessType - Permission to check
100
+ * @returns True if user has permission, false otherwise
101
+ */
102
+ hasPermission(accessType: string): boolean {
103
+ const permissionGroup = config.permissionGroups?.find(
104
+ group => group.title === this.permissionGroup
105
+ );
106
+
107
+ if (permissionGroup == null) return false;
108
+
109
+ let key = false;
110
+
111
+ if (permissionGroup.allowedAccessTypes) {
112
+ for (let i = 0; i < permissionGroup.allowedAccessTypes.length; i++) {
113
+ const userPermissionType = permissionGroup.allowedAccessTypes[i];
114
+
115
+ if (userPermissionType === accessType) {
116
+ key = true;
117
+ break;
118
+ }
119
+ }
120
+ }
121
+
122
+ return key;
123
+ }
124
+
125
+ /**
126
+ * Save user to database
127
+ */
128
+ async save(): Promise<void> {
129
+ if (!this.dbModel) {
130
+ throw new Error('User model is not initialized');
131
+ }
132
+
133
+ this.dbModel['permissionGroup'] = this.permissionGroup;
134
+ this.dbModel['phone'] = this.phone;
135
+ this.dbModel['email'] = this.email;
136
+ this.dbModel['password'] = this.password;
137
+
138
+ await this.dbModel.save();
139
+ }
140
+
141
+ /**
142
+ * Load user from database model
143
+ * @param model - Database model
144
+ * @returns Promise resolving to User instance
145
+ */
146
+ static loadFromModel(model: any): Promise<User> {
147
+ return new Promise((done, reject) => {
148
+ // check required fields
149
+ const isValidData = validateObject(model, 'fullname email password permission');
150
+
151
+ if (!isValidData.isValid) {
152
+ return reject(User.notValid(model));
153
+ }
154
+
155
+ const id = model.id;
156
+ const permissionGroup = model.permissionGroup;
157
+ const phone = model.phone;
158
+ const email = model.email;
159
+ const password = model.password;
160
+ const type = model.type;
161
+
162
+ //create user
163
+ const newUser = new User(id, permissionGroup, phone, email, password, type, model);
164
+ done(newUser);
165
+ });
166
+ }
167
+
168
+ /**
169
+ * Create user from model and details
170
+ * @param model - Mongoose model
171
+ * @param detail - User details
172
+ * @returns Promise resolving to User instance
173
+ */
174
+ static createFromModel(model: Model<any>, detail: UserDetail): Promise<User> {
175
+ return new Promise(async (done, reject) => {
176
+ //create user
177
+ try {
178
+ const newUserDoc = await new model(detail).save();
179
+ const newUser = await User.loadFromModel(newUserDoc);
180
+ done(newUser);
181
+ } catch (error) {
182
+ reject(error);
183
+ }
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Create error for invalid user
189
+ * @param object - Invalid user object
190
+ * @returns Error message
191
+ */
192
+ static notValid(object: any): string {
193
+ const error = `user detail are not valid ${JSON.stringify(object)}`;
194
+ console.error(error);
195
+ return error;
196
+ }
197
+ }
198
+
199
+ export default User;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Validation result interface
3
+ */
4
+ export interface ValidationResult {
5
+ isValid: boolean;
6
+ requires: string[];
7
+ }
8
+
9
+ /**
10
+ * Validates an object by checking if it contains all the required fields.
11
+ * @param obj - The object to be validated.
12
+ * @param requiredFields - The list of required fields. If it's a string, it should contain keys separated by spaces. If it's an object, it should contain key-value pairs where the key is the field name and the value is a boolean indicating whether the field is required or not.
13
+ * @returns Returns a ValidationResult object with validation status and missing fields.
14
+ * @throws Throws an error if the requiredFields parameter is not a string or an object.
15
+ */
16
+ export function validator(
17
+ obj: Record<string, any> | null,
18
+ requiredFields: string | Record<string, string>
19
+ ): ValidationResult {
20
+ /*
21
+ this method could validate an Object by given field's name list and return bool.
22
+ - requiredFields: is a string that contains keys being spared by " ".
23
+ */
24
+ const type = typeof requiredFields;
25
+ let result: ValidationResult;
26
+
27
+ if (type === 'string') result = checkSimple(obj, requiredFields as string);
28
+ else if (type === 'object') result = checkComplex(obj, requiredFields as Record<string, string>);
29
+ else throw 'requiredFields has wrong form, it must be string or object';
30
+
31
+ return result;
32
+ }
33
+
34
+ /**
35
+ * Check simple validation with space-separated string of keys
36
+ */
37
+ function checkSimple(
38
+ obj: Record<string, any> | null,
39
+ requiredFields: string = ''
40
+ ): ValidationResult {
41
+ let isValid = false;
42
+ const requires = requiredFields.split(' ');
43
+
44
+ const validMembers = [];
45
+ const notValidKeys = [];
46
+
47
+ // return if obj is null
48
+ if (obj == null) return _returnResult(isValid, requires);
49
+
50
+ // Filter empty strings that might result from extra spaces
51
+ const requiredKeys = requires.filter(key => key !== '');
52
+
53
+ for (const key of requiredKeys) {
54
+ if (obj[key] !== undefined && obj[key] !== null) validMembers.push(key);
55
+ else notValidKeys.push(key);
56
+ }
57
+
58
+ // check validation
59
+ isValid = requiredKeys.length === validMembers.length;
60
+ return _returnResult(isValid, notValidKeys);
61
+ }
62
+
63
+ /**
64
+ * Check complex validation with object containing expected values
65
+ */
66
+ function checkComplex(
67
+ obj: Record<string, any> | null,
68
+ requiredFields: Record<string, string> = {}
69
+ ): ValidationResult {
70
+ let isValid = false;
71
+ const requireKeys = Object.keys(requiredFields);
72
+
73
+ let validMembers = 0;
74
+ const notValidKeys: string[] = [];
75
+
76
+ // return if obj is null
77
+ if (obj == null) return _returnResult(isValid, requireKeys);
78
+
79
+ for (let i = 0; i < requireKeys.length; i++) {
80
+ const key = requireKeys[i];
81
+ let isValidField = false;
82
+
83
+ // if field has specific values
84
+ if (requiredFields[key].length > 0) {
85
+ const expectedValues = requiredFields[key].split(' ');
86
+
87
+ if (typeof expectedValues !== 'object') throw `${key} must be array of strings`;
88
+
89
+ for (const value of expectedValues) {
90
+ if (obj[key] === value) {
91
+ isValidField = true;
92
+ break;
93
+ }
94
+ }
95
+ }
96
+ // else does not have specific value
97
+ else if (obj[key] != null) {
98
+ isValidField = true;
99
+ }
100
+
101
+ if (isValidField) validMembers++;
102
+ else notValidKeys.push(key);
103
+ }
104
+
105
+ // check validation
106
+ isValid = requireKeys.length === validMembers;
107
+ return _returnResult(isValid, notValidKeys);
108
+ }
109
+
110
+ /**
111
+ * Create a validation result object
112
+ */
113
+ function _returnResult(isValid: boolean, notValidKeys: string[]): ValidationResult {
114
+ return {
115
+ isValid: isValid,
116
+ requires: notValidKeys,
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Return the validator function to maintain compatibility with the JavaScript version
122
+ */
123
+ export const validateObject = validator;
package/src/config.ts ADDED
@@ -0,0 +1,121 @@
1
+ import Koa from 'koa';
2
+
3
+ import { CollectionDefinition } from './class/collection_definition';
4
+ import { PermissionGroup } from './class/security';
5
+ import { CmsTrigger } from './class/cms_trigger';
6
+ import { DefinedFunction } from './services/functions/service';
7
+ import cors from '@koa/cors';
8
+ import { Options as KoaStaticOptionsBase } from 'koa-static';
9
+
10
+ export interface StaticPathOptions extends KoaStaticOptionsBase {
11
+ /**
12
+ * The actual path of the static files on your server
13
+ */
14
+ actualPath: string;
15
+ /**
16
+ * The path you want to serve the static files from
17
+ */
18
+ path: string;
19
+ }
20
+
21
+ /**
22
+ * JWT keypair configuration
23
+ * @interface KeyPair
24
+ * @property {string} private - Private key for JWT signing
25
+ * @property {string} public - Public key for JWT verification
26
+ */
27
+ interface KeyPair {
28
+ private: string;
29
+ public: string;
30
+ }
31
+
32
+ /**
33
+ * MongoDB connection options
34
+ * @interface MongoOptions
35
+ * @property {string} dbPrefix - Prefix for database names
36
+ * @property {string} mongoBaseAddress - MongoDB connection URL
37
+ * @property {string} [addressMap] - Optional address mapping configuration
38
+ */
39
+ interface MongoOptions {
40
+ dbPrefix: string;
41
+ mongoBaseAddress: string;
42
+ addressMap?: string;
43
+ }
44
+
45
+ /**
46
+ * Admin user configuration
47
+ * @interface AdminUser
48
+ * @property {string} email - Admin user email
49
+ * @property {string} password - Admin user password
50
+ */
51
+ interface AdminUser {
52
+ email: string;
53
+ password: string;
54
+ }
55
+
56
+ /**
57
+ * Configuration options for creating a REST API instance
58
+ * @interface RestOptions
59
+ * @property {cors.Options} [cors] - CORS configuration options
60
+ * @property {string} [modulesPath] - Path to custom modules directory
61
+ * @property {string} [uploadDirectory] - Directory for file uploads
62
+ * @property {any} [koaBodyOptions] - Options for koa-body middleware
63
+ * @property {StaticPathOptions} [staticPath] - Static file serving options
64
+ * @property {Function} [onBeforeInit] - Hook called before initialization
65
+ * @property {Function} [onAfterInit] - Hook called after initialization
66
+ * @property {number} [port] - Port to listen on
67
+ * @property {boolean} [dontListen] - Don't start the server
68
+ * @property {MongoOptions} [mongo] - MongoDB connection options
69
+ * @property {Object} [keypair] - JWT keypair for authentication
70
+ * @property {AdminUser} [adminUser] - Admin user configuration
71
+ * @property {Function} [verificationCodeGeneratorMethod] - Custom verification code generator
72
+ * @property {CollectionDefinition[]} [collectionDefinitions] - Custom collection definitions
73
+ * @property {PermissionGroup[]} [permissionGroups] - Custom permission groups
74
+ * @property {CmsTrigger[]} [authTriggers] - Authentication triggers
75
+ * @property {CmsTrigger[]} [fileTriggers] - File handling triggers
76
+ * @property {DefinedFunction[]} [functions] - Custom API functions
77
+ */
78
+ export interface RestOptions {
79
+ cors?: cors.Options;
80
+ modulesPath?: string;
81
+ uploadDirectory?: string;
82
+ koaBodyOptions?: any;
83
+ staticPath?: StaticPathOptions;
84
+ onBeforeInit?: (koaApp: Koa) => void;
85
+ onAfterInit?: (koaApp: Koa) => void;
86
+ port?: number;
87
+ dontListen?: boolean;
88
+ mongo?: MongoOptions;
89
+ keypair?: KeyPair;
90
+ adminUser?: AdminUser;
91
+ verificationCodeGeneratorMethod?: () => string;
92
+ collectionDefinitions?: CollectionDefinition[];
93
+ permissionGroups?: PermissionGroup[];
94
+ authTriggers?: CmsTrigger[];
95
+ fileTriggers?: CmsTrigger[];
96
+ functions?: DefinedFunction[];
97
+ }
98
+
99
+ /**
100
+ * Global configuration object
101
+ * @type {RestOptions}
102
+ */
103
+ export const config: RestOptions = {};
104
+
105
+ /**
106
+ * Updates the global configuration with new options
107
+ * @param {RestOptions} options - New configuration options to merge
108
+ * @example
109
+ * ```typescript
110
+ * setConfig({
111
+ * port: 3000,
112
+ * mongo: {
113
+ * mongoBaseAddress: 'mongodb://localhost:27017',
114
+ * dbPrefix: 'myapp_'
115
+ * }
116
+ * });
117
+ * ```
118
+ */
119
+ export function setConfig(options: RestOptions): void {
120
+ Object.assign(config, options);
121
+ }
@@ -0,0 +1,31 @@
1
+ import { PermissionGroup } from './index';
2
+
3
+ export const permissionGroups = [
4
+ new PermissionGroup({
5
+ title: 'anonymous',
6
+ isAnonymous: true,
7
+ allowedAccessTypes: ['anonymous_access'],
8
+ }),
9
+
10
+ new PermissionGroup({
11
+ title: 'end-user',
12
+ isDefault: true,
13
+ allowedAccessTypes: [
14
+ 'user_access',
15
+ 'anonymous_access',
16
+ 'upload_file_access',
17
+ 'remove_file_access',
18
+ ],
19
+ }),
20
+
21
+ new PermissionGroup({
22
+ title: 'administrator',
23
+ allowedAccessTypes: [
24
+ 'user_access',
25
+ 'anonymous_access',
26
+ 'upload_file_access',
27
+ 'remove_file_access',
28
+ 'advanced_settings',
29
+ ],
30
+ }),
31
+ ];
package/src/events.ts ADDED
@@ -0,0 +1,59 @@
1
+ import Koa from "koa";
2
+
3
+ /**
4
+ * Event callback interface
5
+ */
6
+ interface EventCallback {
7
+ event: string;
8
+ callback: (...args: any[]) => void;
9
+ }
10
+
11
+ /**
12
+ * Array to store all registered event callbacks
13
+ */
14
+ const eventCallbacks: EventCallback[] = [];
15
+
16
+ /**
17
+ * Supported event types:
18
+ * - onBeforeInit: (koaApp: Koa) => void; // A callback called before initializing the Koa server.
19
+ * - onAfterInit: (koaApp: Koa) => void; // A callback called after server initialization.
20
+ * - onNewUser: (user: any) => void; // A callback called when a new user is created.
21
+ *
22
+ * @param event - The event name to register
23
+ * @param callback - The callback function to be called when the event is triggered
24
+ * @throws Error if event is not a string or callback is not a function
25
+ */
26
+ export function registerEventCallback(
27
+ event: string,
28
+ callback: (...args: any[]) => void
29
+ ): void {
30
+ if (typeof event !== "string") throw new Error("Event must be a string");
31
+
32
+ if (typeof callback !== "function")
33
+ throw new Error("Callback must be a function");
34
+
35
+ eventCallbacks.push({ event, callback });
36
+ }
37
+
38
+ /**
39
+ * Get all registered callbacks for a specific event
40
+ * @param event - The event name to get callbacks for
41
+ * @returns Array of callbacks registered for the event
42
+ */
43
+ export function getEventCallbacks(event: string): ((...args: any[]) => void)[] {
44
+ return eventCallbacks
45
+ .filter((cb) => cb.event === event)
46
+ .map((cb) => cb.callback);
47
+ }
48
+
49
+ /**
50
+ * Trigger an event with arguments
51
+ * @param event - The event name to trigger
52
+ * @param args - Arguments to pass to the callback functions
53
+ */
54
+ export function triggerEvent(event: string, ...args: any[]): void {
55
+ const callbacks = getEventCallbacks(event);
56
+ for (const callback of callbacks) {
57
+ callback(...args);
58
+ }
59
+ }