@adaptivestone/framework 5.0.0-alpha.2 → 5.0.0-alpha.20

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 (50) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/commands/CreateUser.js +3 -1
  3. package/commands/GenerateRandomBytes.js +15 -0
  4. package/commands/migration/Migrate.js +1 -1
  5. package/config/auth.js +5 -1
  6. package/config/ipDetector.js +14 -0
  7. package/controllers/Auth.js +1 -1
  8. package/folderConfig.js +0 -1
  9. package/helpers/files.js +8 -8
  10. package/jsconfig.json +9 -0
  11. package/modules/AbstractCommand.js +2 -1
  12. package/modules/AbstractController.js +20 -16
  13. package/modules/AbstractModel.d.ts +48 -0
  14. package/modules/AbstractModel.js +20 -2
  15. package/modules/Base.d.ts +5 -4
  16. package/modules/Base.js +11 -1
  17. package/package.json +12 -15
  18. package/server.d.ts +7 -5
  19. package/server.js +11 -7
  20. package/services/cache/Cache.d.ts +2 -2
  21. package/services/cache/Cache.js +10 -6
  22. package/services/http/HttpServer.js +11 -19
  23. package/services/http/middleware/GetUserByToken.js +2 -1
  24. package/services/http/middleware/I18n.js +20 -21
  25. package/services/http/middleware/IpDetector.js +59 -0
  26. package/services/http/middleware/Pagination.js +3 -2
  27. package/services/http/middleware/RateLimiter.js +8 -2
  28. package/services/http/middleware/RequestParser.js +4 -1
  29. package/services/messaging/email/index.js +7 -15
  30. package/tests/setup.js +3 -1
  31. package/tests/setupVitest.js +1 -1
  32. package/types/TFoldersConfig.d.ts +0 -2
  33. package/.eslintrc.cjs +0 -41
  34. package/controllers/Auth.test.js +0 -451
  35. package/controllers/Home.test.js +0 -12
  36. package/models/Migration.test.js +0 -20
  37. package/models/Sequence.test.js +0 -43
  38. package/models/User.test.js +0 -143
  39. package/modules/Modules.test.js +0 -18
  40. package/services/cache/Cache.test.js +0 -81
  41. package/services/http/middleware/Auth.test.js +0 -57
  42. package/services/http/middleware/Cors.test.js +0 -147
  43. package/services/http/middleware/GetUserByToken.test.js +0 -108
  44. package/services/http/middleware/I18n.test.js +0 -96
  45. package/services/http/middleware/PrepareAppInfo.test.js +0 -26
  46. package/services/http/middleware/RateLimiter.test.js +0 -233
  47. package/services/http/middleware/RequestParser.test.js +0 -112
  48. package/services/http/middleware/Role.test.js +0 -93
  49. package/services/http/middleware/StaticFiles.js +0 -59
  50. package/services/validate/ValidateService.test.js +0 -107
