not-node 6.2.26 → 6.2.28

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": "6.2.26",
3
+ "version": "6.2.28",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/common.js CHANGED
@@ -76,13 +76,17 @@ module.exports.getTodayDate = () => {
76
76
  /**
77
77
  * Returns true if object has field of name
78
78
  * @param {object} obj some object
79
- * @param {string} name field name
79
+ * @param {string|Array<string>} name field name
80
80
  * @return {boolean} if object contains field with name
81
81
  **/
82
82
  const objHas = (obj, name) => {
83
83
  if (typeof obj === "undefined") return false;
84
84
  if (obj === null) return false;
85
- return Object.prototype.hasOwnProperty.call(obj, name);
85
+ if (Array.isArray(name)) {
86
+ return name.every((itm) => typeof itm === "string" && objHas(obj, itm));
87
+ } else {
88
+ return Object.prototype.hasOwnProperty.call(obj, name);
89
+ }
86
90
  };
87
91
  module.exports.objHas = objHas;
88
92
 
@@ -362,3 +366,61 @@ const getValueFromEnv = (
362
366
  }
363
367
  };
364
368
  module.exports.getValueFromEnv = getValueFromEnv;
369
+
370
+ /**
371
+ * Provides shallow object signature checks
372
+ *
373
+ * @param {object} obj object to check
374
+ * @param {object} sign signature object {fieldName: someValueOfTargetType}
375
+ * @param {boolean} [strict=true] if you need exact properties as in signature, when false - properties not described in signature are ok
376
+ * @param {boolean} [typeStrict=true] compares types of properties in obj and signature
377
+ * @return {boolean} true if object structured as signature
378
+ */
379
+ const compareObjectSignatures = (
380
+ obj,
381
+ sign,
382
+ strict = true,
383
+ typeStrict = true
384
+ ) => {
385
+ const objKeys = Object.keys(obj);
386
+ const signKeys = Object.keys(sign);
387
+ const checkKey = (key) => {
388
+ if (objKeys.includes(key)) {
389
+ if (typeStrict) {
390
+ return typeof obj[key] === typeof sign[key];
391
+ } else {
392
+ return true;
393
+ }
394
+ } else {
395
+ return false;
396
+ }
397
+ };
398
+
399
+ if (strict) {
400
+ if (objKeys.length === signKeys.length) {
401
+ return signKeys.every(checkKey);
402
+ } else {
403
+ return false;
404
+ }
405
+ } else {
406
+ return signKeys.every(checkKey);
407
+ }
408
+ };
409
+
410
+ module.exports.compareObjectSignatures = compareObjectSignatures;
411
+
412
+ /**
413
+ * Returns first index of signature matching to object
414
+ *
415
+ * @param {object} obj object to match against signatures
416
+ * @param {Array<object>} signatures array of signature
417
+ * @param {boolean} [strict=true] check exact number of properties
418
+ * @param {boolean} [typeStrict=true] check exact properties types
419
+ * @return {number} -1 if nothing is found, from 0 to signatures.length-1 if some signature
420
+ */
421
+ const findSignature = (obj, signatures, strict = true, typeStrict = true) => {
422
+ return signatures.findIndex((sign) => {
423
+ return compareObjectSignatures(obj, sign, strict, typeStrict);
424
+ });
425
+ };
426
+ module.exports.findSignature = findSignature;
@@ -1,4 +1,4 @@
1
- const { notError } = require("not-error");
1
+ const notError = require("not-error/src/error.node");
2
2
 
