@adaptivestone/framework 4.6.0 → 4.8.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 (90) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/Cli.js +1 -0
  3. package/cluster.js +1 -2
  4. package/commands/GetOpenApiJson.js +1 -2
  5. package/commands/SyncIndexes.js +1 -1
  6. package/commands/migration/Migrate.js +2 -2
  7. package/controllers/Auth.js +3 -5
  8. package/controllers/index.js +0 -3
  9. package/coverage/clover.xml +2035 -1926
  10. package/coverage/coverage-final.json +43 -40
  11. package/coverage/framework/config/auth.js.html +6 -6
  12. package/coverage/framework/config/http.js.html +10 -10
  13. package/coverage/framework/config/i18n.js.html +13 -13
  14. package/coverage/framework/config/index.html +1 -1
  15. package/coverage/framework/config/log.js.html +23 -23
  16. package/coverage/framework/config/mail.js.html +30 -30
  17. package/coverage/framework/config/mongo.js.html +4 -4
  18. package/coverage/framework/config/rateLimiter.js.html +17 -17
  19. package/coverage/framework/config/redis.js.html +5 -5
  20. package/coverage/framework/config/validate.js.html +4 -4
  21. package/coverage/framework/controllers/Auth.js.html +97 -103
  22. package/coverage/framework/controllers/Home.js.html +27 -27
  23. package/coverage/framework/controllers/index.html +15 -15
  24. package/coverage/framework/controllers/index.js.html +58 -67
  25. package/coverage/framework/controllers/test/SomeController.js.html +44 -89
  26. package/coverage/framework/controllers/test/index.html +17 -17
  27. package/coverage/framework/helpers/files.js.html +310 -0
  28. package/coverage/framework/helpers/index.html +131 -0
  29. package/coverage/framework/helpers/logger.js.html +142 -0
  30. package/coverage/framework/helpers/redis/clearNamespace.js.html +10 -10
  31. package/coverage/framework/helpers/redis/index.html +1 -1
  32. package/coverage/framework/index.html +19 -19
  33. package/coverage/framework/models/Migration.js.html +130 -0
  34. package/coverage/framework/models/Sequence.js.html +11 -11
  35. package/coverage/framework/models/User.js.html +130 -130
  36. package/coverage/framework/models/index.html +20 -5
  37. package/coverage/framework/modules/AbstractController.js.html +100 -106
  38. package/coverage/framework/modules/AbstractModel.js.html +58 -58
  39. package/coverage/framework/modules/Base.js.html +70 -403
  40. package/coverage/framework/modules/index.html +24 -24
  41. package/coverage/framework/server.js.html +704 -338
  42. package/coverage/framework/services/cache/Cache.js.html +96 -81
  43. package/coverage/framework/services/cache/index.html +19 -19
  44. package/coverage/framework/services/documentation/DocumentationGenerator.js.html +39 -45
  45. package/coverage/framework/services/documentation/index.html +11 -11
  46. package/coverage/framework/services/http/HttpServer.js.html +90 -90
  47. package/coverage/framework/services/http/index.html +1 -1
  48. package/coverage/framework/services/http/middleware/AbstractMiddleware.js.html +45 -45
  49. package/coverage/framework/services/http/middleware/Auth.js.html +19 -19
  50. package/coverage/framework/services/http/middleware/GetUserByToken.js.html +36 -36
  51. package/coverage/framework/services/http/middleware/I18n.js.html +67 -67
  52. package/coverage/framework/services/http/middleware/Pagination.js.html +21 -21
  53. package/coverage/framework/services/http/middleware/PrepareAppInfo.js.html +5 -5
  54. package/coverage/framework/services/http/middleware/RateLimiter.js.html +19 -19
  55. package/coverage/framework/services/http/middleware/RequestLogger.js.html +21 -21
  56. package/coverage/framework/services/http/middleware/RequestParser.js.html +7 -7
  57. package/coverage/framework/services/http/middleware/Role.js.html +43 -43
  58. package/coverage/framework/services/http/middleware/index.html +33 -33
  59. package/coverage/framework/services/http/middleware/test/CheckFlag.js.html +9 -9
  60. package/coverage/framework/services/http/middleware/test/index.html +1 -1
  61. package/coverage/framework/services/messaging/email/index.html +1 -1
  62. package/coverage/framework/services/messaging/email/index.js.html +67 -67
  63. package/coverage/framework/services/messaging/index.html +1 -1
  64. package/coverage/framework/services/messaging/index.js.html +6 -6
  65. package/coverage/framework/services/validate/ValidateService.js.html +155 -167
  66. package/coverage/framework/services/validate/drivers/AbstractValidator.js.html +24 -24
  67. package/coverage/framework/services/validate/drivers/CustomValidator.js.html +14 -14
  68. package/coverage/framework/services/validate/drivers/YupValidator.js.html +41 -41
  69. package/coverage/framework/services/validate/drivers/index.html +1 -1
  70. package/coverage/framework/services/validate/index.html +5 -5
  71. package/coverage/index.html +91 -76
  72. package/helpers/files.js +75 -0
  73. package/helpers/logger.js +19 -0
  74. package/models/Migration.test.js +19 -0
  75. package/modules/AbstractController.js +2 -4
  76. package/modules/Base.js +8 -119
  77. package/modules/BaseCli.js +0 -4
  78. package/package.json +2 -2
  79. package/server.d.ts +14 -1
  80. package/server.js +208 -86
  81. package/services/cache/Cache.js +10 -5
  82. package/services/cache/Cache.test.js +81 -0
  83. package/services/documentation/DocumentationGenerator.js +18 -20
  84. package/services/http/middleware/Auth.test.js +57 -0
  85. package/services/http/middleware/I18n.test.js +15 -3
  86. package/services/http/middleware/PrepareAppInfo.test.js +1 -1
  87. package/services/http/middleware/Role.test.js +93 -0
  88. package/services/validate/ValidateService.js +3 -7
  89. package/tests/setup.js +1 -0
  90. package/tests/setupVitest.js +1 -0