package/CHANGELOG.md CHANGED
@@ -1,3 +1,92 @@
1
+ ### 5.0.0-alpha.20
2
+
3
+ [UPDATE] update deps
4
+ [UPDATE] #realLogger do not throw error in a scecific cases (model toJSON({virtual:true}))
5
+
6
+ ### 5.0.0-alpha.19
7
+
8
+ [NEW] added modelSchemaOptions for models
9
+
10
+ ### 5.0.0-alpha.18
11
+
12
+ [BREAKING] default auth responce changed to be unified. {token, user} = > {data:{token, user}}
13
+ [UPDATE] RateLimiter updae key generation
14
+
15
+ ### 5.0.0-alpha.17
16
+
17
+ [NEW] generateRandomBytes command
18
+ [UPDATE] update deps
19
+
20
+ ### 5.0.0-alpha.16
21
+
22
+ [UPDATE] no warning of direct usage body and query
23
+ [UPDATE] update deps
24
+
25
+ ### 5.0.0-alpha.15
26
+
27
+ [BUG] fix bug with pagination
28
+ [UPDATE] update deps
29
+
30
+ ### 5.0.0-alpha.14
31
+
32
+ [NEW] add types for Abstract model (wip)
33
+
34
+ ### 5.0.0-alpha.13
35
+
36
+ [UPDATE] update deps
37
+ [UPDATE] update i18n internal implementation
38
+ [CHANGE] disable https server view
39
+
40
+ ### 5.0.0-alpha.12
41
+
42
+ [UPDATE] update deps
43
+
44
+ ### 5.0.0-alpha.11
45
+
46
+ [UPDATE] update deps
47
+
48
+ ### 5.0.0-alpha.10
49
+
50
+ [UPDATE] update deps
51
+ [NEW] IpDetector middleware that support detecting proxy and X-Forwarded-For header
52
+ [BREAKING] RateLimiter now need to have IpDetector middleware before
53
+
54
+ ### 5.0.0-alpha.9
55
+
56
+ [UPDATE] update deps
57
+ [BREAKING] removing staticFiles middleware as it not used in projects anymore. Docs with nginx config will be provided
58
+ [BREAKING] remove default AUTH_SALT. It should be provided on a app level now
59
+ [BREAKING] Vitest 2.0.0 https://vitest.dev/guide/migration.html#migrating-to-vitest-2-0
60
+
61
+ ### 5.0.0-alpha.8
62
+
63
+ [UPDATE] replace dotenv with loadEnvFile
64
+ [UPDATE] replace nodemon with node --watch (dev only)
65
+ [BREAKING] Minimum node version is 20.12 as for now (process.loadEnvFile)
66
+
67
+ ### 5.0.0-alpha.7
68
+
69
+ [UPDATE] deps update
70
+
71
+ ### 5.0.0-alpha.6
72
+
73
+ [UPDATE] Update internal documentation (jsdoc, d.ts)
74
+
75
+ ### 5.0.0-alpha.5
76
+
77
+ [UPDATE] More verbose errors for rapsing body request.
78
+ [UPDATE] deps update
79
+
80
+ ### 5.0.0-alpha.4
81
+
82
+ [UPDATE] Update rate-limiter-flexible to v5
83
+ [CHANGE] Cache update redis.setEX to redis.set(..,..,{EX:xx}) as setEX deprecated
84
+
85
+ ### 5.0.0-alpha.3
86
+
87
+ [UPDATE] deps update
88
+ [FIX] Migration commands apply
89
+
1
90
  ### 5.0.0-alpha.2
2
91
 
3
92
  [UPDATE] deps update
@@ -60,7 +60,9 @@ class CreateUser extends AbstractCommand {
60
60
 
61
61
  await user.generateToken();
62
62
 
63
- this.logger.info(`User was created/updated ${JSON.stringify(user, 0, 4)}`);
63
+ this.logger.info(
64
+ `User was created/updated ${JSON.stringify(user, null, 4)}`,
65
+ );
64
66
 
65
67
  return user;
66
68
  }