3
3
  class VersioningExceptionSameOldData extends notError {
4
4
  constructor() {
@@ -1,6 +1,6 @@
1
1
  /** @module Model/Increment */
2
2
 
3
- const { updateResponseSuccess } = require("./utils.js");
3
+ const { updateResponseSuccess, insertResponseSuccess } = require("./utils.js");
4
4
  const {
5
5
  IncrementExceptionIDGeneratorRebaseFailed,
6
6
  IncrementExceptionIDGenerationFailed,
@@ -25,9 +25,9 @@ let schema = null;
25
25
 
26
26
  /**
27
27
  * Returns sub-list of fields which is not contained in object
28
- * @param {Array.string} fields list of fields
28
+ * @param {Array<string>} fields list of fields
29
29
  * @param {Object} data object to filter against
30
- * @return {Array.string} sub-list of fields not contained in object
30
+ * @return {Array<string>} sub-list of fields not contained in object
31
31
  **/
32
32
  function notContainedInData(fields, data) {
33
33
  let keys = Object.keys(data);
@@ -52,7 +52,7 @@ function formId(modelName, filterFields, data) {
52
52
  module.exports.formId = formId;
53
53
  /**
54
54
  * Some drivers versions work-arounds
55
- * @param {Mongoose.Model} thisModel counter model
55
+ * @param {import('mongoose').Model} thisModel counter model
56
56
  * @param {Object} which filter object of update request
57
57
  * @param {Object} cmd command object of update request
58
58
  * @param {Object} opts options of request
@@ -76,9 +76,9 @@ function newGetNext() {
76
76
  * sub-set of all documents, which is grouped by fields (filterFields) with
77
77
  * same value
78
78
  * @param {string} modelName
79
- * @param {Array.string} filterFields list of fild names, which is used for grouping
79
+ * @param {Array<string>} filterFields list of fild names, which is used for grouping
80
80
  * @param {Object} data item data
81
- * @return {Promise.Number}
81
+ * @return {Promise<Number>}
82
82
  **/
83
83
  return async function (modelName, filterFields, data) {
84
84
  let thisModel = this;
@@ -105,7 +105,7 @@ function newGetNext() {
105
105
  upsert: true,
106
106
  };
107
107
  const res = await secureUpdate(thisModel, which, cmd, opts);
108
- if (updateResponseSuccess(res)) {
108
+ if (updateResponseSuccess(res) || insertResponseSuccess(res, 1)) {
109
109
  const doc = await thisModel.findOne({ id });
110
110
  return doc.seq;
111
111
  } else {
@@ -116,12 +116,12 @@ function newGetNext() {
116
116
 
117
117
  module.exports.newGetNext = newGetNext;
118
118
 
119
- /**
120
- * Sets new current ID for model
121
- * @param {string} modelName name of target model
122
- * @param {number} ID desired new start ID for model
123
- **/
124
119
  function newRebase() {
120
+ /**
121
+ * Sets new current ID for model
122
+ * @param {string} modelName name of target model
123
+ * @param {number} ID desired new start ID for model
124
+ **/
125
125
  return async function (modelName, ID) {
126
126
  let thisModel = this;
127
127
  let which = {
@@ -73,11 +73,6 @@ module.exports = class ModelFabricate {
73
73
 
74
74
  static enrichByFields(targetModule, options) {
75
75
  if (targetModule.enrich) {
76
- const model_name = targetModule.thisModelName;
77
- console.log(
78
- `MODEL: ${model_name}`,
79
- JSON.stringify(options, null, 4)
80
- );
81
76
  if (targetModule.enrich.validators) {
82
77
  targetModule.thisSchema = enrich.byFieldsValidators(
83
78
  targetModule.thisSchema,
@@ -198,9 +193,7 @@ module.exports = class ModelFabricate {
198
193
  if (ModelFabricate.isIgnored(targetModule)) {
199
194
  return;
200
195
  }
201
-
202
196
  options = ModelFabricate.initOptions(options, targetModule);
203
-
204
197
  const schema = ModelFabricate.extendSchema(targetModule, options);
205
198
  if (schema) {
206
199
  targetModule.mongooseSchema = schema;
@@ -211,7 +204,7 @@ module.exports = class ModelFabricate {
211
204
  mongoose
212
205
  );
213
206
  } catch (error) {
214
- log.error(error);
207
+ log && log.error(error);
215
208
  }
216
209
  }
217
210
  }
@@ -1,3 +1,29 @@
1
+ const { findSignature } = require("../common");
2
+
3
+ const INSERT_SIGNATURE = {
4
+ acknowledged: true,
5
+ modifiedCount: 0,
6
+ upsertedId: {},
7
+ upsertedCount: 1,
8
+ matchedCount: 0,
9
+ };
10
+
11
+ const SIGNATURES = {
12
+ INSERT: [INSERT_SIGNATURE],
13
+ UPDATE: [],
14
+ DELETE: [],
15
+ };
16
+
17
+ function insertResponseSuccess(res, count = 1) {
18
+ const ind = findSignature(res, SIGNATURES.INSERT);
19
+ if (ind === -1) {
20
+ return false;
21
+ }
22
+ return SIGNATURES.INSERT[ind].upsertedCount === count;
23
+ }
24
+
25
+ module.exports.insertResponseSuccess = insertResponseSuccess;
26
+
1
27
  /**
2
28
  * checking result of modification queries to ensure that changes were made
3
29
  */
@@ -65,9 +65,9 @@ class ModelVersioning {
65
65
 
66
66
  /**
67
67
  * Compares latest version in __versions list in data with data
68
- * @param {MongooseModel} ModelConstructor model of data
68
+ * @param {import('mongoose').Model} ModelConstructor model of data
69
69
  * @param {Object} data data to save
70
- * @return {boolean} if data differs from latest version
70
+ * @return {Promise<boolean>} if data differs from latest version
71
71
  */
72
72
  static async isNew(ModelConstructor, data) {
73
73
  let latestId = ModelVersioning.getLatestVersionId(data);
@@ -84,10 +84,10 @@ class ModelVersioning {
84
84
 
85
85
  /**
86
86
  * Saves current version to versions archive, updates current version versioning tags
87
- * @param {ObjectId} id current version _id (just saved version)
87
+ * @param {import('mongoose').Types.ObjectId} id current version _id (just saved version)
88
88
  * @param {Object} data data to save
89
- * @param {MongooseModel} ModelConstructor model to use
90
- * @return {Promise<MongooseDocument>} current version with updated versioning tags
89
+ * @param {import('mongoose').Model} ModelConstructor model to use
90
+ * @return {Promise<import('mongoose').Document>} current version with updated versioning tags
91
91
  */
92
92
  static async saveVersion(id, data, ModelConstructor) {
93
93
  let preservedVersionNumber = ModelVersioning.extractVersionNumber(data),
@@ -112,10 +112,10 @@ class ModelVersioning {
112
112
 
113
113
  /**
114
114
  * Saves first version. Run AFTER doing .save() on document.
115
- * @param {ObjectId} id current version _id (just saved version)
115
+ * @param {import('mongoose').Types.ObjectId} id current version _id (just saved version)
116
116
  * @param {Object} data data to save
117
- * @param {MongooseModel} ModelConstructor model to use
118
- * @return {Promise<MongooseDocument>} current version with updated versions tags
117
+ * @param {import('mongoose').Model} ModelConstructor model to use
118
+ * @return {Promise<import('mongoose').Document>} current version with updated versions tags
119
119
  */
120
120
  static async saveFirstVersion(id, data, ModelConstructor) {
121
121
  //it's not latest version, it's archived copy
@@ -138,8 +138,8 @@ class ModelVersioning {
138
138
  * Save document
139
139
  * if document is new - creates document
140
140
  * if it's updated document - updates document and versioning history
141
- * @param {MongooseModel} doc document to save
142
- * @return {Promise<MongooseDocument>} current version with updated versions tags
141
+ * @param {import('mongoose').Model} doc document to save
142
+ * @return {Promise<import('mongoose').Document>} current version with updated versions tags
143
143
  */
144
144
  static saveDiff(ModelConstructor, doc) {
145
145
  let data = toObject(doc),
package/test/common.js CHANGED
@@ -1,151 +1,193 @@
1
- const expect = require('chai').expect,
2
- mongoose = require('mongoose'),
3
- path = require('path'),
4
- ObjectId = mongoose.Types.ObjectId,
5
- Common = require('../src/common');
6
-
7
- describe('Common', function() {
8
- describe('firstLetterToLower', function() {
9
- it('`Some error` -> `some error`', function() {
10
- expect(Common.firstLetterToLower('Some error')).to.be.equal('some error');
11
- });
12
- });
13
-
14
- describe('firstLetterToUpper', function() {
15
- it('`some error` -> `Some error`', function() {
16
- expect(Common.firstLetterToUpper('some error')).to.be.equal('Some error');
17
- });
18
- });
19
-
20
- let testie = 'Иероним Босх';
21
- describe(`validateObjectId, build in validator failed on ${testie}`, function() {
22
-
23
- it(`Mongoose.Types.ObjectId.isValid('${testie}') -> true`, function(){
24
- expect(ObjectId.isValid(testie)).to.be.ok;
25
- });
26
-
27
- it(`validateObjectId(${testie}) -> false`, function() {
28
- expect(Common.validateObjectId(testie)).to.be.not.ok;
29
- });
30
-
31
- it('validateObjectId(`5af96abbce4adb46c5202ed3`) -> true', function() {
32
- expect(Common.validateObjectId('5af96abbce4adb46c5202ed3')).to.be.ok;
33
- });
34
-
35
- it('validateObjectId(undefined) -> false', function() {
36
- expect(Common.validateObjectId(undefined)).to.be.false;
37
- });
38
- });
39
-
40
- describe('compareObjectIds', function() {
41
- it('null and null -> false', function() {
42
- expect(Common.compareObjectIds(null, null)).to.be.false;
43
- });
44
- it('1 and 1 -> false', function() {
45
- expect(Common.compareObjectIds(1, 1)).to.be.false;
46
- });
47
- it('"1" and 1 -> false', function() {
48
- expect(Common.compareObjectIds("1", 1)).to.be.false;
49
- });
50
- });
51
-
52
-
53
- describe('getTodayDate', ()=>{
54
- it('today', ()=>{
55
- const res = Common.getTodayDate();
56
- expect(typeof res).to.be.equal('number');
57
- });
58
- });
59
- //
60
- describe('executeObjectFunction', ()=>{
61
- it('promise', async ()=>{
62
- const obj = {
63
- async method(...params){
64
- return 'apple '+params.join('.');
65
- }
66
- }, name = 'method', params = [1,2,3,true];
67
- const res = await Common.executeObjectFunction(obj, name, params);
68
- expect(res).to.be.equal('apple 1.2.3.true');
69
- });
70
-
71
- it('function', async ()=>{
72
- const obj = {
73
- method(...params){
74
- return 'apple '+params.join('.');
75
- }
76
- }, name = 'method', params = [1,2,3,true];
77
- const res = await Common.executeObjectFunction(obj, name, params);
78
- expect(res).to.be.equal('apple 1.2.3.true');
79
- });
80
-
81
- it('!obj', async ()=>{
82
- const obj = null, name = 'method', params = [1,2,3,true];
83
- const res = await Common.executeObjectFunction(obj, name, params);
84
- expect(res).to.be.undefined;
85
- });
86
- });
87
-
88
-
89
- describe('mapBind', function() {
90
- it('to is undefined, exception throwned', function(done) {
91
- let to = undefined;
92
- try {
93
- Common.mapBind({getModel(){}}, to, ['getModel']);
94
- console.log(to);
95
- done(new Error('should throw'))
96
- } catch (e) {
97
- expect(e).to.be.instanceof(Error);
98
- done()
99
- }
1
+ const expect = require("chai").expect,
2
+ mongoose = require("mongoose"),
3
+ path = require("path"),
4
+ ObjectId = mongoose.Types.ObjectId,
5
+ Common = require("../src/common");
6
+
7
+ describe("Common", function () {
8
+ describe("firstLetterToLower", function () {
9
+ it("`Some error` -> `some error`", function () {
10
+ expect(Common.firstLetterToLower("Some error")).to.be.equal(
11
+ "some error"
12
+ );
13
+ });
100
14
  });
101
15
 
102
- it('list is empty', function() {
103
- const to = {};
104
- Common.mapBind({}, to, []);
105
- expect(to).to.be.deep.equal({});
16
+ describe("firstLetterToUpper", function () {
17
+ it("`some error` -> `Some error`", function () {
18
+ expect(Common.firstLetterToUpper("some error")).to.be.equal(
19
+ "Some error"
20
+ );
21
+ });
106
22
  });
107
23
 
108
- it('list item is not pointing to function', function() {
109
- const to = {};
110
- Common.mapBind({}, to, ['vasqa de gamma']);
111
- expect(to).to.be.deep.equal({});
24
+ let testie = "Иероним Босх";
25
+ describe(`validateObjectId, build in validator failed on ${testie}`, function () {
26
+ it(`Mongoose.Types.ObjectId.isValid('${testie}') -> true`, function () {
27
+ expect(ObjectId.isValid(testie)).to.be.ok;
28
+ });
29
+
30
+ it(`validateObjectId(${testie}) -> false`, function () {
31
+ expect(Common.validateObjectId(testie)).to.be.not.ok;
32
+ });
33
+
34
+ it("validateObjectId(`5af96abbce4adb46c5202ed3`) -> true", function () {
35
+ expect(Common.validateObjectId("5af96abbce4adb46c5202ed3")).to.be
36
+ .ok;
37
+ });
38
+
39
+ it("validateObjectId(undefined) -> false", function () {
40
+ expect(Common.validateObjectId(undefined)).to.be.false;
41
+ });
42
+ });
43
+
44
+ describe("compareObjectIds", function () {
45
+ it("null and null -> false", function () {
46
+ expect(Common.compareObjectIds(null, null)).to.be.false;
47
+ });
48
+ it("1 and 1 -> false", function () {
49
+ expect(Common.compareObjectIds(1, 1)).to.be.false;
50
+ });
51
+ it('"1" and 1 -> false', function () {
52
+ expect(Common.compareObjectIds("1", 1)).to.be.false;
53
+ });
54
+ });
55
+
56
+ describe("getTodayDate", () => {
57
+ it("today", () => {
58
+ const res = Common.getTodayDate();
59
+ expect(typeof res).to.be.equal("number");
60
+ });
61
+ });
62
+ //
63
+ describe("executeObjectFunction", () => {
64
+ it("promise", async () => {
65
+ const obj = {
66
+ async method(...params) {
67
+ return "apple " + params.join(".");
68
+ },
69
+ },
70
+ name = "method",
71
+ params = [1, 2, 3, true];
72
+ const res = await Common.executeObjectFunction(obj, name, params);
73
+ expect(res).to.be.equal("apple 1.2.3.true");
74
+ });
75
+
76
+ it("function", async () => {
77
+ const obj = {
78
+ method(...params) {
79
+ return "apple " + params.join(".");
80
+ },
81
+ },
82
+ name = "method",
83
+ params = [1, 2, 3, true];
84
+ const res = await Common.executeObjectFunction(obj, name, params);
85
+ expect(res).to.be.equal("apple 1.2.3.true");
86
+ });
87
+
88
+ it("!obj", async () => {
89
+ const obj = null,
90
+ name = "method",
91
+ params = [1, 2, 3, true];
92
+ const res = await Common.executeObjectFunction(obj, name, params);
93
+ expect(res).to.be.undefined;
94
+ });
112
95
  });
113
- });
114
-
115
-
116
- describe('tryFile', function() {
117
- const pathToExistingFile = path.join(__dirname, 'testies/module/fields/collection.js');
118
- const pathToAbsentFile = path.join(__dirname, 'testies/module/fields/collection.ejs');
119
- const pathToDirectory = path.join(__dirname, 'testies/module/fields/empty');
120
-
121
- it('file exists, type file', function() {
122
- const res = Common.tryFile(pathToExistingFile);
123
- expect(res).to.be.equal(true);
124
- });
125
-
126
- it('file doesnt exist', function() {
127
- const res = Common.tryFile(pathToAbsentFile);
128
- expect(res).to.be.equal(false);
129
- });
130
-
131
- it('directory', function() {
132
- const res = Common.tryFile(pathToDirectory);
133
- expect(res).to.be.equal(false);
134
- });
135
- });
136
-
137
- describe('copyObj', function () {
138
- it('empty', function () {
139
- let rule = {};
140
- expect(Common.copyObj(rule)).to.be.deep.equal({});
141
- });
142
-
143
- it('not empty, then modification of new rule is not changes original', function () {
144
- let rule = {some: ['data']};
145
- let copyOfRule = Common.copyObj(rule);
146
- delete copyOfRule.some;
147
- expect(rule).to.be.deep.equal({some: ['data']});
148
- });
149
- });
150
96
 
97
+ describe("mapBind", function () {
98
+ it("to is undefined, exception throwned", function (done) {
99
+ let to = undefined;
100
+ try {
101
+ Common.mapBind({ getModel() {} }, to, ["getModel"]);
102
+ console.log(to);
103
+ done(new Error("should throw"));
104
+ } catch (e) {
105
+ expect(e).to.be.instanceof(Error);
106
+ done();
107
+ }
108
+ });
109
+
110
+ it("list is empty", function () {
111
+ const to = {};
112
+ Common.mapBind({}, to, []);
113
+ expect(to).to.be.deep.equal({});
114
+ });
115
+
116
+ it("list item is not pointing to function", function () {
117
+ const to = {};
118
+ Common.mapBind({}, to, ["vasqa de gamma"]);
119
+ expect(to).to.be.deep.equal({});
120
+ });
121
+ });
122
+
123
+ describe("tryFile", function () {
124
+ const pathToExistingFile = path.join(
125
+ __dirname,
126
+ "testies/module/fields/collection.js"
127
+ );
128
+ const pathToAbsentFile = path.join(
129
+ __dirname,
130
+ "testies/module/fields/collection.ejs"
131
+ );
132
+ const pathToDirectory = path.join(
133
+ __dirname,
134
+ "testies/module/fields/empty"
135
+ );
136
+
137
+ it("file exists, type file", function () {
138
+ const res = Common.tryFile(pathToExistingFile);
139
+ expect(res).to.be.equal(true);
140
+ });
141
+
142
+ it("file doesnt exist", function () {
143
+ const res = Common.tryFile(pathToAbsentFile);
144
+ expect(res).to.be.equal(false);
145
+ });
146
+
147
+ it("directory", function () {
148
+ const res = Common.tryFile(pathToDirectory);
149
+ expect(res).to.be.equal(false);
150
+ });
151
+ });
152
+
153
+ describe("copyObj", function () {
154
+ it("empty", function () {
155
+ let rule = {};
156
+ expect(Common.copyObj(rule)).to.be.deep.equal({});
157
+ });
158
+
159
+ it("not empty, then modification of new rule is not changes original", function () {
160
+ let rule = { some: ["data"] };
161
+ let copyOfRule = Common.copyObj(rule);
162
+ delete copyOfRule.some;
163
+ expect(rule).to.be.deep.equal({ some: ["data"] });
164
+ });
165
+ });
166
+
167
+ describe("objHas", () => {
168
+ it("one field, exists", () => {
169
+ const obj = { field: 1 };
170
+ expect(Common.objHas(obj, "field")).to.be.true;
171
+ });
172
+
173
+ it("one field, dont exists", () => {
174
+ const obj = { field: 1 };
175
+ expect(Common.objHas(obj, "field2")).to.be.false;
176
+ });
177
+
178
+ it("few fields, one dont exists", () => {
179
+ const obj = { field: 1, goo: true, joe: "foo" };
180
+ expect(Common.objHas(obj, ["field", "goo", "laste"])).to.be.false;
181
+ });
182
+
183
+ it("few fields, all exists", () => {
184
+ const obj = { field: 1, goo: true, joe: "foo" };
185
+ expect(Common.objHas(obj, ["field", "goo", "joe"])).to.be.true;
186
+ });
187
+
188
+ it("few fields, some names is not string", () => {
189
+ const obj = { field: 1, goo: true, joe: "foo" };
190
+ expect(Common.objHas(obj, [1, "goo", undefined])).to.be.false;
191
+ });
192
+ });
151
193
  });