@adaptivestone/framework 5.0.0-beta.4 → 5.0.0-beta.5

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 CHANGED
@@ -1,3 +1,7 @@
1
+ ### 5.0.0-beta.5
2
+
3
+ [UPDATE] migrate to eslint 9 and away from aibnb styles (they are abonded)
4
+
1
5
  ### 5.0.0-beta.4
2
6
 
3
7
  [NEW] on shutdown event now after timeout we are forcing to shutdown
package/cluster.js CHANGED
@@ -4,7 +4,6 @@ import { cpus } from 'node:os';
4
4
  const numCPUs = cpus().length;
5
5
 
6
6
  if (cluster.isPrimary) {
7
- // eslint-disable-next-line no-console
8
7
  console.log(`Master ${process.pid} is running`);
9
8
  // Fork workers.
10
9
  for (let i = 0; i < numCPUs; i += 1) {
@@ -12,7 +11,6 @@ if (cluster.isPrimary) {
12
11
  }
13
12
 
14
13
  cluster.on('exit', (worker, code, signal) => {
15
- // eslint-disable-next-line no-console
16
14
  console.log(
17
15
  `Worker \x1B[45m ${
18
16
  worker.process.pid
@@ -18,7 +18,7 @@ class GetOpenApiJson extends AbstractCommand {
18
18
 
19
19
  try {
20
20
  jsonFile = JSON.parse(await fs.readFile(jsonFile, 'utf8'));
21
- } catch (e) {
21
+ } catch {
22
22
  this.logger.error(
23
23
  'No npm package detected. Please start this command via NPM as it depends on package.json',
24
24
  );
@@ -123,7 +123,6 @@ class GetOpenApiJson extends AbstractCommand {
123
123
 
124
124
  let routeName = Object.keys(route)[0];
125
125
  if (routeName === '/') {
126
- // eslint-disable-next-line no-continue
127
126
  continue;
128
127
  }
129
128
 
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { object, string } from 'yup';
2
2
  import AbstractController from '../modules/AbstractController.js';
3
3
  import GetUserByToken from '../services/http/middleware/GetUserByToken.js';
4
4
  import RateLimiter from '../services/http/middleware/RateLimiter.js';
@@ -9,58 +9,52 @@ class Auth extends AbstractController {
9
9
  post: {
10
10
  '/login': {
11
11
  handler: this.postLogin,
12
- request: yup.object().shape({
13
- email: yup.string().email().required('auth.emailProvided'), // if not provided then error will be generated
14
- password: yup.string().required('auth.passwordProvided'), // possible to provide values from translation
12
+ request: object().shape({
13
+ email: string().email().required('auth.emailProvided'), // if not provided then error will be generated
14
+ password: string().required('auth.passwordProvided'), // possible to provide values from translation
15
15
  }),
16
16
  },
17
17
  '/register': {
18
18
  handler: this.postRegister,
19
- request: yup.object().shape({
20
- email: yup
21
- .string()
19
+ request: object().shape({
20
+ email: string()
22
21
  .email('auth.emailValid')
23
22
  .required('auth.emailProvided'),
24
- password: yup
25
- .string()
23
+ password: string()
26
24
  .matches(
27
25
  /^[a-zA-Z0-9!@#$%ˆ^&*()_+\-{}[\]<>]+$/,
28
26
  'auth.passwordValid',
29
27
  )
30
28
  .required('auth.passwordProvided'),
31
- nickName: yup
32
- .string()
33
- .matches(/^[a-zA-Z0-9_\-.]+$/, 'auth.nickNameValid'),
34
- firstName: yup.string(),
35
- lastName: yup.string(),
29
+ nickName: string().matches(
30
+ /^[a-zA-Z0-9_\-.]+$/,
31
+ 'auth.nickNameValid',
32
+ ),
33
+ firstName: string(),
34
+ lastName: string(),
36
35
  }),
37
36
  },
38
37
  '/logout': this.postLogout,
39
38
  '/verify': this.verifyUser,
40
39
  '/send-recovery-email': {
41
40
  handler: this.sendPasswordRecoveryEmail,
42
- request: yup
43
- .object()
44
- .shape({ email: yup.string().email().required() }),
41
+ request: object().shape({ email: string().email().required() }),
45
42
  },
46
43
  '/recover-password': {
47
44
  handler: this.recoverPassword,
48
- request: yup.object().shape({
49
- password: yup
50
- .string()
45
+ request: object().shape({
46
+ password: string()
51
47
  .matches(
52
48
  /^[a-zA-Z0-9!@#$%ˆ^&*()_+\-{}[\]<>]+$/,
53
49
  'auth.passwordValid',
54
50
  )
55
51
  .required(),
56
- passwordRecoveryToken: yup.string().required(),
52
+ passwordRecoveryToken: string().required(),
57
53
  }),
58
54
  },
59
55
  '/send-verification': {
60
56
  handler: this.sendVerification,
61
- request: yup
62
- .object()
63
- .shape({ email: yup.string().email().required() }),
57
+ request: object().shape({ email: string().email().required() }),
64
58
  },
65
59
  },
66
60
  };
@@ -136,7 +130,7 @@ class Auth extends AbstractController {
136
130
  user = await User.getUserByVerificationToken(
137
131
  req.query.verification_token,
138
132
  );
139
- } catch (e) {
133
+ } catch {
140
134
  return res.status(400).json({
141
135
  message: req.i18n.t('email.alreadyVerifiedOrWrongToken'),
142
136
  });
@@ -0,0 +1,44 @@
1
+ import globals from 'globals';
2
+ import pluginJs from '@eslint/js';
3
+ import importPlugin from 'eslint-plugin-import';
4
+ import vitest from '@vitest/eslint-plugin';
5
+ import eslintConfigPrettier from 'eslint-config-prettier';
6
+ import prettierPlugin from 'eslint-plugin-prettier/recommended';
7
+
8
+ /** @type {import('eslint').Linter.Config[]} */
9
+ export default [
10
+ pluginJs.configs.recommended,
11
+ importPlugin.flatConfigs.recommended,
12
+ eslintConfigPrettier,
13
+ prettierPlugin,
14
+ {
15
+ languageOptions: {
16
+ sourceType: 'module',
17
+ ecmaVersion: 'latest',
18
+ globals: {
19
+ ...globals.es2023,
20
+ ...globals.node,
21
+ },
22
+ },
23
+ },
24
+ {
25
+ rules: {
26
+ 'no-await-in-loop': 'error',
27
+ 'no-param-reassign': 'error',
28
+ 'class-methods-use-this': 'error',
29
+ 'no-shadow': 'error',
30
+ 'prefer-const': 'error',
31
+ 'import/no-extraneous-dependencies': ['error'],
32
+ 'import/first': ['error'],
33
+ },
34
+ },
35
+ {
36
+ files: ['**/*.test.js'],
37
+ plugins: {
38
+ vitest,
39
+ },
40
+ rules: {
41
+ ...vitest.configs.recommended.rules,
42
+ },
43
+ },
44
+ ];
package/helpers/files.js CHANGED
@@ -73,7 +73,4 @@ const getFilesPathWithInheritance = async ({
73
73
  return filesToLoad;
74
74
  };
75
75
 
76
- export {
77
- // eslint-disable-next-line import/prefer-default-export
78
- getFilesPathWithInheritance,
79
- };
76
+ export { getFilesPathWithInheritance };
package/helpers/logger.js CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-console */
2
1
  const levels = ['error', 'warn', 'info', 'http', 'verbose', 'debug', 'silly'];
3
2
 
4
3
  const consoleLogger = (level, message) => {
package/helpers/yup.js CHANGED
@@ -18,7 +18,4 @@ class YupFile extends Schema {
18
18
  }
19
19
  }
20
20
 
21
- export {
22
- // eslint-disable-next-line import/prefer-default-export
23
- YupFile,
24
- };
21
+ export { YupFile };
package/models/User.js CHANGED
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-param-reassign */
2
-
3
1
  import { scrypt } from 'node:crypto';
4
2
 
5
3
  import { promisify } from 'node:util';
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-restricted-syntax */
2
- /* eslint-disable guard-for-in */
3
1
  import express from 'express';
4
2
 
5
3
  import Base from './Base.js';
@@ -88,7 +86,6 @@ class AbstractController extends Base {
88
86
  this.logger.error(
89
87
  `Method ${verb} not exist for router. Please check your codebase`,
90
88
  );
91
- // eslint-disable-next-line no-continue
92
89
  continue;
93
90
  }
94
91
  for (const path in routes[verb]) {
@@ -112,7 +109,6 @@ class AbstractController extends Base {
112
109
  routeObject.handler
113
110
  }' for controller '${this.getConstructorName()}'`,
114
111
  );
115
- // eslint-disable-next-line no-continue
116
112
  continue;
117
113
  }
118
114
  }
@@ -300,14 +296,12 @@ class AbstractController extends Base {
300
296
  let realPath = path;
301
297
  if (typeof realPath !== 'string') {
302
298
  this.logger.error(`Path not a string ${realPath}. Please check it`);
303
- // eslint-disable-next-line no-continue
304
299
  continue;
305
300
  }
306
301
  if (!realPath.startsWith('/')) {
307
302
  method = realPath.split('/')[0]?.toLowerCase();
308
303
  if (!method) {
309
304
  this.logger.error(`Method not found for ${realPath}`);
310
- // eslint-disable-next-line no-continue
311
305
  continue;
312
306
  }
313
307
  realPath = realPath.substring(method.length);
@@ -316,7 +310,6 @@ class AbstractController extends Base {
316
310
  this.logger.error(
317
311
  `Method ${method} not exist for middleware. Please check your codebase`,
318
312
  );
319
- // eslint-disable-next-line no-continue
320
313
  continue;
321
314
  }
322
315
  const fullPath = `/${httpPath}/${realPath.toUpperCase()}`
package/modules/Base.js CHANGED
@@ -21,7 +21,7 @@ class Base {
21
21
  let l;
22
22
  try {
23
23
  l = this.#realLogger;
24
- } catch (e) {
24
+ } catch {
25
25
  console.warn(
26
26
  `You try to accees logger not from class. that can be ok in case of models.`,
27
27
  );
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-console */
2
1
  import path from 'node:path';
3
2
  import * as url from 'node:url';
4
3
  import Base from './Base.js';
@@ -35,7 +34,6 @@ class Cli extends Base {
35
34
  console.log('Available commands:');
36
35
  let commandsClasses = [];
37
36
  for (const c of commands) {
38
- // eslint-disable-next-line no-await-in-loop
39
37
  commandsClasses.push(import(this.commands[c]));
40
38
  // console.log(
41
39
  // ` \x1b[36m${c.padEnd(maxLength)}\x1b[0m - ${f.default.description}`,
@@ -43,7 +41,6 @@ class Cli extends Base {
43
41
  }
44
42
  commandsClasses = await Promise.all(commandsClasses);
45
43
  for (const [key, c] of Object.entries(commands)) {
46
- // eslint-disable-next-line no-await-in-loop
47
44
  console.log(
48
45
  ` \x1b[36m${c.padEnd(maxLength)}\x1b[0m - ${commandsClasses[key].default.description}`,
49
46
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptivestone/framework",
3
- "version": "5.0.0-beta.4",
3
+ "version": "5.0.0-beta.5",
4
4
  "description": "Adaptive stone node js framework",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -18,8 +18,8 @@
18
18
  "test": "vitest run",
19
19
  "t": "vitest --coverage=false --reporter=default",
20
20
  "prettier": "prettier --check '**/*.(js|jsx|ts|tsx|json|css|scss|md)'",
21
- "lint": "eslint '**/*.js'",
22
- "lint:fix": "eslint '**/*.js' --fix",
21
+ "lint": "eslint",
22
+ "lint:fix": "eslint --fix",
23
23
  "codestyle": "npm run prettier && npm run lint",
24
24
  "prepare": "husky",
25
25
  "cli": "node cliCommand",
@@ -50,12 +50,14 @@
50
50
  "yup": "^1.0.0"
51
51
  },
52
52
  "devDependencies": {
53
+ "@eslint/js": "^9.19.0",
53
54
  "@vitest/coverage-v8": "^3.0.0",
54
- "eslint": "^8.0.0",
55
- "eslint-config-airbnb-base": "^15.0.0",
55
+ "@vitest/eslint-plugin": "^1.1.25",
56
+ "eslint": "^9.0.0",
56
57
  "eslint-config-prettier": "^10.0.0",
58
+ "eslint-plugin-import": "^2.31.0",
57
59
  "eslint-plugin-prettier": "^5.0.0",
58
- "eslint-plugin-vitest": "^0.4.0",
60
+ "globals": "^15.14.0",
59
61
  "husky": "^9.0.0",
60
62
  "lint-staged": "^15.0.0",
61
63
  "mongodb-memory-server": "^10.0.0",
package/server.js CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-console */
2
1
  import EventEmitter from 'node:events';
3
2
  import { hrtime, loadEnvFile } from 'node:process';
4
3
  import * as url from 'node:url';
@@ -12,7 +11,7 @@ import Cache from './services/cache/Cache.js';
12
11
 
13
12
  try {
14
13
  loadEnvFile();
15
- } catch (e) {
14
+ } catch {
16
15
  console.warn('No env file found. This is ok. But please check youself.');
17
16
  }
18
17
 
@@ -323,7 +322,7 @@ class Server {
323
322
  function IsConstructor(f) {
324
323
  try {
325
324
  Reflect.construct(String, [], f);
326
- } catch (e) {
325
+ } catch {
327
326
  return false;
328
327
  }
329
328
  return true;
@@ -94,7 +94,7 @@ class Cache extends Base {
94
94
  }
95
95
  return value;
96
96
  });
97
- } catch (e) {
97
+ } catch {
98
98
  this.logger.warn(
99
99
  'Not able to parse json from redis cache. That can be a normal in case you store string here',
100
100
  );
@@ -43,7 +43,6 @@ class HttpServer extends Base {
43
43
  // eslint-disable-next-line no-unused-vars
44
44
  this.express.use((err, req, res, next) => {
45
45
  // error handling
46
- // eslint-disable-next-line no-console
47
46
  console.error(err.stack);
48
47
  // TODO
49
48
  res.status(500).json({ message: 'Something broke!' });
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { object } from 'yup';
2
2
  import Base from '../../../modules/Base.js';
3
3
 
4
4
  class AbstractMiddleware extends Base {
@@ -18,13 +18,13 @@ class AbstractMiddleware extends Base {
18
18
  // eslint-disable-next-line class-methods-use-this
19
19
  get relatedQueryParameters() {
20
20
  // For example yup.object().shape({page: yup.number().required(),limit: yup.number()})
21
- return yup.object().shape({});
21
+ return object().shape({});
22
22
  }
23
23
 
24
24
  // eslint-disable-next-line class-methods-use-this
25
25
  get relatedRequestParameters() {
26
26
  // For example yup.object().shape({page: yup.number().required(),limit: yup.number()})
27
- return yup.object().shape({});
27
+ return object().shape({});
28
28
  }
29
29
 
30
30
  get relatedReqParameters() {
@@ -27,6 +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
31
  i18next.use(BackendFS).init({
31
32
  backend: {
32
33
  loadPath: `${this.app.foldersConfig.locales}/{{lng}}/{{ns}}.json`,
@@ -98,7 +99,6 @@ class I18n extends AbstractMiddleware {
98
99
  for (const detectorName of this.detectorOrder) {
99
100
  const lng = this.detectors[detectorName](req);
100
101
  if (!lng) {
101
- // eslint-disable-next-line no-continue
102
102
  continue;
103
103
  }
104
104
  if (i18next.services.languageUtils.isSupportedCode(lng)) {
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { object, number } from 'yup';
2
2
  import AbstractMiddleware from './AbstractMiddleware.js';
3
3
  /**
4
4
  * Middleware for reusing pagination
@@ -10,9 +10,9 @@ class Pagination extends AbstractMiddleware {
10
10
 
11
11
  // eslint-disable-next-line class-methods-use-this
12
12
  get relatedQueryParameters() {
13
- return yup.object().shape({
14
- page: yup.number(),
15
- limit: yup.number(),
13
+ return object().shape({
14
+ page: number(),
15
+ limit: number(),
16
16
  });
17
17
  }
18
18
 
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { isSchema } from 'yup';
2
2
  import YupValidator from './drivers/YupValidator.js';
3
3
  import CustomValidator from './drivers/CustomValidator.js';
4
4
  import Base from '../../modules/Base.js';
@@ -30,7 +30,7 @@ class ValidateService extends Base {
30
30
  if (this.isValidatorExists(body)) {
31
31
  return body;
32
32
  }
33
- if (yup.isSchema(body)) {
33
+ if (isSchema(body)) {
34
34
  const yupValidator = new YupValidator(app, body);
35
35
  return yupValidator;
36
36
  }
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { ValidationError } from 'yup';
2
2
  import AbstractValidator from './AbstractValidator.js';
3
3
 
4
4
  class CustomValidator extends AbstractValidator {
@@ -19,7 +19,7 @@ class CustomValidator extends AbstractValidator {
19
19
  } catch (e) {
20
20
  this.logger.warn(`CustomValidator validateFields ${e}`);
21
21
  if (e.path) {
22
- throw new yup.ValidationError({
22
+ throw new ValidationError({
23
23
  [e.path]: e.message,
24
24
  });
25
25
  }
@@ -1,4 +1,4 @@
1
- import yup from 'yup';
1
+ import { ValidationError } from 'yup';
2
2
  import AbstractValidator from './AbstractValidator.js';
3
3
 
4
4
  class YupValidator extends AbstractValidator {
@@ -76,7 +76,7 @@ class YupValidator extends AbstractValidator {
76
76
  });
77
77
  }
78
78
 
79
- throw new yup.ValidationError({
79
+ throw new ValidationError({
80
80
  ...errorAnswer,
81
81
  });
82
82
  }
package/tests/setup.js CHANGED
@@ -64,9 +64,7 @@ beforeAll(async () => {
64
64
  nick: 'testUserNickName',
65
65
  },
66
66
  }).catch((e) => {
67
- // eslint-disable-next-line no-console
68
67
  console.error(e);
69
- // eslint-disable-next-line no-console
70
68
  console.info(
71
69
  'That error can happens in case you have custom user model. Please use global.testSetup.disableUserCreate flag to skip user creating',
72
70
  );
@@ -97,7 +95,7 @@ afterEach(async () => {
97
95
  await redisClient.connect();
98
96
  await clearRedisNamespace(redisClient, namespace);
99
97
  await redisClient.disconnect();
100
- } catch (err) {
98
+ } catch {
101
99
  // that ok. No redis connection
102
100
  }
103
101
  }
@@ -57,9 +57,7 @@ beforeAll(async () => {
57
57
  nick: 'testUserNickName',
58
58
  },
59
59
  }).catch((e) => {
60
- // eslint-disable-next-line no-console
61
60
  console.error(e);
62
- // eslint-disable-next-line no-console
63
61
  console.info(
64
62
  'That error can happens in case you have custom user model. Please use global.testSetup.disableUserCreate flag to skip user creating',
65
63
  );
@@ -90,7 +88,7 @@ afterEach(async () => {
90
88
  await redisClient.connect();
91
89
  await clearRedisNamespace(redisClient, namespace);
92
90
  await redisClient.disconnect();
93
- } catch (err) {
91
+ } catch {
94
92
  // that ok. No redis connection
95
93
  }
96
94
  }