@adaptivestone/framework 2.17.0 → 3.0.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.
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@adaptivestone/framework",
3
- "version": "2.17.0",
3
+ "version": "3.0.0",
4
4
  "description": "Adaptive stone node js framework",
5
5
  "main": "index.js",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://gitlab.com/adaptivestone/framework"
9
9
  },
10
+ "homepage": "https://framework.adaptivestone.com/",
10
11
  "scripts": {
11
12
  "dev": "nodemon ./index.js",
12
13
  "prod": "nodemon ./cluster.js",
@@ -25,7 +26,6 @@
25
26
  "license": "MIT",
26
27
  "dependencies": {
27
28
  "bcrypt": "^5.0.1",
28
- "body-parser": "^1.19.0",
29
29
  "cors": "^2.8.5",
30
30
  "deepmerge": "^4.2.2",
31
31
  "dotenv": "^10.0.0",
@@ -36,7 +36,7 @@
36
36
  "i18next-fs-backend": "^1.1.1",
37
37
  "i18next-http-middleware": "^3.1.4",
38
38
  "minimist": "^1.2.5",
39
- "mongoose": "^5.13.3",
39
+ "mongoose": "^6.0.0",
40
40
  "nodemailer": "^6.6.3",
41
41
  "nodemailer-sendmail-transport": "^1.0.2",
42
42
  "nodemailer-stub-transport": "^1.1.0",
@@ -44,21 +44,20 @@
44
44
  "pug": "^3.0.2",
45
45
  "rate-limiter-flexible": "^2.2.4",
46
46
  "redis": "^3.1.2",
47
- "validator": "^13.6.0",
48
47
  "winston": "^3.3.3",
49
48
  "winston-transport-sentry-node": "^2.0.0",
50
49
  "yup": "^0.32.9"
51
50
  },
52
51
  "devDependencies": {
53
- "eslint": "^7.31.0",
54
- "eslint-config-airbnb-base": "^14.2.1",
52
+ "eslint": "^8.0.0",
53
+ "eslint-config-airbnb-base": "^15.0.0",
55
54
  "eslint-config-prettier": "^8.3.0",
56
55
  "eslint-plugin-import": "^2.23.4",
57
- "eslint-plugin-jest": "^24.4.0",
56
+ "eslint-plugin-jest": "^25.0.0",
58
57
  "husky": "^7.0.0",
59
58
  "jest": "^27.0.6",
60
- "lint-staged": "^11.1.1",
61
- "mongodb-memory-server": "^7.3.4",
59
+ "lint-staged": "^12.0.0",
60
+ "mongodb-memory-server": "^8.0.2",
62
61
  "nodemon": "^2.0.12",
63
62
  "supertest": "^6.1.4"
64
63
  },
@@ -66,10 +65,5 @@
66
65
  "**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
67
66
  "prettier --write"
68
67
  ]
69
- },
70
- "config": {
71
- "mongodbMemoryServer": {
72
- "version": "4.4.6"
73
- }
74
68
  }
75
69
  }
package/server.d.ts CHANGED
@@ -6,6 +6,7 @@ import EventEmitter from 'events';
6
6
  import { Model as MongooseModel, Schema } from 'mongoose';
7
7
 
8
8
  import BaseCli from './modules/BaseCli';
9
+ import Cache from './services/cache/Cache';
9
10
 
