@drax/crud-back 2.11.0 → 3.1.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 (65) hide show
  1. package/dist/controllers/AbstractFastifyController.js +47 -24
  2. package/dist/repository/AbstractMongoRepository.js +12 -8
  3. package/dist/repository/AbstractSqliteRepository.js +40 -9
  4. package/dist/services/AbstractService.js +9 -6
  5. package/package.json +8 -7
  6. package/src/controllers/AbstractFastifyController.ts +56 -28
  7. package/src/repository/AbstractMongoRepository.ts +17 -8
  8. package/src/repository/AbstractSqliteRepository.ts +61 -10
  9. package/src/services/AbstractService.ts +12 -6
  10. package/test/_mocks/MockRepository.ts +1 -1
  11. package/test/controllers/PersonController.test.ts +547 -0
  12. package/test/people/controllers/CountryController.ts +40 -0
  13. package/test/people/controllers/LanguageController.ts +29 -0
  14. package/test/people/controllers/PersonController.ts +29 -0
  15. package/test/people/factory/services/CountryServiceFactory.ts +41 -0
  16. package/test/people/factory/services/LanguageServiceFactory.ts +41 -0
  17. package/test/people/factory/services/PersonServiceFactory.ts +41 -0
  18. package/test/people/interfaces/ICountry.ts +28 -0
  19. package/test/people/interfaces/ICountryRepository.ts +11 -0
  20. package/test/people/interfaces/ILanguage.ts +32 -0
  21. package/test/people/interfaces/ILanguageRepository.ts +11 -0
  22. package/test/people/interfaces/IPerson.ts +58 -0
  23. package/test/people/interfaces/IPersonRepository.ts +11 -0
  24. package/test/people/models/CountryModel.ts +38 -0
  25. package/test/people/models/LanguageModel.ts +40 -0
  26. package/test/people/models/PersonModel.ts +61 -0
  27. package/test/people/permissions/CountryPermissions.ts +14 -0
  28. package/test/people/permissions/LanguagePermissions.ts +14 -0
  29. package/test/people/permissions/PersonPermissions.ts +18 -0
  30. package/test/people/repository/mongo/CountryMongoRepository.ts +22 -0
  31. package/test/people/repository/mongo/LanguageMongoRepository.ts +22 -0
  32. package/test/people/repository/mongo/PersonMongoRepository.ts +22 -0
  33. package/test/people/repository/sqlite/CountrySqliteRepository.ts +33 -0
  34. package/test/people/repository/sqlite/LanguageSqliteRepository.ts +37 -0
  35. package/test/people/repository/sqlite/PersonSqliteRepository.ts +42 -0
  36. package/test/people/routes/CountryRoutes.ts +34 -0
  37. package/test/people/routes/LanguageRoutes.ts +34 -0
  38. package/test/people/routes/PersonRoutes.ts +40 -0
  39. package/test/people/schemas/CountrySchema.ts +22 -0
  40. package/test/people/schemas/LanguageSchema.ts +22 -0
  41. package/test/people/schemas/PersonSchema.ts +42 -0
  42. package/test/people/services/CountryService.ts +20 -0
  43. package/test/people/services/LanguageService.ts +20 -0
  44. package/test/people/services/PersonService.ts +20 -0
  45. package/test/services/AbstractService.test.ts +11 -7
  46. package/test/setup/MongoInMemory.ts +56 -0
  47. package/test/setup/TestSetup.ts +344 -0
  48. package/test/setup/data/admin-role.ts +13 -0
  49. package/test/setup/data/basic-user.ts +14 -0
  50. package/test/setup/data/one-tenant.ts +6 -0
  51. package/test/setup/data/restricted-role.ts +16 -0
  52. package/test/setup/data/root-user.ts +14 -0
  53. package/test/setup/data/tenant-one-user.ts +13 -0
  54. package/test/setup/data/tenant-two-user.ts +14 -0
  55. package/test/setup/data/two-tenant.ts +6 -0
  56. package/test/workers/ExportCsvWorker.test.ts +1 -1
  57. package/tsconfig.json +2 -1
  58. package/tsconfig.tsbuildinfo +1 -1
  59. package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
  60. package/types/repository/AbstractMongoRepository.d.ts +3 -3
  61. package/types/repository/AbstractMongoRepository.d.ts.map +1 -1
  62. package/types/repository/AbstractSqliteRepository.d.ts +5 -4
  63. package/types/repository/AbstractSqliteRepository.d.ts.map +1 -1
  64. package/types/services/AbstractService.d.ts +4 -2
  65. package/types/services/AbstractService.d.ts.map +1 -1