@@ -0,0 +1,81 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { setTimeout } from 'node:timers/promises';
3
+
4
+ describe('cache', () => {
5
+ const time = Date.now();
6
+
7
+ it('can get set values', async () => {
8
+ expect.assertions(2);
9
+
10
+ const { cache } = global.server.app;
11
+
12
+ const res = await cache.getSetValue('TEST_TIME', () => time);
13
+ expect(res).toStrictEqual(time);
14
+
15
+ const res2 = await cache.getSetValue('TEST_TIME', () => '123');
16
+ expect(res2).toStrictEqual(time);
17
+ });
18
+
19
+ it('can delete values', async () => {
20
+ expect.assertions(1);
21
+ const { cache } = global.server.app;
22
+
23
+ await cache.removeKey('TEST_TIME');
24
+
25
+ const res2 = await cache.getSetValue('TEST_TIME', () => '123');
26
+ expect(res2).toBe('123');
27
+ });
28
+
29
+ it('can works with big int', async () => {
30
+ expect.assertions(2);
31
+ const { cache } = global.server.app;
32
+
33
+ const res = await cache.getSetValue('BIN_INT', () => 1n);
34
+ expect(res).toBe(1n);
35
+
36
+ const res2 = await cache.getSetValue('BIN_INT', () => '1111');
37
+ expect(res2).toBe(1n);
38
+ });
39
+
40
+ it('can execute only one request per time', async () => {
41
+ expect.assertions(3);
42
+ const { cache } = global.server.app;
43
+ let counter = 0;
44
+
45
+ const f = async () => {
46
+ await setTimeout(10);
47
+ counter += 1;
48
+ return 1;
49
+ };
50
+
51
+ const [res, res1] = await Promise.all([
52
+ cache.getSetValue('T', f),
53
+ cache.getSetValue('T', f),
54
+ ]);
55
+
56
+ expect(counter).toBe(1);
57
+
58
+ expect(res).toBe(1);
59
+ expect(res1).toBe(1);
60
+ });
61
+
62
+ it('can handle problems on onNotFound', async () => {
63
+ expect.assertions(1);
64
+ const getAsyncThrow = async () => {
65
+ throw new Error('err');
66
+ };
67
+ let err;
68
+
69
+ const { cache } = global.server.app;
70
+
71
+ try {
72
+ await Promise.all([
73
+ cache.getSetValue('THROW', getAsyncThrow),
74
+ cache.getSetValue('THROW', getAsyncThrow),
75
+ ]);
76
+ } catch (e) {
77
+ err = e;
78
+ }
79
+ expect(err.message).toBe('err');
80
+ });
81
+ });
@@ -2,7 +2,8 @@ const Base = require('../../modules/Base');
2
2
  const ValidateService = require('../validate/ValidateService');
