not-node 4.0.12 → 4.0.17

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,6 +1,6 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "4.0.12",
3
+ "version": "4.0.17",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -63,6 +63,7 @@
63
63
  "not-path": "*",
64
64
  "rate-limiter-flexible": "^2.3.6",
65
65
  "redis": "^4.0.0",
66
+ "rfdc": "^1.3.0",
66
67
  "rmdir": "^1.2.0",
67
68
  "serve-static": "*",
68
69
  "simple-git": "*",
@@ -73,7 +74,7 @@
73
74
  "babel-eslint": "^10.1.0",
74
75
  "chai": "*",
75
76
  "chai-as-promised": "*",
76
- "eslint": "^8.3.0",
77
+ "eslint": "^7.0.0",
77
78
  "eslint-plugin-node": "^11.1.0",
78
79
  "eslint-plugin-promise": "^5.2.0",
79
80
  "eslint-plugin-sonarjs": "^0.11.0",
package/src/common.js CHANGED
@@ -92,6 +92,21 @@ module.exports.copyObj = (obj) => {
92
92
  return JSON.parse(JSON.stringify(obj));
93
93
  };
94
94
 
95
+ /**
96
+ * Copies object to secure it from changes
97
+ * @param {object} obj original object
98
+ * @return {object} copy of object
99
+ **/
100
+ module.exports.partCopyObj = (obj, list) => {
101
+ let partObj = Object.keys(obj).reduce((prev, curr)=>{
102
+ if(list.includes(curr)){
103
+ prev[curr] = obj[curr];
104
+ }
105
+ return prev;
106
+ }, {});
107
+ return JSON.parse(JSON.stringify(partObj));
108
+ };
109
+
95
110
 
96
111
  /**
97
112
  * Test argument type to be 'function'
package/src/domain.js CHANGED
@@ -100,7 +100,7 @@ class notDomain extends EventEmitter {
100
100
  notApp: this,
101
101
  fields: this.options.fields
102
102
  });
103
- this.importModule(mod, moduleName || mod.getModuleName());
103
+ this.importModule(mod, moduleName || mod.getName());
104
104
  return this;
105
105
  }
106
106
 
@@ -235,7 +235,7 @@ class notDomain extends EventEmitter {
235
235
  return this.modules[moduleName];
236
236
  } else {
237
237
  for (let t in this.modules) {
238
- if (this.modules[t].getModuleName() === moduleName) {
238
+ if (this.modules[t].getName() === moduleName) {
239
239
  return this.modules[t];
240
240
  }
241
241
  }
@@ -1,3 +1,4 @@
1
+ const clone = require('rfdc')();
1
2
  const fs = require('fs');
2
3
  const path = require('path');
3
4
  const {objHas, tryFile} = require('../common');
@@ -82,7 +83,7 @@ module.exports.initField = (field, resultOnly = true, type = 'ui') => {
82
83
  destName = srcName = field;
83
84
  }
84
85
  let proto = (objHas(FIELDS, srcName) && objHas(FIELDS[srcName], type)) ? FIELDS[srcName][type]:{};
85
- let result = Object.assign({}, proto, mutation);
86
+ let result = Object.assign({}, clone(proto), mutation);
86
87
  if (resultOnly) {
87
88
  return result;
88
89
  } else {
@@ -5,7 +5,7 @@ module.exports = class FormFabric {
5
5
  FIELDS,
6
6
  MODULE_NAME,
7
7
  FORM_NAME,
8
- exractor
8
+ extractor
9
9
  }) {
10
10
  return class extends Form {
11
11
  constructor() {
@@ -21,7 +21,7 @@ module.exports = class FormFabric {
21
21
  * @return {Object} forma data
22
22
  **/
23
23
  extract(req) {
24
- return exractor(req);
24
+ return extractor(req);
25
25
  }
26
26
  };
27
27
  }
package/src/form/form.js CHANGED
@@ -25,15 +25,20 @@ class Form {
25
25
  FORM_NAME
26
26
  }) {
27
27
  this.FORM_NAME = FORM_NAME;
28
- this.FIELDS = FIELDS;
29
- this.SCHEMA = byFieldsValidators(initFields(FIELDS, 'model'));
28
+ this.PROTO_FIELDS = FIELDS;
30
29
  if (mongoose.modelNames().indexOf(FORM_NAME)===-1){
30
+ this.SCHEMA = byFieldsValidators(initFields(this.PROTO_FIELDS, 'model'));
31
31
  this.MODEL = mongoose.model(FORM_NAME, Schema(this.SCHEMA));
32
32
  }else{
33
33
  this.MODEL = mongoose.connection.model(FORM_NAME);
34
+ this.SCHEMA = this.MODEL.schema;
34
35
  }
35
36
  }
