@adaptivestone/framework 4.8.0 → 4.8.2
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/CHANGELOG.md +10 -0
- package/Cli.js +2 -0
- package/commands/migration/Create.js +4 -3
- package/coverage/clover.xml +2820 -2789
- package/coverage/coverage-final.json +43 -43
- package/coverage/framework/config/auth.js.html +6 -6
- package/coverage/framework/config/http.js.html +10 -10
- package/coverage/framework/config/i18n.js.html +13 -13
- package/coverage/framework/config/index.html +1 -1
- package/coverage/framework/config/log.js.html +23 -23
- package/coverage/framework/config/mail.js.html +30 -30
- package/coverage/framework/config/mongo.js.html +4 -4
- package/coverage/framework/config/rateLimiter.js.html +17 -17
- package/coverage/framework/config/redis.js.html +5 -5
- package/coverage/framework/config/validate.js.html +4 -4
- package/coverage/framework/controllers/Auth.js.html +90 -90
- package/coverage/framework/controllers/Home.js.html +39 -39
- package/coverage/framework/controllers/index.html +17 -17
- package/coverage/framework/controllers/index.js.html +54 -54
- package/coverage/framework/controllers/test/SomeController.js.html +106 -106
- package/coverage/framework/controllers/test/index.html +19 -19
- package/coverage/framework/helpers/files.js.html +66 -66
- package/coverage/framework/helpers/index.html +1 -1
- package/coverage/framework/helpers/logger.js.html +14 -14
- package/coverage/framework/helpers/redis/clearNamespace.js.html +28 -28
- package/coverage/framework/helpers/redis/index.html +17 -17
- package/coverage/framework/index.html +19 -19
- package/coverage/framework/models/Migration.js.html +16 -16
- package/coverage/framework/models/Sequence.js.html +39 -39
- package/coverage/framework/models/User.js.html +192 -192
- package/coverage/framework/models/index.html +28 -28
- package/coverage/framework/modules/AbstractController.js.html +478 -478
- package/coverage/framework/modules/AbstractModel.js.html +54 -54
- package/coverage/framework/modules/Base.js.html +52 -52
- package/coverage/framework/modules/index.html +21 -21
- package/coverage/framework/server.js.html +478 -385
- package/coverage/framework/services/cache/Cache.js.html +216 -216
- package/coverage/framework/services/cache/index.html +20 -20
- package/coverage/framework/services/documentation/DocumentationGenerator.js.html +17 -17
- package/coverage/framework/services/documentation/index.html +1 -1
- package/coverage/framework/services/http/HttpServer.js.html +90 -90
- package/coverage/framework/services/http/index.html +1 -1
- package/coverage/framework/services/http/middleware/AbstractMiddleware.js.html +60 -60
- package/coverage/framework/services/http/middleware/Auth.js.html +16 -16
- package/coverage/framework/services/http/middleware/GetUserByToken.js.html +60 -60
- package/coverage/framework/services/http/middleware/I18n.js.html +129 -129
- package/coverage/framework/services/http/middleware/Pagination.js.html +95 -95
- package/coverage/framework/services/http/middleware/PrepareAppInfo.js.html +27 -27
- package/coverage/framework/services/http/middleware/RateLimiter.js.html +166 -166
- package/coverage/framework/services/http/middleware/RequestLogger.js.html +21 -21
- package/coverage/framework/services/http/middleware/RequestParser.js.html +47 -47
- package/coverage/framework/services/http/middleware/Role.js.html +55 -55
- package/coverage/framework/services/http/middleware/index.html +99 -99
- package/coverage/framework/services/http/middleware/test/CheckFlag.js.html +36 -36
- package/coverage/framework/services/http/middleware/test/index.html +19 -19
- package/coverage/framework/services/messaging/email/index.html +1 -1
- package/coverage/framework/services/messaging/email/index.js.html +67 -67
- package/coverage/framework/services/messaging/index.html +1 -1
- package/coverage/framework/services/messaging/index.js.html +6 -6
- package/coverage/framework/services/validate/ValidateService.js.html +202 -202
- package/coverage/framework/services/validate/drivers/AbstractValidator.js.html +24 -24
- package/coverage/framework/services/validate/drivers/CustomValidator.js.html +14 -14
- package/coverage/framework/services/validate/drivers/YupValidator.js.html +55 -55
- package/coverage/framework/services/validate/drivers/index.html +1 -1
- package/coverage/framework/services/validate/index.html +21 -21
- package/coverage/index.html +110 -110
- package/models/User.test.js +3 -3
- package/package.json +2 -1
- package/server.d.ts +9 -1
- package/server.js +50 -19
- package/services/http/middleware/I18n.test.js +1 -1
- package/services/http/middleware/RateLimiter.test.js +7 -7
- package/services/validate/ValidateService.test.js +3 -3
- package/tests/setup.js +3 -1
- package/tests/setupVitest.js +3 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptivestone/framework",
|
|
3
|
-
"version": "4.8.
|
|
3
|
+
"version": "4.8.2",
|
|
4
4
|
"description": "Adaptive stone node js framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"eslint": "^8.0.0",
|
|
56
56
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
57
57
|
"eslint-config-prettier": "^9.0.0",
|
|
58
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
58
59
|
"eslint-plugin-vitest": "^0.3.1",
|
|
59
60
|
"husky": "^8.0.0",
|
|
60
61
|
"lint-staged": "^14.0.0",
|
package/server.d.ts
CHANGED
|
@@ -49,7 +49,15 @@ declare class Server {
|
|
|
49
49
|
* Do an initialization (config reading, etc)
|
|
50
50
|
* @returns {Promise}
|
|
51
51
|
*/
|
|
52
|
-
init(
|
|
52
|
+
init(
|
|
53
|
+
options: { isSkipModelInit: boolean } = { isSkipModelInit: false },
|
|
54
|
+
): Promise<boolean>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Load model and init them
|
|
58
|
+
* @returns {Promise}
|
|
59
|
+
*/
|
|
60
|
+
initAllModels(): Promise<void>;
|
|
53
61
|
|
|
54
62
|
/**
|
|
55
63
|
* Return config from {configName} (file name) on config folder.
|
package/server.js
CHANGED
|
@@ -88,13 +88,19 @@ class Server {
|
|
|
88
88
|
* Do an initialization (config reading, etc)
|
|
89
89
|
* @returns {Promise}
|
|
90
90
|
*/
|
|
91
|
-
async init() {
|
|
91
|
+
async init({ isSkipModelInit = false } = {}) {
|
|
92
92
|
if (this.#isInited) {
|
|
93
93
|
return true;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
console.time('Server init. Done');
|
|
97
|
+
console.time('Loading config and model files. Time');
|
|
97
98
|
await Promise.all([this.#initConfigFiles(), this.#loadModelFiles()]);
|
|
99
|
+
console.timeEnd('Loading config and model files. Time');
|
|
100
|
+
|
|
101
|
+
if (!isSkipModelInit) {
|
|
102
|
+
await this.initAllModels();
|
|
103
|
+
}
|
|
98
104
|
|
|
99
105
|
this.#isInited = true;
|
|
100
106
|
|
|
@@ -103,6 +109,35 @@ class Server {
|
|
|
103
109
|
return true;
|
|
104
110
|
}
|
|
105
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Load model and init them
|
|
114
|
+
* @returns {Promise}
|
|
115
|
+
*/
|
|
116
|
+
async initAllModels() {
|
|
117
|
+
console.time('Initing models. Time');
|
|
118
|
+
|
|
119
|
+
if (this.app.getConfig('mongo').connectionString) {
|
|
120
|
+
for (const [modelName, ModelConstructor] of this.cache
|
|
121
|
+
.modelConstructors) {
|
|
122
|
+
try {
|
|
123
|
+
const model = new ModelConstructor(this.app);
|
|
124
|
+
this.cache.models.set(modelName, model.mongooseModel);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
this.app.logger.error(
|
|
127
|
+
`Problem with model ${modelName}, ${e.message}`,
|
|
128
|
+
);
|
|
129
|
+
this.app.logger.error(e);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
this.app.logger.info(
|
|
134
|
+
'Skipping inited models as we have no mongo connection string',
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.timeEnd('Initing models. Time');
|
|
139
|
+
}
|
|
140
|
+
|
|
106
141
|
async #initConfigFiles() {
|
|
107
142
|
const files = await getFilesPathWithInheritance({
|
|
108
143
|
internalFolder: `${__dirname}/config`,
|
|
@@ -207,12 +242,11 @@ class Server {
|
|
|
207
242
|
* @returns {Object} config object. Structure depends of config file
|
|
208
243
|
*/
|
|
209
244
|
getConfig(configName) {
|
|
210
|
-
if (!this.#isInited) {
|
|
211
|
-
throw new Error('You should call Server.init() before using it');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
245
|
if (!this.cache.configs.has(configName)) {
|
|
215
|
-
this
|
|
246
|
+
if (!this.#isInited) {
|
|
247
|
+
throw new Error('You should call Server.init() before using getConfig');
|
|
248
|
+
}
|
|
249
|
+
this.app.logger.warn(
|
|
216
250
|
`You asked for config ${configName} that not exists. Please check you codebase `,
|
|
217
251
|
);
|
|
218
252
|
return {};
|
|
@@ -321,20 +355,17 @@ class Server {
|
|
|
321
355
|
`Probably your model name '${modelName}' in plural from. Try to avoid plural form`,
|
|
322
356
|
);
|
|
323
357
|
}
|
|
358
|
+
if (!this.#isInited) {
|
|
359
|
+
this.app.logger.error(
|
|
360
|
+
new Error('You should call Server.init() before using getModel'),
|
|
361
|
+
);
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
324
364
|
if (!this.cache.models.has(modelName)) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
try {
|
|
331
|
-
const model = new Model(this.app);
|
|
332
|
-
|
|
333
|
-
this.cache.models.set(modelName, model.mongooseModel);
|
|
334
|
-
} catch (e) {
|
|
335
|
-
this.app.logger.error(`Problem with model ${modelName}, ${e.message}`);
|
|
336
|
-
this.app.logger.error(e);
|
|
337
|
-
}
|
|
365
|
+
this.app.logger.warn(
|
|
366
|
+
`You asked for model ${modelName} that not exists. Please check you codebase `,
|
|
367
|
+
);
|
|
368
|
+
return {};
|
|
338
369
|
}
|
|
339
370
|
return this.cache.models.get(modelName);
|
|
340
371
|
}
|
|
@@ -87,7 +87,7 @@ describe('i18n middleware methods', () => {
|
|
|
87
87
|
appInfo: {},
|
|
88
88
|
};
|
|
89
89
|
await middleware.middleware(req, {}, nextFunction);
|
|
90
|
-
expect(isCalled).
|
|
90
|
+
expect(isCalled).toBeTruthy();
|
|
91
91
|
expect(req.appInfo.i18n).toBeDefined();
|
|
92
92
|
expect(req.appInfo.i18n.t('aaaaa')).toBe('aaaaa');
|
|
93
93
|
expect(req.i18n.t('aaaaa')).toBe('aaaaa'); // proxy test
|
|
@@ -113,7 +113,7 @@ describe('rate limiter methods', () => {
|
|
|
113
113
|
() => {},
|
|
114
114
|
);
|
|
115
115
|
expect(status).toBe(500);
|
|
116
|
-
expect(isSend).
|
|
116
|
+
expect(isSend).toBeTruthy();
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
const makeOneRequest = async ({ rateLimiter, driver, request }) => {
|
|
@@ -154,7 +154,7 @@ describe('rate limiter methods', () => {
|
|
|
154
154
|
rateLimiter: mongoRateLimiter,
|
|
155
155
|
request: { ip: '10.10.0.1' },
|
|
156
156
|
});
|
|
157
|
-
expect(isNextCalled).
|
|
157
|
+
expect(isNextCalled).toBeTruthy();
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
it('middleware should works with a memory drivers', async () => {
|
|
@@ -163,7 +163,7 @@ describe('rate limiter methods', () => {
|
|
|
163
163
|
driver: 'memory',
|
|
164
164
|
request: { ip: '10.10.0.1' },
|
|
165
165
|
});
|
|
166
|
-
expect(isNextCalled).
|
|
166
|
+
expect(isNextCalled).toBeTruthy();
|
|
167
167
|
});
|
|
168
168
|
|
|
169
169
|
it('middleware should works with a redis drivers', async () => {
|
|
@@ -172,7 +172,7 @@ describe('rate limiter methods', () => {
|
|
|
172
172
|
driver: 'redis',
|
|
173
173
|
request: { ip: '10.10.0.1' },
|
|
174
174
|
});
|
|
175
|
-
expect(isNextCalled).
|
|
175
|
+
expect(isNextCalled).toBeTruthy();
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
it('middleware should rate limits for us. mongo driver', async () => {
|
|
@@ -188,7 +188,7 @@ describe('rate limiter methods', () => {
|
|
|
188
188
|
const isSend = data.find((obj) => obj.isSend);
|
|
189
189
|
|
|
190
190
|
expect(status.status).toBe(429);
|
|
191
|
-
expect(isSend.isSend).
|
|
191
|
+
expect(isSend.isSend).toBeTruthy();
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
it('middleware should rate limits for us. memory driver', async () => {
|
|
@@ -208,7 +208,7 @@ describe('rate limiter methods', () => {
|
|
|
208
208
|
const isSend = data.find((obj) => obj.isSend);
|
|
209
209
|
|
|
210
210
|
expect(status.status).toBe(429);
|
|
211
|
-
expect(isSend.isSend).
|
|
211
|
+
expect(isSend.isSend).toBeTruthy();
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
it('middleware should rate limits for us. redis driver', async () => {
|
|
@@ -228,6 +228,6 @@ describe('rate limiter methods', () => {
|
|
|
228
228
|
const isSend = data.find((obj) => obj.isSend);
|
|
229
229
|
|
|
230
230
|
expect(status.status).toBe(429);
|
|
231
|
-
expect(isSend.isSend).
|
|
231
|
+
expect(isSend.isSend).toBeTruthy();
|
|
232
232
|
});
|
|
233
233
|
});
|
|
@@ -45,21 +45,21 @@ describe('validate service', () => {
|
|
|
45
45
|
expect.assertions(1);
|
|
46
46
|
const validator = 'not an object';
|
|
47
47
|
const result = ValidateService.isValidatorExists(validator);
|
|
48
|
-
expect(result).
|
|
48
|
+
expect(result).toBeFalsy();
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
it('returns true if validator is an instance of one of the drivers', () => {
|
|
52
52
|
expect.assertions(1);
|
|
53
53
|
const validator = new ValidateService.drivers.YupValidator();
|
|
54
54
|
const result = ValidateService.isValidatorExists(validator);
|
|
55
|
-
expect(result).
|
|
55
|
+
expect(result).toBeTruthy();
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
it('returns false if validator is not an instance of any of the drivers', () => {
|
|
59
59
|
expect.assertions(1);
|
|
60
60
|
const validator = {};
|
|
61
61
|
const result = ValidateService.isValidatorExists(validator);
|
|
62
|
-
expect(result).
|
|
62
|
+
expect(result).toBeFalsy();
|
|
63
63
|
});
|
|
64
64
|
});
|
|
65
65
|
|
package/tests/setup.js
CHANGED
|
@@ -38,12 +38,14 @@ beforeAll(async () => {
|
|
|
38
38
|
process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
|
|
39
39
|
},
|
|
40
40
|
});
|
|
41
|
-
await global.server.init();
|
|
41
|
+
await global.server.init({ isSkipModelInit: true });
|
|
42
42
|
global.server.updateConfig('mongo', {
|
|
43
43
|
connectionString: connectionStringMongo,
|
|
44
44
|
});
|
|
45
45
|
global.server.updateConfig('http', { port: 0 }); // allow to use random
|
|
46
46
|
global.server.updateConfig('mail', { transport: 'stub' });
|
|
47
|
+
await global.server.initAllModels();
|
|
48
|
+
|
|
47
49
|
if (!global.testSetup) {
|
|
48
50
|
global.testSetup = {};
|
|
49
51
|
}
|
package/tests/setupVitest.js
CHANGED
|
@@ -12,7 +12,6 @@ const Server = require('../server');
|
|
|
12
12
|
|
|
13
13
|
const clearRedisNamespace = require('../helpers/redis/clearNamespace');
|
|
14
14
|
|
|
15
|
-
// eslint-disable-next-line vitest/no-hooks, vitest/require-top-level-describe
|
|
16
15
|
beforeAll(async () => {
|
|
17
16
|
mongoMemoryServerInstance = await MongoMemoryReplSet.create({
|
|
18
17
|
// binary: { version: '4.4.6' },
|
|
@@ -40,12 +39,14 @@ beforeAll(async () => {
|
|
|
40
39
|
process.env.TEST_FOLDER_MIGRATIONS || path.resolve('./migrations'),
|
|
41
40
|
},
|
|
42
41
|
});
|
|
43
|
-
await global.server.init();
|
|
42
|
+
await global.server.init({ isSkipModelInit: true });
|
|
44
43
|
global.server.updateConfig('mongo', {
|
|
45
44
|
connectionString: connectionStringMongo,
|
|
46
45
|
});
|
|
47
46
|
global.server.updateConfig('http', { port: 0 }); // allow to use random
|
|
48
47
|
global.server.updateConfig('mail', { transport: 'stub' });
|
|
48
|
+
await global.server.initAllModels();
|
|
49
|
+
|
|
49
50
|
if (!global.testSetup) {
|
|
50
51
|
global.testSetup = {};
|
|
51
52
|
}
|
|
@@ -76,7 +77,6 @@ beforeAll(async () => {
|
|
|
76
77
|
await global.server.startServer();
|
|
77
78
|
});
|
|
78
79
|
|
|
79
|
-
// eslint-disable-next-line vitest/no-hooks, vitest/require-top-level-describe
|
|
80
80
|
beforeEach(() => {
|
|
81
81
|
if (global.server) {
|
|
82
82
|
const key = `test-${Math.random().toString(36).substring(7)}`;
|
|
@@ -86,7 +86,6 @@ beforeEach(() => {
|
|
|
86
86
|
}
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
// eslint-disable-next-line vitest/no-hooks, vitest/require-top-level-describe
|
|
90
89
|
afterEach(async () => {
|
|
91
90
|
if (global.server) {
|
|
92
91
|
const { url, namespace } = global.server.getConfig('redis');
|
|
@@ -102,7 +101,6 @@ afterEach(async () => {
|
|
|
102
101
|
}
|
|
103
102
|
});
|
|
104
103
|
|
|
105
|
-
// eslint-disable-next-line vitest/no-hooks, vitest/require-top-level-describe
|
|
106
104
|
afterAll(async () => {
|
|
107
105
|
if (global.server) {
|
|
108
106
|
global.server.app.httpServer.shutdown();
|