@adaptivestone/framework 5.0.0-beta.5 → 5.0.0-beta.7
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 +13 -1
- package/Cli.js +2 -3
- package/commands/CreateUser.js +31 -0
- package/commands/DropIndex.js +14 -5
- package/commands/GetOpenApiJson.js +12 -0
- package/commands/SyncIndexes.js +1 -0
- package/commands/migration/Create.js +21 -10
- package/commands/migration/Migrate.js +1 -0
- package/eslint.config.js +27 -3
- package/helpers/yup.js +1 -0
- package/jsconfig.json +3 -3
- package/modules/AbstractCommand.js +10 -1
- package/modules/Base.js +2 -1
- package/modules/BaseCli.js +66 -3
- package/package.json +3 -3
- package/server.d.ts +4 -3
- package/server.js +1 -1
- package/services/http/HttpServer.js +6 -6
- package/services/http/middleware/I18n.js +1 -1
- package/services/messaging/email/index.js +2 -2
- package/services/validate/ValidateService.js +2 -2
- package/services/validate/drivers/AbstractValidator.js +2 -2
- package/services/validate/drivers/YupValidator.js +1 -1
- package/tests/setup.js +5 -0
- package/tests/setupVitest.js +6 -1
- package/types/ICommandArguments.d.ts +41 -0
- package/vitest.config.js +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
### 5.0.0-beta.7
|
|
2
|
+
[UPDATE] update deps
|
|
3
|
+
[UPDATE] change vitest shutdown behavior as mongo driver v6.13 change befaviur that affect us (MongoClient.close now closes any outstanding cursors)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 5.0.0-beta.5
|
|
9
|
+
|
|
10
|
+
[BREAKING] remove minimist CLI parsing and replace it by commandArguments parser
|
|
11
|
+
[UPDATE] migrated from eslint-plugin-import to eslint-plugin-import-x
|
|
12
|
+
|
|
1
13
|
### 5.0.0-beta.5
|
|
2
14
|
|
|
3
15
|
[UPDATE] migrate to eslint 9 and away from aibnb styles (they are abonded)
|
|
@@ -466,7 +478,7 @@ await doc.populate([
|
|
|
466
478
|
[UPDATE] update deps
|
|
467
479
|
[UPDATE] winston console transport now using timestapms
|
|
468
480
|
[UPDATE] PrepareAppInfo middleware now a global one. Do not need to include it on every controller
|
|
469
|
-
[NEW] Request
|
|
481
|
+
[NEW] Request also works with req.query, but req.body have bigger priority
|
|
470
482
|
|
|
471
483
|
### 2.18.0
|
|
472
484
|
|
package/Cli.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import parseArgs from 'minimist';
|
|
2
1
|
import mongoose from 'mongoose';
|
|
3
2
|
import BaseCli from './modules/BaseCli.js';
|
|
4
3
|
import Server from './server.js';
|
|
@@ -8,14 +7,14 @@ class Cli extends BaseCli {
|
|
|
8
7
|
mongoose.set('autoIndex', false); // we do not need create indexes on CLI.
|
|
9
8
|
const server = new Server(serverConfig);
|
|
10
9
|
super(server);
|
|
11
|
-
this.args = parseArgs(process.argv.slice(3));
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
async run() {
|
|
15
13
|
await this.server.init({ isSkipModelInit: true, isSkipModelLoading: true });
|
|
16
14
|
const command = process.argv[2]?.toLowerCase();
|
|
17
|
-
await super.run(command
|
|
15
|
+
await super.run(command);
|
|
18
16
|
this.app.events.emit('shutdown');
|
|
17
|
+
return true;
|
|
19
18
|
}
|
|
20
19
|
}
|
|
21
20
|
|
package/commands/CreateUser.js
CHANGED
|
@@ -6,6 +6,37 @@ class CreateUser extends AbstractCommand {
|
|
|
6
6
|
return 'Create user in a database';
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* You able to add command arguments for parsing there.
|
|
11
|
+
* @returns {import("../types/ICommandArguments.js").ICommandArguments}
|
|
12
|
+
*/
|
|
13
|
+
static get commandArguments() {
|
|
14
|
+
return {
|
|
15
|
+
id: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'User id to find user',
|
|
18
|
+
},
|
|
19
|
+
email: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
description: 'User id to find/create user',
|
|
22
|
+
},
|
|
23
|
+
password: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'New password for user',
|
|
26
|
+
},
|
|
27
|
+
roles: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
description:
|
|
30
|
+
'User roles comma separated string (--roles=user,admin,someOtherRoles)',
|
|
31
|
+
},
|
|
32
|
+
update: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
default: false,
|
|
35
|
+
description: 'Update user if it exists',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
9
40
|
async run() {
|
|
10
41
|
const User = this.app.getModel('User');
|
|
11
42
|
const { id, email, password, roles, update } = this.args;
|
package/commands/DropIndex.js
CHANGED
|
@@ -5,12 +5,21 @@ class DropIndex extends AbstractCommand {
|
|
|
5
5
|
return 'Drop indexes of model';
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
/**
|
|
9
|
+
* You able to add command arguments for parsing there.
|
|
10
|
+
* @returns {import("../types/ICommandArguments.js").ICommandArguments}
|
|
11
|
+
*/
|
|
12
|
+
static get commandArguments() {
|
|
13
|
+
return {
|
|
14
|
+
model: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'Model name',
|
|
17
|
+
required: true,
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
13
21
|
|
|
22
|
+
async run() {
|
|
14
23
|
const Model = this.app.getModel(this.args.model);
|
|
15
24
|
|
|
16
25
|
if (!Model) {
|
|
@@ -8,6 +8,18 @@ class GetOpenApiJson extends AbstractCommand {
|
|
|
8
8
|
static get description() {
|
|
9
9
|
return 'Generate documentation (openApi) ';
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* You able to add command arguments for parsing there.
|
|
13
|
+
* @returns {import("../types/ICommandArguments.js").ICommandArguments}
|
|
14
|
+
*/
|
|
15
|
+
static get commandArguments() {
|
|
16
|
+
return {
|
|
17
|
+
output: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Output file path',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
11
23
|
|
|
12
24
|
async run() {
|
|
13
25
|
const { myDomain } = this.app.getConfig('http');
|
package/commands/SyncIndexes.js
CHANGED
|
@@ -7,28 +7,39 @@ class CreateMigration extends AbstractCommand {
|
|
|
7
7
|
return 'Create new migration';
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* You able to add command arguments for parsing there.
|
|
12
|
+
* @returns {import("../../types/ICommandArguments.js").ICommandArguments}
|
|
13
|
+
*/
|
|
14
|
+
static get commandArguments() {
|
|
15
|
+
return {
|
|
16
|
+
name: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'Migration name',
|
|
19
|
+
required: true,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
10
24
|
async run() {
|
|
11
|
-
if (!this.args.name) {
|
|
12
|
-
return this.logger.error(
|
|
13
|
-
'Please provide migration name with key "--name={someName}"',
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
25
|
if (this.args.name.match(/^\d/)) {
|
|
17
|
-
|
|
26
|
+
this.logger.error('Command cant start from nubmer');
|
|
27
|
+
return false;
|
|
18
28
|
}
|
|
19
|
-
const fileName = `${Date.now()}_${
|
|
29
|
+
const fileName = `${Date.now()}_${CreateMigration.camelSentence(
|
|
20
30
|
this.args.name,
|
|
21
31
|
)}.js`;
|
|
22
32
|
|
|
23
|
-
const fileContent =
|
|
24
|
-
|
|
33
|
+
const fileContent = CreateMigration.getTemplate(
|
|
34
|
+
CreateMigration.camelSentence(this.args.name),
|
|
25
35
|
);
|
|
26
36
|
|
|
27
37
|
await fs.writeFile(
|
|
28
38
|
path.join(this.app.foldersConfig.migrations, fileName),
|
|
29
39
|
fileContent,
|
|
30
40
|
);
|
|
31
|
-
|
|
41
|
+
this.logger.info(`Migration created ${fileName}`);
|
|
42
|
+
return true;
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
static camelSentence(str) {
|
package/eslint.config.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import globals from 'globals';
|
|
2
2
|
import pluginJs from '@eslint/js';
|
|
3
|
-
import importPlugin from 'eslint-plugin-import';
|
|
3
|
+
import importPlugin from 'eslint-plugin-import-x';
|
|
4
4
|
import vitest from '@vitest/eslint-plugin';
|
|
5
5
|
import eslintConfigPrettier from 'eslint-config-prettier';
|
|
6
6
|
import prettierPlugin from 'eslint-plugin-prettier/recommended';
|
|
7
7
|
|
|
8
8
|
/** @type {import('eslint').Linter.Config[]} */
|
|
9
|
+
// @ts-ignore
|
|
9
10
|
export default [
|
|
10
11
|
pluginJs.configs.recommended,
|
|
11
12
|
importPlugin.flatConfigs.recommended,
|
|
@@ -28,8 +29,31 @@ export default [
|
|
|
28
29
|
'class-methods-use-this': 'error',
|
|
29
30
|
'no-shadow': 'error',
|
|
30
31
|
'prefer-const': 'error',
|
|
31
|
-
'import/no-extraneous-dependencies': ['error'],
|
|
32
|
-
'import/first': ['error'],
|
|
32
|
+
'import-x/no-extraneous-dependencies': ['error'],
|
|
33
|
+
'import-x/first': ['error'],
|
|
34
|
+
camelcase: ['error', { properties: 'never', ignoreDestructuring: false }],
|
|
35
|
+
'prefer-destructuring': [
|
|
36
|
+
'error',
|
|
37
|
+
{
|
|
38
|
+
VariableDeclarator: {
|
|
39
|
+
array: false,
|
|
40
|
+
object: true,
|
|
41
|
+
},
|
|
42
|
+
AssignmentExpression: {
|
|
43
|
+
array: true,
|
|
44
|
+
object: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
enforceForRenamedProperties: false,
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
'no-plusplus': 'error',
|
|
52
|
+
'consistent-return': 'error',
|
|
53
|
+
'no-return-await': 'error',
|
|
54
|
+
'arrow-body-style': 'error',
|
|
55
|
+
'dot-notation': 'error',
|
|
56
|
+
curly: 'error',
|
|
33
57
|
},
|
|
34
58
|
},
|
|
35
59
|
{
|
package/helpers/yup.js
CHANGED
package/jsconfig.json
CHANGED
|
@@ -26,9 +26,18 @@ class AbstractCommand extends Base {
|
|
|
26
26
|
return `CLI: ${commandName} ${JSON.stringify(args)}`;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* You able to add command arguments for parsing there.
|
|
31
|
+
* @see https://nodejs.org/api/util.html#utilparseargsconfig in config.options plus extended with description and required
|
|
32
|
+
* @returns {import("../types/ICommandArguments.js").ICommandArguments}
|
|
33
|
+
*/
|
|
34
|
+
static get commandArguments() {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
/**
|
|
30
39
|
* Entry point to every command. This method should be overridden
|
|
31
|
-
* @return {Promise<boolean>}
|
|
40
|
+
* @return {Promise<boolean>} result
|
|
32
41
|
*/
|
|
33
42
|
async run() {
|
|
34
43
|
this.logger.error('You should implement run method');
|
package/modules/Base.js
CHANGED
|
@@ -29,8 +29,9 @@ class Base {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
if (!l) {
|
|
32
|
+
const { loggerGroup } = /** @type {typeof Base} */ (this.constructor);
|
|
32
33
|
this.#realLogger = this.getLogger(
|
|
33
|
-
|
|
34
|
+
loggerGroup + this.getConstructorName(),
|
|
34
35
|
);
|
|
35
36
|
}
|
|
36
37
|
return this.#realLogger;
|
package/modules/BaseCli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import * as url from 'node:url';
|
|
3
|
+
import { parseArgs } from 'node:util';
|
|
3
4
|
import Base from './Base.js';
|
|
4
5
|
|
|
5
6
|
class Cli extends Base {
|
|
@@ -45,9 +46,37 @@ class Cli extends Base {
|
|
|
45
46
|
` \x1b[36m${c.padEnd(maxLength)}\x1b[0m - ${commandsClasses[key].default.description}`,
|
|
46
47
|
);
|
|
47
48
|
}
|
|
49
|
+
console.log(
|
|
50
|
+
'\nUsage (use one of option): \n node cli.js <command> [options] \n npm run cli <command> -- [options]',
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static showHelp(Command, finalArguments) {
|
|
55
|
+
console.log(`\n\x1b[32m${Command.description}\x1b[0m`);
|
|
56
|
+
let output = '';
|
|
57
|
+
|
|
58
|
+
Object.entries(finalArguments).forEach(([key, opt]) => {
|
|
59
|
+
const outputLocal = [];
|
|
60
|
+
outputLocal.push(`\n\x1b[36m --${key} \x1b[0m`);
|
|
61
|
+
if (opt.type !== 'boolean') {
|
|
62
|
+
outputLocal.push(`<${opt.type}>`);
|
|
63
|
+
// flag += `<${opt.type}>`;
|
|
64
|
+
}
|
|
65
|
+
if (opt.required) {
|
|
66
|
+
outputLocal.push('(required)');
|
|
67
|
+
}
|
|
68
|
+
outputLocal.push(`\n \x1b[2m${opt.description}`);
|
|
69
|
+
if (opt.default !== undefined) {
|
|
70
|
+
outputLocal.push(` (default: ${opt.default})`);
|
|
71
|
+
}
|
|
72
|
+
outputLocal.push('\x1b[0m');
|
|
73
|
+
output += outputLocal.join(' ');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
console.log(output);
|
|
48
77
|
}
|
|
49
78
|
|
|
50
|
-
async run(command
|
|
79
|
+
async run(command) {
|
|
51
80
|
await this.loadCommands();
|
|
52
81
|
|
|
53
82
|
if (!command) {
|
|
@@ -63,20 +92,54 @@ class Cli extends Base {
|
|
|
63
92
|
}
|
|
64
93
|
const { default: Command } = await import(this.commands[command]);
|
|
65
94
|
|
|
95
|
+
const defaultArgs = {
|
|
96
|
+
help: {
|
|
97
|
+
type: 'boolean',
|
|
98
|
+
description: 'Show help',
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const finalArguments = {
|
|
103
|
+
...Command.commandArguments,
|
|
104
|
+
...defaultArgs,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const parsedArgs = parseArgs({
|
|
108
|
+
args: process.argv.slice(3), // remove command name
|
|
109
|
+
options: finalArguments,
|
|
110
|
+
tokens: true,
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
if (parsedArgs.values.help) {
|
|
115
|
+
Cli.showHelp(Command, finalArguments);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const [key, opt] of Object.entries(finalArguments)) {
|
|
120
|
+
if (opt.required && !parsedArgs.values[key]) {
|
|
121
|
+
console.log(
|
|
122
|
+
`\x1b[31mRequired field not proivded. Please provide "${key}" argument\x1b[0m`,
|
|
123
|
+
);
|
|
124
|
+
Cli.showHelp(Command, finalArguments);
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
66
129
|
if (Command.isShouldInitModels) {
|
|
67
130
|
this.logger.debug(
|
|
68
131
|
`Command ${command} isShouldInitModels called. If you want to skip loading and init models, please set isShouldInitModels to false in tyou command`,
|
|
69
132
|
);
|
|
70
133
|
process.env.MONGO_APP_NAME = Command.getMongoConnectionName(
|
|
71
134
|
command,
|
|
72
|
-
|
|
135
|
+
parsedArgs.values,
|
|
73
136
|
);
|
|
74
137
|
await this.server.initAllModels();
|
|
75
138
|
} else {
|
|
76
139
|
this.logger.debug(`Command ${command} NOT need to isShouldInitModels`);
|
|
77
140
|
}
|
|
78
141
|
|
|
79
|
-
const c = new Command(this.app, this.commands,
|
|
142
|
+
const c = new Command(this.app, this.commands, parsedArgs.values);
|
|
80
143
|
let result = false;
|
|
81
144
|
|
|
82
145
|
result = await c.run().catch((e) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptivestone/framework",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.7",
|
|
4
4
|
"description": "Adaptive stone node js framework",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"i18next": "^24.0.0",
|
|
38
38
|
"i18next-fs-backend": "^2.0.0",
|
|
39
39
|
"juice": "^11.0.0",
|
|
40
|
-
"minimist": "^1.2.5",
|
|
41
40
|
"mongoose": "^8.0.0",
|
|
42
41
|
"nodemailer": "^6.6.3",
|
|
43
42
|
"nodemailer-sendmail-transport": "^1.0.2",
|
|
@@ -51,11 +50,12 @@
|
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
53
52
|
"@eslint/js": "^9.19.0",
|
|
53
|
+
"@types/node": "^22.13.1",
|
|
54
54
|
"@vitest/coverage-v8": "^3.0.0",
|
|
55
55
|
"@vitest/eslint-plugin": "^1.1.25",
|
|
56
56
|
"eslint": "^9.0.0",
|
|
57
57
|
"eslint-config-prettier": "^10.0.0",
|
|
58
|
-
"eslint-plugin-import": "^
|
|
58
|
+
"eslint-plugin-import-x": "^4.6.1",
|
|
59
59
|
"eslint-plugin-prettier": "^5.0.0",
|
|
60
60
|
"globals": "^15.14.0",
|
|
61
61
|
"husky": "^9.0.0",
|
package/server.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import Cache from './services/cache/Cache';
|
|
|
10
10
|
import winston from 'winston';
|
|
11
11
|
|
|
12
12
|
import HttpServer from './services/http/HttpServer.js';
|
|
13
|
+
import ControllerManager from './services/http/ControllerManager.js';
|
|
13
14
|
|
|
14
15
|
type ServerConfig = {
|
|
15
16
|
folders: ExpandDeep<TFolderConfig>;
|
|
@@ -27,7 +28,7 @@ declare class Server {
|
|
|
27
28
|
get cache(): Server['cacheService'];
|
|
28
29
|
get logger(): winston.Logger;
|
|
29
30
|
httpServer: HttpServer | null;
|
|
30
|
-
controllerManager: null;
|
|
31
|
+
controllerManager: ControllerManager | null;
|
|
31
32
|
};
|
|
32
33
|
cacheService: Cache;
|
|
33
34
|
|
|
@@ -45,7 +46,7 @@ declare class Server {
|
|
|
45
46
|
/**
|
|
46
47
|
* Start server (http + init all http ralated functions)
|
|
47
48
|
*/
|
|
48
|
-
startServer(callbackBefore404?: Promise<null>): Promise<null>;
|
|
49
|
+
startServer(callbackBefore404?: () => Promise<null>): Promise<null>;
|
|
49
50
|
|
|
50
51
|
/**
|
|
51
52
|
* Do an initialization (config reading, etc)
|
|
@@ -92,7 +93,7 @@ declare class Server {
|
|
|
92
93
|
/**
|
|
93
94
|
* Run cli command into framework (http, ws, etc)
|
|
94
95
|
*/
|
|
95
|
-
runCliCommand(commandName: string, args
|
|
96
|
+
runCliCommand(commandName: string, args?: {}): Promise<BaseCli['run']>;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
export default Server;
|
package/server.js
CHANGED
|
@@ -414,7 +414,7 @@ class Server {
|
|
|
414
414
|
* @param {String} commandName name of command to load
|
|
415
415
|
* @param {Object} args list of arguments to pass into command
|
|
416
416
|
*/
|
|
417
|
-
async runCliCommand(commandName, args) {
|
|
417
|
+
async runCliCommand(commandName, args = {}) {
|
|
418
418
|
if (!this.cli) {
|
|
419
419
|
const { default: BaseCli } = await import('./modules/BaseCli.js'); // Speed optimisation
|
|
420
420
|
this.cli = new BaseCli(this);
|
|
@@ -54,15 +54,15 @@ class HttpServer extends Base {
|
|
|
54
54
|
httpConfig.port,
|
|
55
55
|
httpConfig.hostname,
|
|
56
56
|
() => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
);
|
|
60
|
-
if (+
|
|
57
|
+
const address = listener.address();
|
|
58
|
+
const port = typeof address === 'string' ? 0 : address.port;
|
|
59
|
+
this.logger.info(`App started and listening on port ${port}`);
|
|
60
|
+
if (+port !== +httpConfig.port) {
|
|
61
61
|
// in case we using port 0
|
|
62
|
-
this.app.updateConfig('http', { port
|
|
62
|
+
this.app.updateConfig('http', { port });
|
|
63
63
|
this.logger.info(
|
|
64
64
|
`Updating http config to use new port ${
|
|
65
|
-
|
|
65
|
+
port
|
|
66
66
|
}. Old was ${httpConfig.port} `,
|
|
67
67
|
);
|
|
68
68
|
}
|
|
@@ -27,7 +27,7 @@ class I18n extends AbstractMiddleware {
|
|
|
27
27
|
if (I18NConfig.enabled) {
|
|
28
28
|
this.logger.info('Enabling i18n support');
|
|
29
29
|
this.i18n = i18next;
|
|
30
|
-
// eslint-disable-next-line import/no-named-as-default-member
|
|
30
|
+
// eslint-disable-next-line import-x/no-named-as-default-member
|
|
31
31
|
i18next.use(BackendFS).init({
|
|
32
32
|
backend: {
|
|
33
33
|
loadPath: `${this.app.foldersConfig.locales}/{{lng}}/{{ns}}.json`,
|
|
@@ -123,6 +123,7 @@ class Mail extends Base {
|
|
|
123
123
|
this.#renderTemplateFile(templates.style),
|
|
124
124
|
]);
|
|
125
125
|
|
|
126
|
+
// @ts-ignore
|
|
126
127
|
juice.tableElements = ['TABLE'];
|
|
127
128
|
|
|
128
129
|
const juiceResourcesAsync = promisify(juice.juiceResources);
|
|
@@ -139,7 +140,6 @@ class Mail extends Base {
|
|
|
139
140
|
inlinedHTML,
|
|
140
141
|
};
|
|
141
142
|
}
|
|
142
|
-
|
|
143
143
|
/**
|
|
144
144
|
* Send email
|
|
145
145
|
* @param {string} to email send to
|
|
@@ -150,7 +150,7 @@ class Mail extends Base {
|
|
|
150
150
|
async send(to, from = null, aditionalNodemailerOptions = {}) {
|
|
151
151
|
const { subject, text, inlinedHTML } = await this.renderTemplate();
|
|
152
152
|
|
|
153
|
-
return
|
|
153
|
+
return Mail.sendRaw(
|
|
154
154
|
this.app,
|
|
155
155
|
to,
|
|
156
156
|
subject,
|
|
@@ -7,7 +7,7 @@ class ValidateService extends Base {
|
|
|
7
7
|
constructor(app, validator) {
|
|
8
8
|
super(app);
|
|
9
9
|
this.validator = validator
|
|
10
|
-
?
|
|
10
|
+
? ValidateService.getDriverByValidatorBody(app, validator)
|
|
11
11
|
: null;
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -104,7 +104,7 @@ class ValidateService extends Base {
|
|
|
104
104
|
const result = [];
|
|
105
105
|
|
|
106
106
|
for (const validator of validators) {
|
|
107
|
-
const formatedValidator =
|
|
107
|
+
const formatedValidator = ValidateService.getDriverByValidatorBody(
|
|
108
108
|
this.app,
|
|
109
109
|
validator,
|
|
110
110
|
);
|
|
@@ -18,8 +18,8 @@ class AbstractValidator extends Base {
|
|
|
18
18
|
return {};
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
// eslint-disable-next-line class-methods-use-this
|
|
22
|
-
async validateFields() {
|
|
21
|
+
// eslint-disable-next-line class-methods-use-this, no-unused-vars
|
|
22
|
+
async validateFields(data, { query, body, appInfo }) {
|
|
23
23
|
// IMPLENT;
|
|
24
24
|
return true;
|
|
25
25
|
}
|
|
@@ -3,7 +3,7 @@ import AbstractValidator from './AbstractValidator.js';
|
|
|
3
3
|
|
|
4
4
|
class YupValidator extends AbstractValidator {
|
|
5
5
|
get fieldsInJsonFormat() {
|
|
6
|
-
return
|
|
6
|
+
return YupValidator.convertFieldsToJson(this.body);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
static convertFieldsToJson(fields) {
|
package/tests/setup.js
CHANGED
|
@@ -12,7 +12,9 @@ mongoose.set('autoIndex', false);
|
|
|
12
12
|
|
|
13
13
|
let mongoMemoryServerInstance;
|
|
14
14
|
|
|
15
|
+
// @ts-ignore
|
|
15
16
|
jest.setTimeout(1000000);
|
|
17
|
+
// @ts-ignore
|
|
16
18
|
beforeAll(async () => {
|
|
17
19
|
mongoMemoryServerInstance = await MongoMemoryReplSet.create({
|
|
18
20
|
// binary: { version: '4.4.6' },
|
|
@@ -77,6 +79,7 @@ beforeAll(async () => {
|
|
|
77
79
|
await global.server.startServer();
|
|
78
80
|
});
|
|
79
81
|
|
|
82
|
+
// @ts-ignore
|
|
80
83
|
beforeEach(() => {
|
|
81
84
|
if (global.server) {
|
|
82
85
|
const key = `test-${Math.random().toString(36).substring(7)}`;
|
|
@@ -86,6 +89,7 @@ beforeEach(() => {
|
|
|
86
89
|
}
|
|
87
90
|
});
|
|
88
91
|
|
|
92
|
+
// @ts-ignore
|
|
89
93
|
afterEach(async () => {
|
|
90
94
|
if (global.server) {
|
|
91
95
|
const { url, namespace } = global.server.getConfig('redis');
|
|
@@ -101,6 +105,7 @@ afterEach(async () => {
|
|
|
101
105
|
}
|
|
102
106
|
});
|
|
103
107
|
|
|
108
|
+
// @ts-ignore
|
|
104
109
|
afterAll(async () => {
|
|
105
110
|
if (global.server) {
|
|
106
111
|
global.server.app.httpServer.shutdown();
|
package/tests/setupVitest.js
CHANGED
|
@@ -102,6 +102,11 @@ afterAll(async () => {
|
|
|
102
102
|
if (typeof global.testSetup.afterAll === 'function') {
|
|
103
103
|
await global.testSetup.afterAll();
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
try {
|
|
106
|
+
await mongoose.connection.db.dropDatabase(); // clean database after test
|
|
107
|
+
} catch {
|
|
108
|
+
// that ok. No mongoose connection
|
|
109
|
+
}
|
|
110
|
+
|
|
106
111
|
await mongoose.disconnect();
|
|
107
112
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// this is from nodejs types
|
|
2
|
+
interface ParseArgsOptionConfig {
|
|
3
|
+
/**
|
|
4
|
+
* Type of argument.
|
|
5
|
+
*/
|
|
6
|
+
type: 'string' | 'boolean';
|
|
7
|
+
/**
|
|
8
|
+
* Whether this option can be provided multiple times.
|
|
9
|
+
* If `true`, all values will be collected in an array.
|
|
10
|
+
* If `false`, values for the option are last-wins.
|
|
11
|
+
* @default false.
|
|
12
|
+
*/
|
|
13
|
+
multiple?: boolean | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* A single character alias for the option.
|
|
16
|
+
*/
|
|
17
|
+
short?: string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* The default option value when it is not set by args.
|
|
20
|
+
* It must be of the same type as the the `type` property.
|
|
21
|
+
* When `multiple` is `true`, it must be an array.
|
|
22
|
+
* @since v18.11.0
|
|
23
|
+
*/
|
|
24
|
+
default?: string | boolean | string[] | boolean[] | undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ParseArgsOptionsConfigExtended extends ParseArgsOptionConfig {
|
|
28
|
+
/**
|
|
29
|
+
* A description of the option.
|
|
30
|
+
*/
|
|
31
|
+
description?: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Is it required?
|
|
35
|
+
*/
|
|
36
|
+
required?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface ICommandArguments {
|
|
40
|
+
[longOption: string]: ParseArgsOptionsConfigExtended;
|
|
41
|
+
}
|
package/vitest.config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// eslint-disable-next-line import/no-unresolved
|
|
1
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
2
2
|
import { defineConfig } from 'vitest/config';
|
|
3
3
|
|
|
4
4
|
export default defineConfig({
|
|
@@ -9,6 +9,7 @@ export default defineConfig({
|
|
|
9
9
|
outputFile: './coverage/rspec.xml',
|
|
10
10
|
reporters: ['default', 'junit'],
|
|
11
11
|
coverage: {
|
|
12
|
+
provider: 'v8',
|
|
12
13
|
enabled: true,
|
|
13
14
|
reporter: ['text', 'html', 'clover', 'json', 'cobertura'],
|
|
14
15
|
},
|