3
3
 
4
4
  class DocumentationGenerator extends Base {
5
- static processingFields(fieldsByRoute) {
5
+ // eslint-disable-next-line class-methods-use-this
6
+ processingFields(fieldsByRoute) {
6
7
  const fields = [];
7
8
  if (!fieldsByRoute) {
8
9
  return fields;
@@ -36,7 +37,8 @@ class DocumentationGenerator extends Base {
36
37
  return fields;
37
38
  }
38
39
 
39
- static selectUniqueFields(fields) {
40
+ // eslint-disable-next-line class-methods-use-this
41
+ selectUniqueFields(fields) {
40
42
  return Array.from(
41
43
  new Map(fields.map((item) => [item.name, item])).values(),
42
44
  ).reduce((uniqueArray, item) => {
@@ -52,7 +54,7 @@ class DocumentationGenerator extends Base {
52
54
  }, []);
53
55
  }
54
56
 
55
- static groupFieldsFromSchemas(schemas) {
57
+ groupFieldsFromSchemas(schemas) {
56
58
  const result = [];
57
59
  schemas.forEach((schema) => {
58
60
  const convertedSchema = new ValidateService(this.app, schema).validator;
@@ -71,7 +73,7 @@ class DocumentationGenerator extends Base {
71
73
  return result;
72
74
  }
73
75
 
74
- static convertDataToDocumentationElement(
76
+ convertDataToDocumentationElement(
75
77
  controllerName,
76
78
  routesInfo,
77
79
  middlewaresInfo,
@@ -80,23 +82,19 @@ class DocumentationGenerator extends Base {
80
82
  return {
81
83
  contollerName: controllerName,
82
84
  routesInfo: routesInfo.map((route) => {
83
- const middlewareQueryParams = ValidateService.getMiddlewareParams(
84
- middlewaresInfo,
85
- routeMiddlewaresReg,
86
- {
87
- method: route.method.toLowerCase(),
88
- path: route.fullPath,
89
- },
90
- ).query;
85
+ const middlewareQueryParams = new ValidateService(
86
+ this.app,
87
+ ).getMiddlewareParams(middlewaresInfo, routeMiddlewaresReg, {
88
+ method: route.method.toLowerCase(),
89
+ path: route.fullPath,
90
+ }).query;
91
91
 
92
- const middlewareRequestParams = ValidateService.getMiddlewareParams(
93
- middlewaresInfo,
94
- routeMiddlewaresReg,
95
- {
96
- method: route.method.toLowerCase(),
97
- path: route.fullPath,
98
- },
99
- ).request;
92
+ const middlewareRequestParams = new ValidateService(
93
+ this.app,
94
+ ).getMiddlewareParams(middlewaresInfo, routeMiddlewaresReg, {
95
+ method: route.method.toLowerCase(),
96
+ path: route.fullPath,
97
+ }).request;
100
98
 
101
99
  const queryParams = this.groupFieldsFromSchemas(middlewareQueryParams);
102
100
 
@@ -0,0 +1,57 @@
1
+ import { beforeAll, describe, it, expect } from 'vitest';
2
+ import Auth from './Auth';
3
+
4
+ describe('atuh middleware methods', () => {
5
+ let middleware;
6
+ beforeAll(() => {
7
+ middleware = new Auth(global.server.app);
8
+ });
9
+ it('have description fields', async () => {
10
+ expect.assertions(1);
11
+ expect(middleware.constructor.description).toBeDefined();
12
+ });
13
+
14
+ it('middleware pass when user presented', async () => {
15
+ expect.assertions(1);
16
+ let isCalled = false;
17
+ const nextFunction = () => {
18
+ isCalled = true;
19
+ };
20
+ const req = {
21
+ appInfo: {
22
+ user: true,
23
+ },
24
+ };
25
+ await middleware.middleware(req, {}, nextFunction);
26
+ expect(isCalled).toBeTruthy();
27
+ });
28
+
29
+ it('middleware NOT pass when user NOT presented', async () => {
30
+ expect.assertions(3);
31
+ let isCalled = false;
32
+ let status;
33
+ let isSend;
34
+ const nextFunction = () => {
35
+ isCalled = true;
36
+ };
37
+ const req = {
38
+ appInfo: {}, // no user
39
+ };
40
+ await middleware.middleware(
41
+ req,
42
+ {
43
+ status(statusCode) {
44
+ status = statusCode;
45
+ return this;
46
+ },
47
+ json() {
48
+ isSend = true;
49
+ },
50
+ },
51
+ nextFunction,
52
+ );
53
+ expect(isCalled).toBeFalsy();
54
+ expect(status).toBe(401);
55
+ expect(isSend).toBeTruthy();
56
+ });
57
+ });
@@ -12,7 +12,7 @@ describe('i18n middleware methods', () => {
12
12
  });
13
13
 
14
14
  it('detectors should works correctly', async () => {
15
- expect.assertions(5);
15
+ expect.assertions(6);
16
16
  const request = {
17
17
  get: () => 'en',
18
18
  query: {
@@ -42,10 +42,13 @@ describe('i18n middleware methods', () => {
42
42
  };
43
43
  lang = await middleware.detectLang(request);
44
44
  expect(lang).toBe('en');
45
+
46
+ lang = await middleware.detectLang(request, false);
47
+ expect(lang).toBe('en-GB');
45
48
  });
46
49
 
47
50
  it('middleware that works', async () => {
48
- expect.assertions(4);
51
+ expect.assertions(6);
49
52
  let isCalled = false;
50
53
  const nextFunction = () => {
51
54
  isCalled = true;
@@ -55,10 +58,19 @@ describe('i18n middleware methods', () => {
55
58
  appInfo: {},
56
59
  };
57
60
  await middleware.middleware(req, {}, nextFunction);
58
- expect(isCalled).toBe(true);
61
+ expect(isCalled).toBeTruthy();
59
62
  expect(req.appInfo.i18n).toBeDefined();
63
+ expect(req.appInfo.i18n.language).toBe('en');
60
64
  expect(req.appInfo.i18n.t('aaaaa')).toBe('aaaaa');
61
65
  expect(req.i18n.t('aaaaa')).toBe('aaaaa'); // proxy test
66
+
67
+ const req2 = {
68
+ get: () => 'fakeLang',
69
+ appInfo: {},
70
+ };
71
+
72
+ await middleware.middleware(req2, {}, nextFunction);
73
+ expect(req2.appInfo.i18n.language).toBe('en');
62
74
  });
63
75
 
64
76
  it('middleware disabled', async () => {
@@ -17,7 +17,7 @@ describe('prepareAppInfo methods', () => {
17
17
  };
18
18
  const req = {};
19
19
  await middleware.middleware(req, {}, nextFunction);
20
- expect(isCalled).toBe(true);
20
+ expect(isCalled).toBeTruthy();
21
21
  expect(req.appInfo).toBeDefined();
22
22
  req.appInfo.test = 5;
23
23
  await middleware.middleware(req, {}, nextFunction);
@@ -0,0 +1,93 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import Role from './Role';
3
+
4
+ describe('role middleware methods', () => {
5
+ it('have description fields', async () => {
6
+ expect.assertions(1);
7
+ const middleware = new Role(global.server.app);
8
+ expect(middleware.constructor.description).toBeDefined();
9
+ });
10
+
11
+ it('middleware pass when user presented with a right role', async () => {
12
+ expect.assertions(1);
13
+ let isCalled = false;
14
+ const nextFunction = () => {
15
+ isCalled = true;
16
+ };
17
+ const req = {
18
+ appInfo: {
19
+ user: {
20
+ roles: ['role1', 'role2'],
21
+ },
22
+ },
23
+ };
24
+ const middleware = new Role(global.server.app, {
25
+ roles: ['admin', 'role1'],
26
+ });
27
+
28
+ await middleware.middleware(req, {}, nextFunction);
29
+ expect(isCalled).toBeTruthy();
30
+ });
31
+
32
+ it('middleware NOT pass when user NOT presented', async () => {
33
+ expect.assertions(3);
34
+ let isCalled = false;
35
+ let status;
36
+ let isSend;
37
+ const nextFunction = () => {
38
+ isCalled = true;
39
+ };
40
+ const req = {
41
+ appInfo: {}, // no user
42
+ };
43
+ const middleware = new Role(global.server.app);
44
+ await middleware.middleware(
45
+ req,
46
+ {
47
+ status(statusCode) {
48
+ status = statusCode;
49
+ return this;
50
+ },
51
+ send() {
52
+ isSend = true;
53
+ },
54
+ },
55
+ nextFunction,
56
+ );
57
+ expect(isCalled).toBeFalsy();
58
+ expect(status).toBe(401);
59
+ expect(isSend).toBeTruthy();
60
+ });
61
+
62
+ it('middleware NOT pass when user have a wrong role', async () => {
63
+ expect.assertions(3);
64
+ let isCalled = false;
65
+ let status;
66
+ let isSend;
67
+ const nextFunction = () => {
68
+ isCalled = true;
69
+ };
70
+ const req = {
71
+ appInfo: {
72
+ user: { roles: ['role1', 'role2'] },
73
+ },
74
+ };
75
+ const middleware = new Role(global.server.app, { roles: ['admin'] });
76
+ await middleware.middleware(
77
+ req,
78
+ {
79
+ status(statusCode) {
80
+ status = statusCode;
81
+ return this;
82
+ },
83
+ json() {
84
+ isSend = true;
85
+ },
86
+ },
87
+ nextFunction,
88
+ );
89
+ expect(isCalled).toBeFalsy();
90
+ expect(status).toBe(403);
91
+ expect(isSend).toBeTruthy();
92
+ });
93
+ });
@@ -41,7 +41,7 @@ class ValidateService extends Base {
41
41
  /**
42
42
  * Filter middlewares by route path and select all parameters
43
43
  */
44
- static filterRelatedParametersByRoute(middlewares, method, path) {
44
+ filterRelatedParametersByRoute(middlewares, method, path) {
45
45
  const middlewaresParams = middlewares
46
46
  .filter(
47
47
  (middleware) =>
@@ -63,11 +63,7 @@ class ValidateService extends Base {
63
63
  /**
64
64
  * Group all middleware(routes + controller) parameters
65
65
  */
66
- static getMiddlewareParams(
67
- controllerMiddlewares,
68
- AllrouteMiddlewares,
69
- options,
70
- ) {
66
+ getMiddlewareParams(controllerMiddlewares, AllrouteMiddlewares, options) {
71
67
  const { method, path } = options;
72
68
  const routeMiddlewaresParams = this.filterRelatedParametersByRoute(
73
69
  AllrouteMiddlewares,
@@ -134,7 +130,7 @@ class ValidateService extends Base {
134
130
  this.validator,
135
131
  selectedReqData,
136
132
  );
137
- const additionalMiddlewareSchemas = this.constructor.getMiddlewareParams(
133
+ const additionalMiddlewareSchemas = this.getMiddlewareParams(
138
134
  middlewaresInfo,
139
135
  routeMiddlewaresReg,
140
136
  routeOptions,
package/tests/setup.js CHANGED
@@ -38,6 +38,7 @@ beforeAll(async () => {
38
38
  process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
39
39
  },
40
40
  });
41
+ await global.server.init();
41
42
  global.server.updateConfig('mongo', {
42
43
  connectionString: connectionStringMongo,
43
44
  });
@@ -40,6 +40,7 @@ beforeAll(async () => {
40
40
  process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
41
41
  },
42
42
  });
43
+ await global.server.init();
43
44
  global.server.updateConfig('mongo', {
44
45
  connectionString: connectionStringMongo,
45
46
  });