@@ -0,0 +1,15 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import AbstractCommand from '../modules/AbstractCommand.js';
3
+
4
+ class GenerateRandomBytes extends AbstractCommand {
5
+ async run() {
6
+ const sizes = [16, 32, 64, 128, 256];
7
+ for (const size of sizes) {
8
+ const bytes = randomBytes(size).toString('hex');
9
+ this.logger.info(`${size} bytes: ${bytes}`);
10
+ }
11
+ return true;
12
+ }
13
+ }
14
+
15
+ export default GenerateRandomBytes;
@@ -36,7 +36,7 @@ class Migrate extends AbstractCommand {
36
36
  for (const migration of migrations) {
37
37
  this.logger.info(`=== Start migration ${migration.file} ===`);
38
38
  // eslint-disable-next-line no-await-in-loop
39
- const MigrationCommand = await import(migration.path);
39
+ const { default: MigrationCommand } = await import(migration.path);
40
40
  const migrationCommand = new MigrationCommand(this.app);
41
41
  // eslint-disable-next-line no-await-in-loop
42
42
  await migrationCommand.up();
package/config/auth.js CHANGED
@@ -1,5 +1,9 @@
1
1
  export default {
2
2
  hashRounds: 64,
3
- saltSecret: process.env.AUTH_SALT || 'gdfg45667_%%^trterte',
3
+ saltSecret:
4
+ process.env.AUTH_SALT ||
5
+ console.error(
6
+ 'AUTH_SALT is not defined. You can "npm run cli generateRandomBytes" and use it',
7
+ ),
4
8
  isAuthWithVefificationFlow: true,
5
9
  };
@@ -0,0 +1,14 @@
1
+ export default {
2
+ headers: ['X-Forwarded-For'],
3
+ trustedProxy: [
4
+ // list of trusted proxies.
5
+ '169.254.0.0/16', // linklocal
6
+ 'fe80::/10', // linklocal
7
+ '127.0.0.1/8', // loopback
8
+ '::1/128', // loopback
9
+ '10.0.0.0/8', // uniquelocal
10
+ '172.16.0.0/12', // uniquelocal
11
+ '192.168.0.0/16', // uniquelocal
12
+ 'fc00::/7', // uniquelocal
13
+ ],
14
+ };
@@ -83,7 +83,7 @@ class Auth extends AbstractController {
83
83
  }
84
84
  const token = await user.generateToken();
85
85
 
86
- return res.status(200).json({ token, user: user.getPublic() });
86
+ return res.status(200).json({ data: { token, user: user.getPublic() } });
87
87
  }
88
88
 
89
89
  async postRegister(req, res) {
package/folderConfig.js CHANGED
@@ -6,7 +6,6 @@ export default {
6
6
  models: path.resolve('./models'),
7
7
  controllers: path.resolve('./controllers'),
8
8
  views: path.resolve('./views'),
9
- public: path.resolve('./public'),
10
9
  locales: path.resolve('./locales'),
11
10
  emails: path.resolve('./services/messaging/email/templates'),
12
11
  commands: path.resolve('./commands'),
package/helpers/files.js CHANGED
@@ -8,7 +8,7 @@ const getFilesPathWithInheritance = async ({
8
8
  loggerFileType = '',
9
9
  filter: { startWithCapital = true, notTests = true, notHidden = true } = {},
10
10
  }) => {
11
- let [internalFiles, externalFiles] = await Promise.all([
11
+ const [internalFiles, externalFiles] = await Promise.all([
12
12
  fs.readdir(internalFolder, { recursive: true, withFileTypes: true }),
13
13
  fs.readdir(externalFolder, { recursive: true, withFileTypes: true }),
14
14
  ]);
@@ -33,24 +33,24 @@ const getFilesPathWithInheritance = async ({
33
33
  return true;
34
34
  };
35
35
 
36
- internalFiles = internalFiles
36
+ const internalFilesString = internalFiles
37
37
  .filter(filterIndexFile)
38
38
  .map((fileDirent) =>
39
- join(fileDirent.path, fileDirent.name)
39
+ join(fileDirent.parentPath, fileDirent.name)
40
40
  .replace(`${internalFolder}/`, '')
41
41
  .replace(`${internalFolder}`, ''),
42
42
  );
43
- externalFiles = externalFiles
43
+ const externalFilesString = externalFiles
44
44
  .filter(filterIndexFile)
45
45
  .map((fileDirent) =>
46
- join(fileDirent.path, fileDirent.name)
46
+ join(fileDirent.parentPath, fileDirent.name)
47
47
  .replace(`${externalFolder}/`, '')
48
48
  .replace(`${externalFolder}`, ''),
49
49
  );
50
50
 
51
51
  const filesToLoad = [];
52
- for (const file of internalFiles) {
53
- if (externalFiles.includes(file)) {
52
+ for (const file of internalFilesString) {
53
+ if (externalFilesString.includes(file)) {
54
54
  logger(
55
55
  `Skipping register INTERNAL file '${file}' ${
56
56
  loggerFileType ? `of type ${loggerFileType}` : ''
@@ -64,7 +64,7 @@ const getFilesPathWithInheritance = async ({
64
64
  }
65
65
  }
66
66
 
67
- for (const file of externalFiles) {
67
+ for (const file of externalFilesString) {
68
68
  filesToLoad.push({
69
69
  path: join(externalFolder, file),
70
70
  file,
package/jsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "node16",
4
+ "target": "ES2022",
5
+ "moduleResolution": "node16",
6
+ "checkJs": true
7
+ },
8
+ "exclude": ["node_modules"]
9
+ }
@@ -13,10 +13,11 @@ class AbstractCommand extends Base {
13
13
 
14
14
  /**
15
15
  * Entry point to every command. This method should be overridden
16
- * @override
16
+ * @return {Promise<boolean>} resut
17
17
  */
18
18
  async run() {
19
19
  this.logger.error('You should implement run method');
20
+ return false;
20
21
  }
21
22
 
22
23
  static get loggerGroup() {
@@ -25,10 +25,12 @@ class AbstractController extends Base {
25
25
  const { routes } = this;
26
26
  let httpPath = this.getHttpPath();
27
27
 
28
+ // @ts-ignore
28
29
  if (this.getExpressPath) {
29
30
  this.logger.warn(
30
31
  `getExpressPath deprecated. Please use getHttpPath instead. Will be removed on v5`,
31
32
  );
33
+ // @ts-ignore
32
34
  httpPath = this.getExpressPath();
33
35
  }
34
36
 
@@ -58,6 +60,7 @@ class AbstractController extends Base {
58
60
  httpPath,
59
61
  );
60
62
  const middlewaresInfo = this.parseMiddlewares(
63
+ // @ts-ignore
61
64
  this.constructor.middleware,
62
65
  httpPath,
63
66
  );
@@ -193,22 +196,22 @@ class AbstractController extends Base {
193
196
  errors: err.message,
194
197
  });
195
198
  }
196
- req.body = new Proxy(req.body, {
197
- get: (target, prop) => {
198
- this.logger.warn(
199
- 'Please not use "req.body" directly. Implement "request" and use "req.appInfo.request" ',
200
- );
201
- return target[prop];
202
- },
203
- });
204
- req.query = new Proxy(req.query, {
205
- get: (target, prop) => {
206
- this.logger.warn(
207
- 'Please not use "req.query" directly. Implement "query" and use "req.appInfo.query" ',
208
- );
209
- return target[prop];
210
- },
211
- });
199
+ // req.body = new Proxy(req.body, {
200
+ // get: (target, prop) => {
201
+ // this.logger.warn(
202
+ // 'Please not use "req.body" directly. Implement "request" and use "req.appInfo.request" ',
203
+ // );
204
+ // return target[prop];
205
+ // },
206
+ // });
207
+ // req.query = new Proxy(req.query, {
208
+ // get: (target, prop) => {
209
+ // this.logger.warn(
210
+ // 'Please not use "req.query" directly. Implement "query" and use "req.appInfo.query" ',
211
+ // );
212
+ // return target[prop];
213
+ // },
214
+ // });
212
215
 
213
216
  if (!routeObject.handler) {
214
217
  this.logger.error(`Route object have no handler defined`);
@@ -370,6 +373,7 @@ class AbstractController extends Base {
370
373
  * You should provide path relative to controller and then array of middlewares to apply.
371
374
  * Order is matter.
372
375
  * Be default path apply to ANY' method, but you can preattach 'METHOD' into patch to scope patch to this METHOD
376
+ * @returns {Map<string, Array<typeof import('../services/http/middleware/AbstractMiddleware.js').default | [Function, ...any]>>}
373
377
  * @example
374
378
  * return new Map([
375
379
  * ['/*', [GetUserByToken]] // for any method for this controller
@@ -0,0 +1,48 @@
1
+ import type Base from './Base.js';
2
+ import { Model, Schema } from 'mongoose';
3
+ import type Server from '../server.js';
4
+
5
+ interface AbstractModel<T extends Document> extends Model, Base {
6
+ constructor(app: Server['app'], callback?: () => void);
7
+
8
+ /**
9
+ * Return itself for internal methods.
10
+ */
11
+ getSuper(): this;
12
+
13
+ /**
14
+ * Model schema in Js object (not a mongoose schema).
15
+ */
16
+ get modelSchema(): Object;
17
+
18
+ /**
19
+ * Mongoose schema.
20
+ */
21
+ mongooseSchema: Schema<T>;
22
+
23
+ /**
24
+ * Acces to mongoose model too
25
+ */
26
+ mongooseModel: Model<T>;
27
+
28
+ /**
29
+ * Init custom hooks before model
30
+ */
31
+ initHooks(): void;
32
+ }
33
+
34
+ abstract class AbstractModel<T extends Document>
35
+ extends Model
36
+ implements AbstractModel
37
+ {
38
+ abstract get modelSchema(): Object;
39
+
40
+ /**
41
+ * Return itself for internal methods.
42
+ */
43
+ static abstract getSuper(): this;
44
+
45
+ mongooseSchema: Schema<T> = new Schema<T>(this.modelSchema);
46
+ }
47
+
48
+ export default AbstractModel;
@@ -2,13 +2,20 @@ import mongoose from 'mongoose';
2
2
  import Base from './Base.js';
3
3
 
4
4
  class AbstractModel extends Base {
5
+ mongooseSchema = null;
6
+
7
+ mongooseModel = null;
8
+
5
9
  /**
6
- * @param {import('../server')} app //TODO change to *.d.ts as this is a Server, not app
10
+ * @param {import('../server.js').default['app']} app //TODO change to *.d.ts as this is a Server, not app
7
11
  * @param function callback optional callback when connection ready
8
12
  */
9
13
  constructor(app, callback = () => {}) {
10
14
  super(app);
11
- this.mongooseSchema = mongoose.Schema(this.modelSchema);
15
+ this.mongooseSchema = new mongoose.Schema(
16
+ this.modelSchema,
17
+ this.modelSchemaOptions,
18
+ );
12
19
  mongoose.set('strictQuery', true);
13
20
  this.mongooseSchema.set('timestamps', true);
14
21
  this.mongooseSchema.set('minimize', false);
@@ -22,6 +29,9 @@ class AbstractModel extends Base {
22
29
  );
23
30
  if (!mongoose.connection.readyState) {
24
31
  this.app.events.on('shutdown', async () => {
32
+ this.logger.verbose(
33
+ 'Shutdown was called. Closing all mongoose connections',
34
+ );
25
35
  for (const c of mongoose.connections) {
26
36
  c.close(true);
27
37
  }
@@ -51,6 +61,14 @@ class AbstractModel extends Base {
51
61
  return {};
52
62
  }
53
63
 
64
+ /**
65
+ * Mongoose schema options
66
+ */
67
+ // eslint-disable-next-line class-methods-use-this
68
+ get modelSchemaOptions() {
69
+ return {};
70
+ }
71
+
54
72
  static get loggerGroup() {
55
73
  return 'model';
56
74
  }
package/modules/Base.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import winston from 'winston';
2
- import Server from '../server';
1
+ import type winston from 'winston';
2
+ import type Server from '../server.js';
3
+ import type { Dirent } from 'node.fs';
3
4
 
4
5
  declare class Base {
5
6
  app: Server['app'];
@@ -26,11 +27,11 @@ declare class Base {
26
27
  getFilesPathWithInheritance(
27
28
  internalFolder: string,
28
29
  externalFolder: string,
29
- ): Promise<string[]>;
30
+ ): Promise<{ path: string; file: string }[]>;
30
31
 
31
32
  /**
32
33
  * Return logger group. Just to have all logs groupped logically
33
34
  */
34
35
  static get loggerGroup(): string;
35
36
  }
36
- export = Base;
37
+ export default Base;
package/modules/Base.js CHANGED
@@ -18,7 +18,17 @@ class Base {
18
18
  * Optimzation to lazy load logger. It will be inited only on request
19
19
  */
20
20
  get logger() {
21
- if (!this.#realLogger) {
21
+ let l;
22
+ try {
23
+ l = this.#realLogger;
24
+ } catch (e) {
25
+ console.warn(
26
+ `You try to accees logger not from class. that can be ok in case of models.`,
27
+ );
28
+ return null;
29
+ }
30
+
31
+ if (!l) {
22
32
  this.#realLogger = this.getLogger(
23
33
  this.constructor.loggerGroup + this.getConstructorName(),
24
34
  );
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@adaptivestone/framework",
3
- "version": "5.0.0-alpha.2",
3
+ "version": "5.0.0-alpha.20",
4
4
  "description": "Adaptive stone node js framework",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "engines": {
8
- "node": ">=18.17.0"
8
+ "node": ">=20.12.0"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
@@ -13,9 +13,10 @@
13
13
  },
14
14
  "homepage": "https://framework.adaptivestone.com/",
15
15
  "scripts": {
16
- "dev": "nodemon ./index.js",
17
- "prod": "nodemon ./cluster.js",
16
+ "dev": "node --watch ./index.js",
17
+ "prod": "node --watch ./cluster.js",
18
18
  "test": "vitest run",
19
+ "t": "vitest --coverage=false --reporter=default",
19
20
  "prettier": "prettier --check '**/*.(js|jsx|ts|tsx|json|css|scss|md)'",
20
21
  "lint": "eslint '**/*.js'",
21
22
  "lint:fix": "eslint '**/*.js' --fix",
@@ -30,40 +31,36 @@
30
31
  "license": "MIT",
31
32
  "dependencies": {
32
33
  "deepmerge": "^4.2.2",
33
- "dotenv": "^16.0.0",
34
34
  "express": "^4.17.1",
35
35
  "formidable": "^3.5.1",
36
36
  "html-to-text": "^9.0.3",
37
37
  "i18next": "^23.2.8",
38
- "i18next-chained-backend": "^4.0.0",
39
38
  "i18next-fs-backend": "^2.0.0",
40
- "juice": "^10.0.0",
41
- "mime": "^4.0.0",
39
+ "juice": "^11.0.0",
42
40
  "minimist": "^1.2.5",
43
41
  "mongoose": "^8.0.0",
44
42
  "nodemailer": "^6.6.3",
45
43
  "nodemailer-sendmail-transport": "^1.0.2",
46
44
  "nodemailer-stub-transport": "^1.1.0",
47
45
  "pug": "^3.0.2",
48
- "rate-limiter-flexible": "^4.0.0",
46
+ "rate-limiter-flexible": "^5.0.0",
49
47
  "redis": "^4.3.1",
50
48
  "winston": "^3.3.3",
51
- "winston-transport-sentry-node": "^2.0.0",
49
+ "winston-transport-sentry-node": "^3.0.0",
52
50
  "yup": "^1.0.0"
53
51
  },
54
52
  "devDependencies": {
55
- "@vitest/coverage-v8": "^1.0.0",
53
+ "@vitest/coverage-v8": "^2.0.0",
56
54
  "eslint": "^8.0.0",
57
55
  "eslint-config-airbnb-base": "^15.0.0",
58
56
  "eslint-config-prettier": "^9.0.0",
59
57
  "eslint-plugin-prettier": "^5.0.0",
60
- "eslint-plugin-vitest": "^0.3.1",
58
+ "eslint-plugin-vitest": "^0.4.0",
61
59
  "husky": "^9.0.0",
62
60
  "lint-staged": "^15.0.0",
63
- "mongodb-memory-server": "^9.0.0",
64
- "nodemon": "^3.0.1",
61
+ "mongodb-memory-server": "^10.0.0",
65
62
  "prettier": "^3.0.0",
66
- "vitest": "^1.0.0"
63
+ "vitest": "^2.0.0"
67
64
  },
68
65
  "lint-staged": {
69
66
  "**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
package/server.d.ts CHANGED
@@ -9,6 +9,8 @@ import BaseCli from './modules/BaseCli';
9
9
  import Cache from './services/cache/Cache';
10
10
  import winston from 'winston';
11
11
 
12
+ import HttpServer from './services/http/HttpServer.js';
13
+
12
14
  type ServerConfig = {
13
15
  folders: ExpandDeep<TFolderConfig>;
14
16
  };
@@ -24,7 +26,7 @@ declare class Server {
24
26
  events: EventEmitter;
25
27
  get cache(): Server['cacheService'];
26
28
  get logger(): winston.Logger;
27
- httpServer: null;
29
+ httpServer: HttpServer | null;
28
30
  controllerManager: null;
29
31
  };
30
32
  cacheService: Cache;
@@ -33,7 +35,7 @@ declare class Server {
33
35
  configs: Map<string, {}>;
34
36
  models: Map<string, MongooseModel<any>>;
35
37
  };
36
- cli: boolean;
38
+ cli: null | BaseCli;
37
39
 
38
40
  /**
39
41
  * Construct new server
@@ -68,7 +70,7 @@ declare class Server {
68
70
  * @see updateConfig
69
71
  * @TODO generate that based on real data
70
72
  */
71
- getConfig(configName: string): {};
73
+ getConfig(configName: string): { [key: string]: any };
72
74
 
73
75
  /**
74
76
  * Return or create new logger instance. This is a main logger instance
@@ -79,7 +81,7 @@ declare class Server {
79
81
  * Primary designed for tests when we need to update some configs before start testing
80
82
  * Should be called before any initialization was done
81
83
  */
82
- updateConfig(configName: string, config: {}): {};
84
+ updateConfig(configName: string, config: {}): { [key: string]: any };
83
85
 
84
86
  /**
85
87
  * Return model from {modelName} (file name) on model folder.
@@ -93,4 +95,4 @@ declare class Server {
93
95
  runCliCommand(commandName: string, args: {}): Promise<BaseCli['run']>;
94
96
  }
95
97
 
96
- export = Server;
98
+ export default Server;
package/server.js CHANGED
@@ -1,16 +1,21 @@
1
1
  /* eslint-disable no-console */
2
2
  import EventEmitter from 'node:events';
3
- import { hrtime } from 'node:process';
3
+ import { hrtime, loadEnvFile } from 'node:process';
4
4
  import * as url from 'node:url';
5
5
  import path from 'node:path';
6
6
 
7
- import 'dotenv/config';
8
7
  import merge from 'deepmerge';
9
8
  import winston from 'winston';
10
9
  import { getFilesPathWithInheritance } from './helpers/files.js';
11
10
  import { consoleLogger } from './helpers/logger.js';
12
11
  import Cache from './services/cache/Cache.js';
13
12
 
13
+ try {
14
+ loadEnvFile();
15
+ } catch (e) {
16
+ console.warn('No env file found. This is ok. But please check youself.');
17
+ }
18
+
14
19
  /**
15
20
  * Main framework class.
16
21
  */
@@ -19,6 +24,8 @@ class Server {
19
24
 
20
25
  #isInited = false;
21
26
 
27
+ cli = null;
28
+
22
29
  /**
23
30
  * Construct new server
24
31
  * @param {Object} config main config object
@@ -27,7 +34,6 @@ class Server {
27
34
  * @param {String} config.folders.models path to folder with moidels files
28
35
  * @param {String} config.folders.controllers path to folder with controllers files
29
36
  * @param {String} config.folders.views path to folder with view files
30
- * @param {String} config.folders.public path to folder with public files
31
37
  * @param {String} config.folders.locales path to folder with locales files
32
38
  * @param {String} config.folders.emails path to folder with emails files
33
39
  */
@@ -56,13 +62,11 @@ class Server {
56
62
  models: new Map(),
57
63
  modelConstructors: new Map(),
58
64
  };
59
-
60
- this.cli = false;
61
65
  }
62
66
 
63
67
  /**
64
68
  * Start server (http + init all http ralated functions)
65
- * @param <Promise>callbackBefore404 code that should be executed before adding page 404
69
+ * @param {Function} callbackBefore404 code that should be executed before adding page 404
66
70
  * @returns {Promise}
67
71
  */
68
72
  async startServer(callbackBefore404 = async () => Promise.resolve()) {
@@ -350,7 +354,7 @@ class Server {
350
354
  * Return model from {modelName} (file name) on model folder.
351
355
  * Support cache
352
356
  * @param {String} modelName name on config file to load
353
- * @returns {import('mongoose').Model}
357
+ * @returns {import('mongoose').Model | false| {}}
354
358
  */
355
359
  getModel(modelName) {
356
360
  if (modelName.endsWith('s')) {
@@ -1,5 +1,5 @@
1
1
  import Base from '../../modules/Base';
2
- import Server from '../../server';
2
+ import Server from '../../server.js';
3
3
 
4
4
  declare class Cache extends Base {
5
5
  app: Server['app'];
@@ -32,4 +32,4 @@ declare class Cache extends Base {
32
32
  removeKey(key: string): Promise<number>;
33
33
  }
34
34
 
35
- export = Cache;
35
+ export default Cache;