10
11
  type ServerConfig = {
11
12
  folders: ExpandDeep<TFolderConfig>;
@@ -20,10 +21,11 @@ declare class Server {
20
21
  updateConfig: Server['updateConfig'];
21
22
  foldersConfig: Server['config'];
22
23
  events: EventEmitter;
23
- get cache(): Server['cache'];
24
+ get cache(): Server['cacheService'];
24
25
  httpServer: null;
25
26
  controllerManager: null;
26
27
  };
28
+ cacheService: Cache;
27
29
 
28
30
  cache: {
29
31
  configs: Map<string, {}>;
package/server.js CHANGED
@@ -124,7 +124,7 @@ class Server {
124
124
  updateConfig(configName, config) {
125
125
  // const confName = configName.charAt(0).toUpperCase() + configName.slice(1);
126
126
  const conf = this.getConfig(configName);
127
- const newConf = Object.assign(conf, config);
127
+ const newConf = Object.assign(conf, config); // TODO deep clone
128
128
  this.cache.configs.set(configName, newConf);
129
129
  return newConf;
130
130
  }
@@ -136,6 +136,11 @@ class Server {
136
136
  * @returns {import('mongoose').Model}
137
137
  */
138
138
  getModel(modelName) {
139
+ if (modelName.endsWith('s')) {
140
+ console.warn(
141
+ `Probably your model name '${modelName}' in plural from. Try to avoid plural form`,
142
+ );
143
+ }
139
144
  if (!this.cache.models.has(modelName)) {
140
145
  const Model = this.getFileWithExtendingInhirence('models', modelName);
141
146
  if (!Model) {
@@ -0,0 +1,22 @@
1
+ import Base from '../../modules/Base';
2
+ import Server from '../../server';
3
+
4
+ declare class Cache extends Base {
5
+ app: Server['app'];
6
+
7
+ constructor(app: Server['app']);
8
+
9
+ /**
10
+ * Get value from cache. Set and get if not eists
11
+ * @param key key to check
12
+ * @param onNotFound callback that will be executed if value not found on cahce
13
+ * @param storeTime how long we should store value on cache
14
+ */
15
+ getSetValue(
16
+ key: String,
17
+ onNotFound: () => Promise<any>,
18
+ storeTime: number,
19
+ ): Promise<any>;
20
+ }
21
+
22
+ export = Cache;
@@ -57,6 +57,10 @@ class Cache extends Base {
57
57
  this.promiseMapping.delete(key);
58
58
  return result;
59
59
  }
60
+
61
+ static get loggerGroup() {
62
+ return 'Cache_';
63
+ }
60
64
  }
61
65
 
62
66
  module.exports = Cache;
@@ -1,13 +1,13 @@
1
1
  const express = require('express');
2
2
  const http = require('http');
3
3
  const path = require('path');
4
- const bodyParser = require('body-parser');
5
4
  const cors = require('cors');
6
5
 
7
6
  const i18next = require('i18next');
8
7
  const i18nextMiddleware = require('i18next-http-middleware');
9
8
  const BackendFS = require('i18next-fs-backend');
10
9
  const Backend = require('i18next-chained-backend');
10
+ const PrepareAppInfoMiddleware = require('./middleware/PrepareAppInfo');
11
11
 
12
12
  const Base = require('../../modules/Base');
13
13
 
@@ -41,11 +41,13 @@ class HttpServer extends Base {
41
41
  origin: httpConfig.corsDomains,
42
42
  }),
43
43
  ); // todo whitelist
44
- this.express.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
45
- this.express.use(bodyParser.json({ limit: '50mb' }));
44
+ this.express.use(express.urlencoded({ limit: '50mb', extended: true }));
45
+ this.express.use(express.json({ limit: '50mb' }));
46
46
  this.express.use(express.static(folderConfig.folders.public));
47
47
  this.express.use(express.static('./public'));
48
48
 
49
+ this.express.use(new PrepareAppInfoMiddleware(this.app).getMiddleware());
50
+
49
51
  // As exprress will check numbersof arguments
50
52
  // eslint-disable-next-line no-unused-vars
51
53
  this.express.use((err, req, res, next) => {
@@ -1,6 +1,20 @@
1
1
  const Base = require('../../../modules/Base');
2
2
 
3
3
  class AbstractMiddleware extends Base {
4
+ constructor(app, params) {
5
+ super(app);
6
+ this.params = params;
7
+ }
8
+
9
+ static get description() {
10
+ return ' Middleware description. Please provide own';
11
+ }
12
+
13
+ async middleware(req, res, next) {
14
+ this.logger.warn('Middleware is not implemented');
15
+ next();
16
+ }
17
+
4
18
  getMiddleware() {
5
19
  return this.middleware.bind(this);
6
20
  }
@@ -1,6 +1,10 @@
1
1
  const AbstractMiddleware = require('./AbstractMiddleware');
2
2
 
3
3
  class AuthMiddleware extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Allow to pass only if the user provided. Please use any middleware that provide user instance before';
6
+ }
7
+
4
8
  async middleware(req, res, next) {
5
9
  if (!req.appInfo.user) {
6
10
  this.logger.info('User try to access resource without credentials');
@@ -1,6 +1,10 @@
1
1
  const AbstractMiddleware = require('./AbstractMiddleware');
2
2
 
3
3
  class GetUserByToken extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Grab a token and try to parse the user from it. It user exist will add req.appInfo.user variable';
6
+ }
7
+
4
8
  async middleware(req, res, next) {
5
9
  let { token } = req.body;
6
10
  if (!token) {
@@ -1,6 +1,10 @@
1
1
  const AbstractMiddleware = require('./AbstractMiddleware');
2
2
 
3
3
  class PrepareAppInfo extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Basic middleware that creates "req.appInfo" object';
6
+ }
7
+
4
8
  async middleware(req, res, next) {
5
9
  if (!req.appInfo) {
6
10
  req.appInfo = {
@@ -10,8 +10,12 @@ const mongoose = require('mongoose');
10
10
  const AbstractMiddleware = require('./AbstractMiddleware');
11
11
 
12
12
  class RateLimiter extends AbstractMiddleware {
13
+ static get description() {
14
+ return 'Rate limiter middleware. Limit amount of request. Please refer to documentation';
15
+ }
16
+
13
17
  constructor(app, params) {
14
- super(app);
18
+ super(app, params);
15
19
  const limiterOptions = this.app.getConfig('rateLimiter');
16
20
  this.finalOptions = merge(limiterOptions, params);
17
21
 
@@ -0,0 +1,29 @@
1
+ const AbstractMiddleware = require('./AbstractMiddleware');
2
+
3
+ class RoleMiddleware extends AbstractMiddleware {
4
+ static get description() {
5
+ return 'Check user role (user.roles property). If the user has no role then stop request and return error. OR logic (any role will pass user)';
6
+ }
7
+
8
+ async middleware(req, res, next) {
9
+ const { user } = req.appInfo;
10
+
11
+ if (!user) {
12
+ return res.status(401).send();
13
+ }
14
+
15
+ let hasRole = false;
16
+ user.roles.forEach((role) => {
17
+ if (this.params.roles.includes(role)) {
18
+ hasRole = true;
19
+ }
20
+ });
21
+
22
+ if (!hasRole) {
23
+ return res.status(403).json({ message: 'You do not have access' });
24
+ }
25
+ return next();
26
+ }
27
+ }
28
+
29
+ module.exports = RoleMiddleware;
package/tests/setup.js CHANGED
@@ -9,7 +9,7 @@ const Server = require('../server');
9
9
  jest.setTimeout(1000000);
10
10
  beforeAll(async () => {
11
11
  mongoMemoryServerInstance = await MongoMemoryReplSet.create({
12
- binary: { version: '4.4.6' },
12
+ // binary: { version: '4.4.6' },
13
13
  replSet: { storageEngine: 'wiredTiger' },
14
14
  });
15
15
  await mongoMemoryServerInstance.waitUntilRunning();