36
37
 
38
+ getFields(){
39
+ return Object.keys(this.SCHEMA);
40
+ }
41
+
37
42
  /**
38
43
  * Extract data from ExpressRequest object and validates it
39
44
  * returns it or throws
@@ -43,7 +48,7 @@ class Form {
43
48
  **/
44
49
  async run(req) {
45
50
  let data = await this.extract(req);
46
- await this.validate(data);
51
+ await this._validate(data);
47
52
  return data;
48
53
  }
49
54
 
@@ -62,9 +67,9 @@ class Form {
62
67
  * @return {Object}
63
68
  * @throws {notValidationError}
64
69
  **/
65
- async validate(data) {
70
+ async _validate(data) {
66
71
  try {
67
- await this.MODEL.validate(data, this.FIELDS);
72
+ await this.validate(data);
68
73
  } catch (e) {
69
74
  let fields = {};
70
75
  if (e instanceof mongoose.Error.ValidationError) {
@@ -72,12 +77,17 @@ class Form {
72
77
  fields[name] = [e.errors[name].message];
73
78
  });
74
79
  throw new notValidationError(e.message, fields, e, data);
75
- } else {
80
+ } else if (e instanceof notValidationError){
81
+ throw e;
82
+ }else {
76
83
  throw new notError(
77
- 'core:form_validation_error', {
84
+ 'core:form_validation_error',
85
+ {
78
86
  FORM_NAME: this.FORM_NAME,
79
- FIELDS: this.FIELDS,
80
- data
87
+ PROTO_FIELDS: this.PROTO_FIELDS,
88
+ FORM_FIELDS: this.getFields(),
89
+ data,
90
+ message: e.message
81
91
  },
82
92
  e
83
93
  );
@@ -85,6 +95,10 @@ class Form {
85
95
  }
86
96
  }
87
97
 
98
+ async validate(data){
99
+ await this.MODEL.validate(data, this.getFields());
100
+ }
101
+
88
102
  static fabric(){
89
103
  return FormFabric;
90
104
  }
@@ -1,5 +1,6 @@
1
1
  const emit = require('./additional').run;
2
2
  const log = require('not-log')(module, 'RateLimiter');
3
+ const {partCopyObj} = require('../common');
3
4
 
4
5
  const DEFAULT_OPTIONS = {
5
6
  keyPrefix: 'rateLimiterMiddleware',
@@ -7,6 +8,8 @@ const DEFAULT_OPTIONS = {
7
8
  duration: 1
8
9
  };
9
10
 
11
+ const DEFAULT_CLIENT = 'ioredis';
12
+
10
13
  module.exports = class InitRateLimiter{
11
14
 
12
15
  static createMiddleware({rateLimiter}){
@@ -29,18 +32,20 @@ module.exports = class InitRateLimiter{
29
32
  }
30
33
 
31
34
 
32
- getOptions({config}){
35
+ static getOptions({config}){
36
+ const opts = partCopyObj(config.get('modules.rateLimiter', {}), Object.keys(DEFAULT_OPTIONS));
33
37
  return {
34
38
  ...DEFAULT_OPTIONS,
35
- ...config.get('modules.rateLimiter', {})
39
+ ...opts
36
40
  };
37
41
  }
38
42
 
39
43
  static createRateLimiter({master, config}){
40
44
  const {RateLimiterRedis} = require('rate-limiter-flexible');
45
+ const storeClient = config.get('modules.rateLimiter.client', DEFAULT_CLIENT);
41
46
  return new RateLimiterRedis({
42
- storeClient: master.getEnv('db.redis'),
43
- ...this.getOptions({master, config})
47
+ storeClient: master.getEnv(`db.${storeClient}`),
48
+ ...InitRateLimiter.getOptions({master, config})
44
49
  });
45
50
  }
46
51
  };
@@ -1,17 +1,20 @@
1
1
  const log = require('not-log')(module, 'not-node//init');
2
2
  const ADDS = require('../additional');
3
3
 
4
+ const DEFAULT_CLIENT = 'ioredis';
5
+
4
6
  module.exports = class InitSessionsRedis{
5
7
  async run({config, options, master}) {
6
8
  log.info('Setting up user sessions handler(redis)...');
7
9
  await ADDS.run('sessions.pre', {config, options, master});
8
10
  const expressSession = require('express-session');
9
- const redisClient = master.getEnv('db.redis');
11
+ const storeClient = config.get('session.client', DEFAULT_CLIENT);
12
+ const redisClient = master.getEnv(`db.${storeClient}`);
10
13
  const redisStore = require('connect-redis')(expressSession);
11
14
  master.getServer().use(expressSession({
12
- secret: config.get('session:secret'),
13
- key: config.get('session:key'),
14
- cookie: config.get('session:cookie'),
15
+ secret: config.get('session.secret'),
16
+ key: config.get('session.key'),
17
+ cookie: config.get('session.cookie'),
15
18
  resave: false,
16
19
  saveUninitialized: true,
17
20
  store: new redisStore({
@@ -56,17 +56,11 @@ class notModule {
56
56
  };
57
57
  this.fieldsImportRules = (objHas(options, 'fields') && options.fields) ? options.fields : {};
58
58
 
59
- log.info(`Creating module: ${this.getModuleName()}`);
59
+ log.info(`Creating module: ${this.getName()}`);
60
60
  this.init();
61
61
  return this;
62
62
  }
63
63
 
64
- getModuleName() {
65
- if(this.module && this.module.name){
66
- return this.module.name;
67
- }
68
- return this.path;
69
- }
70
64
 
71
65
  init() {
72
66
  if (this.path) {
@@ -174,7 +168,7 @@ class notModule {
174
168
  }
175
169
 
176
170
  fabricateModel(model) {
177
- protoModel.fabricate(model, {}, this.mongoose);
171
+ protoModel.fabricate(model, this.getOptions(), this.mongoose);
178
172
  }
179
173
 
180
174
  fabricateModels() {
@@ -318,7 +312,14 @@ class notModule {
318
312
  }
319
313
 
320
314
  getName(){
321
- return this.module.name;
315
+ if(this.module && this.module.name){
316
+ return this.module.name;
317
+ }
318
+ return this.path;
319
+ }
320
+
321
+ getOptions(){
322
+ return (this.module && this.module.options)?this.module.options:{};
322
323
  }
323
324
 
324
325
  setRouteWS({
@@ -1,5 +1,40 @@
1
1
  /** @module Model/Validator */
2
2
  const validate = require('mongoose-validator');
3
+ const {objHas, executeObjectFunction, isFunc} = require('../common');
4
+
5
+ function extractValidationEnvGetter(options){
6
+ if(options && objHas(options, 'getValidationEnv') && isFunc(options.getValidationEnv)){
7
+ return options.getValidationEnv;
8
+ }else{
9
+ //should return at least empty object
10
+ return ()=>{return {};};
11
+ }
12
+ }
13
+
14
+ function extendObsolete(rule){
15
+ return validate(rule);
16
+ }
17
+
18
+ function extendModern(rule, options){
19
+ const result = {...rule};
20
+ delete result.validator;
21
+ const validationEnv = extractValidationEnvGetter(options)();
22
+ result.validator = async (val) => {
23
+ return await executeObjectFunction(rule, 'validator', [val, validationEnv]);
24
+ };
25
+ return result;
26
+ }
27
+
28
+
29
+ function extendValidation(rule, options){
30
+ if(typeof rule.validator === 'string'){
31
+ //will extend from text description to validatejs lib validation function
32
+ return extendObsolete(rule);
33
+ }else{
34
+ //more complex validation
35
+ return extendModern(rule, options);
36
+ }
37
+ }
3
38
 
4
39
  /**
5
40
  * Take array of validator (https://www.npmjs.com/package/validator) rules
@@ -7,10 +42,8 @@ const validate = require('mongoose-validator');
7
42
  * then return it
8
43
  **/
9
44
 
10
- module.exports = function(validators) {
11
- var result = null;
12
- result = validators.map((item) => {
13
- return validate(item);
14
- });
45
+ module.exports = function(validators, options) {
46
+ let result = null;
47
+ result = validators.map(rule => extendValidation(rule, options));
15
48
  return result;
16
49
  };
@@ -1,7 +1,7 @@
1
1
  /** @module Model/Enrich */
2
2
 
3
3
  const Schema = require('mongoose').Schema,
4
- firstLetterToLower = require('../common').firstLetterToLower,
4
+ {firstLetterToLower,isFunc} = require('../common'),
5
5
  buildValidator = require('./buildValidator');
6
6
 
7
7
  class ModelEnricher{
@@ -49,7 +49,7 @@ class ModelEnricher{
49
49
  mongooseSchema.statics.__incModel = modelName;
50
50
  if(options && options.filter){
51
51
  mongooseSchema.statics.__incFilter = options.filter;
52
- }
52
+ }
53
53
  return mongooseSchema;
54
54
  }
55
55
 
@@ -58,11 +58,11 @@ class ModelEnricher{
58
58
  return mongooseSchema;
59
59
  }
60
60
 
61
- static byFieldsValidators (mongooseSchema) {
61
+ static byFieldsValidators (mongooseSchema, options) {
62
62
  if (mongooseSchema) {
63
63
  for (let fieldName in mongooseSchema) {
64
- if (Object.prototype.hasOwnProperty.call(mongooseSchema[fieldName], 'validate')) {
65
- mongooseSchema[fieldName].validate = buildValidator(mongooseSchema[fieldName].validate);
64
+ if (Object.prototype.hasOwnProperty.call(mongooseSchema[fieldName], 'validate') && mongooseSchema[fieldName].validate.length && !isFunc(mongooseSchema[fieldName].validate[0])) {
65
+ mongooseSchema[fieldName].validate = buildValidator(mongooseSchema[fieldName].validate, options);
66
66
  }
67
67
  }
68
68
  }
@@ -59,10 +59,10 @@ module.exports = class ModelFabricate{
59
59
  this.extendSchemaFrom(targetModule.thisPost, schema.post.bind(schema));
60
60
  }
61
61
 
62
- static enrichByFields(targetModule){
62
+ static enrichByFields(targetModule, options){
63
63
  if (targetModule.enrich) {
64
64
  if (targetModule.enrich.validators) {
65
- targetModule.thisSchema = enrich.byFieldsValidators(targetModule.thisSchema, targetModule.thisModelName);
65
+ targetModule.thisSchema = enrich.byFieldsValidators(targetModule.thisSchema, options);
66
66
  }
67
67
  if (targetModule.enrich.versioning) {
68
68
  targetModule.thisSchema = enrich.byFieldsForVersioning(targetModule.thisSchema, targetModule.thisModelName);
@@ -125,7 +125,7 @@ module.exports = class ModelFabricate{
125
125
  if (ModelFabricate.isNotExtendable(targetModule)) {
126
126
  return new Schema(targetModule.thisSchema, options.schemaOptions);
127
127
  } else {
128
- ModelFabricate.enrichByFields(targetModule);
128
+ ModelFabricate.enrichByFields(targetModule, options);
129
129
  //collecting information of unique fields, removing unique flag from schema
130
130
  let fieldsForIndexes = ModelFabricate.collectFieldsForIndexes(targetModule);
131
131
  //creating schema for model
package/test/notDomain.js CHANGED
@@ -390,12 +390,12 @@ describe('notDomain', function() {
390
390
  it('exists, but with custom name', function() {
391
391
  const route = 'Jungle';
392
392
  const targetMod = {
393
- getModuleName(){ return 'Jungle'; }
393
+ getName(){ return 'Jungle'; }
394
394
  };
395
395
  const ctx = {
396
396
  modules:{
397
397
  loop:{
398
- getModuleName(){return 'loop'; }
398
+ getName(){return 'loop'; }
399
399
  },
400
400
  trees: targetMod
401
401
  }
@@ -408,12 +408,12 @@ describe('notDomain', function() {
408
408
  it('not exists', function() {
409
409
  const route = 'Jungle';
410
410
  const targetMod = {
411
- getModuleName(){ return 'Jungle1'; }
411
+ getName(){ return 'Jungle1'; }
412
412
  };
413
413
  const ctx = {
414
414
  modules:{
415
415
  loop:{
416
- getModuleName(){return 'loop'; }
416
+ getName(){return 'loop'; }
417
417
  },
418
418
  trees: targetMod
419
419
  }
package/test/notModule.js CHANGED
@@ -144,14 +144,14 @@ describe('notModule', function() {
144
144
  name: 'fake my name'
145
145
  }
146
146
  }
147
- expect(notModule.prototype.getModuleName.call(ctx)).to.be.equal('fake my name');
147
+ expect(notModule.prototype.getName.call(ctx)).to.be.equal('fake my name');
148
148
  });
149
149
 
150
150
  it('no module.name, no path', function() {
151
151
  const ctx = {
152
152
  module: {}
153
153
  }
154
- expect(notModule.prototype.getModuleName.call(ctx)).to.be.undefined;
154
+ expect(notModule.prototype.getName.call(ctx)).to.be.undefined;
155
155
  });
156
156
  });
157
157