@@ -0,0 +1,344 @@
1
+ import Fastify, { FastifyInstance, FastifyPluginAsync } from "fastify";
2
+ import { LoadCommonConfigFromEnv } from "@drax/common-back";
3
+ import {
4
+ LoadIdentityConfigFromEnv,
5
+ CreateTenantIfNotExist,
6
+ CreateOrUpdateRole,
7
+ CreateUserIfNotExist,
8
+ jwtMiddleware,
9
+ rbacMiddleware,
10
+ apiKeyMiddleware,
11
+ UserRoutes, RoleRoutes, TenantRoutes, UserApiKeyRoutes,
12
+ UserPermissions, RolePermissions, TenantPermissions, UserApiKeyPermissions,
13
+ LoadPermissions
14
+ } from "@drax/identity-back";
15
+
16
+
17
+
18
+
19
+
20
+ import adminRoleData from "./data/admin-role";
21
+ import restrictedRoleData from "./data/restricted-role";
22
+
23
+ import rootUserData from "./data/root-user";
24
+ import basicUserData from "./data/basic-user";
25
+
26
+ import { IUser, IRole, ITenant } from "@drax/identity-share";
27
+ import MongoInMemory from "./MongoInMemory";
28
+
29
+ import oneTenant from "./data/one-tenant";
30
+ import twoTenant from "./data/two-tenant";
31
+ import tenantOneUser from "./data/tenant-one-user";
32
+ import tenantTwoUser from "./data/tenant-two-user";
33
+
34
+ interface ITestSetupInput {
35
+ routes?: FastifyPluginAsync[]
36
+ permissions?: object[]
37
+ }
38
+
39
+ class TestSetup {
40
+
41
+ private _fastifyInstance: FastifyInstance;
42
+ private _mongoInMemory: MongoInMemory;
43
+ private _rootUser: IUser;
44
+ private _basicUser: IUser;
45
+ private _adminRole: IRole;
46
+ private _restrictedRole: IRole;
47
+ private _customRoutes: FastifyPluginAsync[] = [];
48
+ private _customPermissions: object[] = [];
49
+
50
+ private _tenantOne: ITenant;
51
+ private _tenantTwo: ITenant;
52
+ private _tenantOneUser: IUser;
53
+ private _tenantTwoUser: IUser;
54
+
55
+ constructor(input?: ITestSetupInput) {
56
+ this._customRoutes = input?.routes ?? [];
57
+ this._customPermissions = input?.permissions ?? [];
58
+ }
59
+
60
+ async setup() {
61
+ this.setupEnvironmentVariables();
62
+ this.setupConfig();
63
+ this.setupPermissions();
64
+ this.setupFastifyInstance();
65
+ await this.setupMongoInMemoryAndConnect();
66
+ await this.setupRootUserAndAdminRole();
67
+ await this.setupBasicUserAndRestrictedRole();
68
+ await this.setupTenantOneAndTenantOneUser();
69
+ await this.setupTenantTwoAndTenantTwoUser();
70
+ }
71
+
72
+ setupEnvironmentVariables() {
73
+ // Define environment variables
74
+ process.env.DRAX_DB_ENGINE = "mongo";
75
+ process.env.DRAX_JWT_SECRET = "xxx";
76
+ }
77
+
78
+ setupConfig() {
79
+ LoadCommonConfigFromEnv();
80
+ LoadIdentityConfigFromEnv();
81
+ }
82
+
83
+ setupPermissions() {
84
+ //Merge All Permissions
85
+ const permissions = [
86
+ ...Object.values(UserPermissions),
87
+ ...Object.values(RolePermissions),
88
+ ...Object.values(TenantPermissions),
89
+ ...Object.values(UserApiKeyPermissions),
90
+ ...this.getCustomPermissions()
91
+ ]
92
+
93
+ //Load All Permissions
94
+ LoadPermissions(permissions)
95
+ }
96
+
97
+ getCustomPermissions() {
98
+ const customPermissions = []
99
+ for (const permission of this._customPermissions) {
100
+ customPermissions.push(...Object.values(permission))
101
+ }
102
+ return customPermissions
103
+ }
104
+
105
+ setupFastifyInstance() {
106
+ this._fastifyInstance = Fastify()
107
+ this._fastifyInstance.setErrorHandler(function (error: any, request, reply) {
108
+ console.error("TEST FASTIFY ERROR CAUGHT:", error);
109
+ reply.status(500).send({ statusCode: 500, error: "InternalServerError", message: error?.message });
110
+ });
111
+ this._fastifyInstance.setValidatorCompiler(() => () => true)
112
+ this._fastifyInstance.addHook('onRequest', jwtMiddleware)
113
+ this._fastifyInstance.addHook('onRequest', rbacMiddleware)
114
+ this._fastifyInstance.addHook('onRequest', apiKeyMiddleware)
115
+ this._fastifyInstance.register(UserRoutes)
116
+ this._fastifyInstance.register(RoleRoutes)
117
+ this._fastifyInstance.register(TenantRoutes)
118
+ this._fastifyInstance.register(UserApiKeyRoutes)
119
+ this.registerRoutes(this._customRoutes)
120
+ }
121
+
122
+ registerRoutes(routes: FastifyPluginAsync[]) {
123
+ for (const route of routes) {
124
+ this._fastifyInstance.register(route)
125
+ }
126
+ }
127
+
128
+ async setupMongoInMemoryAndConnect() {
129
+ this._mongoInMemory = new MongoInMemory();
130
+ await this._mongoInMemory.connect();
131
+ }
132
+
133
+ async setupTenantOneAndTenantOneUser() {
134
+ this._tenantOne = await CreateTenantIfNotExist(oneTenant)
135
+ this._tenantOneUser = await CreateUserIfNotExist({ ...tenantOneUser })
136
+ }
137
+
138
+ async setupTenantTwoAndTenantTwoUser() {
139
+ this._tenantTwo = await CreateTenantIfNotExist(twoTenant)
140
+ this._tenantTwoUser = await CreateUserIfNotExist({ ...tenantTwoUser })
141
+ }
142
+
143
+ async setupRootUserAndAdminRole() {
144
+ this._adminRole = await CreateOrUpdateRole({ ...adminRoleData })
145
+ this._rootUser = await CreateUserIfNotExist({ ...rootUserData })
146
+ }
147
+
148
+ async setupBasicUserAndRestrictedRole() {
149
+ this._restrictedRole = await CreateOrUpdateRole({ ...restrictedRoleData })
150
+ this._basicUser = await CreateUserIfNotExist({ ...basicUserData })
151
+ }
152
+
153
+ addRoutes(routes) {
154
+ this._fastifyInstance.register(routes)
155
+ }
156
+
157
+ addPermissions(permissions: object) {
158
+ LoadPermissions([...Object.values(permissions)])
159
+ }
160
+
161
+ async dropCollections() {
162
+ await this._mongoInMemory.dropCollections()
163
+ }
164
+
165
+ async dropCollection(collectionName: string) {
166
+ await this._mongoInMemory.dropCollection(collectionName)
167
+ }
168
+
169
+ async dropAndClose() {
170
+ await this._mongoInMemory.dropAndClose()
171
+ }
172
+
173
+ async login(username: string, password: string): Promise<{ accessToken: string }> {
174
+
175
+ const resp = await this._fastifyInstance.inject({
176
+ method: 'POST',
177
+ url: '/api/auth/login',
178
+ payload: { username: username, password: password }
179
+ });
180
+
181
+ let body = resp.json()
182
+
183
+ if (resp.statusCode === 200 && body.accessToken) {
184
+ return { accessToken: body.accessToken }
185
+ } else {
186
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
187
+ }
188
+
189
+ }
190
+
191
+ async rootUserLogin(): Promise<{ accessToken: string }> {
192
+
193
+ const resp = await this._fastifyInstance.inject({
194
+ method: 'POST',
195
+ url: '/api/auth/login',
196
+ payload: {
197
+ username: rootUserData.username,
198
+ password: rootUserData.password
199
+ }
200
+ });
201
+
202
+ let body = resp.json()
203
+
204
+ if (resp.statusCode === 200 && body.accessToken) {
205
+ return { accessToken: body.accessToken }
206
+ } else {
207
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
208
+ }
209
+ }
210
+
211
+ async basicUserLogin(): Promise<{ accessToken: string }> {
212
+
213
+ const resp = await this._fastifyInstance.inject({
214
+ method: 'POST',
215
+ url: '/api/auth/login',
216
+ payload: {
217
+ username: basicUserData.username,
218
+ password: basicUserData.password
219
+ }
220
+ });
221
+
222
+ let body = resp.json()
223
+
224
+ if (resp.statusCode === 200 && body.accessToken) {
225
+ return { accessToken: body.accessToken }
226
+ } else {
227
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
228
+ }
229
+ }
230
+
231
+ async tenantOneUserLogin(): Promise<{ accessToken: string }> {
232
+ const resp = await this._fastifyInstance.inject({
233
+ method: 'POST',
234
+ url: '/api/auth/login',
235
+ payload: {
236
+ username: tenantOneUser.username,
237
+ password: tenantOneUser.password
238
+ }
239
+ });
240
+
241
+ let body = resp.json()
242
+
243
+ if (resp.statusCode === 200 && body.accessToken) {
244
+ return { accessToken: body.accessToken }
245
+ } else {
246
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
247
+ }
248
+ }
249
+
250
+ async tenantTwoUserLogin(): Promise<{ accessToken: string }> {
251
+ const resp = await this._fastifyInstance.inject({
252
+ method: 'POST',
253
+ url: '/api/auth/login',
254
+ payload: {
255
+ username: tenantTwoUser.username,
256
+ password: tenantTwoUser.password
257
+ }
258
+ });
259
+
260
+ let body = resp.json()
261
+
262
+ if (resp.statusCode === 200 && body.accessToken) {
263
+ return { accessToken: body.accessToken }
264
+ } else {
265
+ throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
266
+ }
267
+ }
268
+
269
+ async me(accessToken: string): Promise<IUser> {
270
+
271
+ const resp = await this._fastifyInstance.inject({
272
+ method: 'GET',
273
+ url: '/api/auth/me',
274
+ headers: { Authorization: `Bearer ${accessToken}` }
275
+ });
276
+
277
+ if (resp.statusCode === 200) {
278
+ let user: IUser = resp.json() as IUser
279
+ return user
280
+ } else {
281
+ throw new Error(`Failed to get me. Status Code: ${resp.statusCode} body: ${resp.body}`)
282
+ }
283
+
284
+
285
+ }
286
+
287
+
288
+ get adminRoleData() {
289
+ return { ...adminRoleData };
290
+ }
291
+
292
+ get restrictedRoleData() {
293
+ return { ...restrictedRoleData };
294
+ }
295
+
296
+ get rootUserData() {
297
+ return { ...rootUserData };
298
+ }
299
+
300
+ get basicUserData() {
301
+ return { ...basicUserData };
302
+ }
303
+
304
+ get tenantOneUserData() {
305
+ return { ...tenantOneUser };
306
+ }
307
+
308
+ get tenantTwoUserData() {
309
+ return { ...tenantTwoUser };
310
+ }
311
+
312
+ get adminRole() {
313
+ return this._adminRole;
314
+ }
315
+
316
+ get restrictedRole() {
317
+ return this._restrictedRole;
318
+ }
319
+
320
+ get rootUser() {
321
+ return this._rootUser;
322
+ }
323
+
324
+ get basicUser() {
325
+ return this._basicUser;
326
+ }
327
+
328
+ get fastifyInstance() {
329
+ return this._fastifyInstance;
330
+ }
331
+
332
+ get mongoInMemory() {
333
+ return this._mongoInMemory;
334
+ }
335
+
336
+
337
+ }
338
+
339
+
340
+ export default TestSetup
341
+
342
+ export {
343
+ TestSetup
344
+ }
@@ -0,0 +1,13 @@
1
+ import {PermissionService} from "@drax/identity-back"
2
+
3
+ const adminRoleData = {
4
+ name: "Admin",
5
+ permissions: PermissionService.getPermissions(),
6
+ childRoles: [],
7
+ readonly: true
8
+ }
9
+
10
+ export default adminRoleData
11
+ export {
12
+ adminRoleData
13
+ }
@@ -0,0 +1,14 @@
1
+
2
+ const basicUser = {
3
+ active: true,
4
+ groups: [],
5
+ name: "Basic User",
6
+ username: "basicUser",
7
+ password: "basic.123",
8
+ email: "basic@example.com",
9
+ phone: "123456789",
10
+ role: "Restricted"
11
+ };
12
+
13
+ export default basicUser
14
+ export {basicUser}
@@ -0,0 +1,6 @@
1
+ const oneTenant = {
2
+ name: "one",
3
+ };
4
+
5
+ export default oneTenant
6
+ export {oneTenant}
@@ -0,0 +1,16 @@
1
+ import PersonPermissions from "../../people/permissions/PersonPermissions";
2
+
3
+ const restrictedRoleData = {
4
+ name: "Restricted",
5
+ permissions: [
6
+ PersonPermissions.Create,
7
+ PersonPermissions.Update,
8
+ PersonPermissions.Delete,
9
+ PersonPermissions.View
10
+ ],
11
+ childRoles: [],
12
+ readonly: true
13
+ }
14
+
15
+ export default restrictedRoleData
16
+ export {restrictedRoleData}
@@ -0,0 +1,14 @@
1
+
2
+ const rootUser = {
3
+ active: true,
4
+ groups: [],
5
+ name: "Root",
6
+ username: "root",
7
+ password: "root.123",
8
+ email: "root@example.com",
9
+ phone: "123456789",
10
+ role: "Admin"
11
+ };
12
+
13
+ export default rootUser
14
+ export {rootUser}
@@ -0,0 +1,13 @@
1
+ const tenantOneUser = {
2
+ active: true,
3
+ name: "TenantOneUser",
4
+ username: "tenantoneuser",
5
+ password: "123456789",
6
+ email: "tenantoneuser@example.com",
7
+ phone: "123456789",
8
+ role: "Restricted",
9
+ tenant: 'one'
10
+ };
11
+
12
+ export default tenantOneUser
13
+ export {tenantOneUser}
@@ -0,0 +1,14 @@
1
+
2
+ const tenantTwoUser = {
3
+ active: true,
4
+ name: "TenantTwoUser",
5
+ username: "tenanttwouser",
6
+ password: "123456789",
7
+ email: "tenanttwouser@example.com",
8
+ phone: "123456789",
9
+ role: "Restricted",
10
+ tenant: 'two'
11
+ };
12
+
13
+ export default tenantTwoUser
14
+ export {tenantTwoUser}
@@ -0,0 +1,6 @@
1
+ const twoTenant = {
2
+ name: "two",
3
+ };
4
+
5
+ export default twoTenant
6
+ export {twoTenant}
@@ -1,7 +1,7 @@
1
1
 
2
2
  // Reemplazo de __dirname para ES modules
3
3
  import {test} from "node:test";
4
- import path from "path";
4
+ import * as path from "path";
5
5
  import assert from "node:assert";
6
6
  import {WorkerHandler} from "@drax/common-back"
7
7
  import {fileURLToPath} from "url";
package/tsconfig.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "compilerOptions": {
4
4
  "rootDir": "src",
5
5
  "outDir": "dist",
6
- "declarationDir": "types"
6
+ "declarationDir": "types",
7
+ "esModuleInterop": true
7
8
  },
8
9
  "exclude": ["test", "types","dist","node_modules"],
9
10
  "ts-node": {