not-node 6.3.0 → 6.3.2
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/index.js +2 -0
- package/package.json +2 -2
- package/src/auth/const.js +17 -0
- package/src/auth/fields.js +10 -5
- package/src/auth/roles.js +2 -2
- package/src/auth/rules.js +49 -13
- package/src/bootstrap/logic.js +12 -11
- package/src/bootstrap/route.js +1 -1
- package/src/common.js +7 -0
- package/src/fields/filter.js +326 -0
- package/src/fields/index.js +2 -2
- package/src/form/env_extractors/activeUser.js +1 -1
- package/src/form/env_extractors/activeUserId.js +6 -0
- package/src/form/env_extractors/index.js +3 -0
- package/src/form/env_extractors/query.js +6 -0
- package/src/form/fabric.js +3 -3
- package/src/form/form.js +37 -10
- package/src/generic/form.authorizedAction.js +6 -8
- package/src/generic/form.getByID.js +8 -10
- package/src/generic/form.getById.js +8 -9
- package/src/generic/form.listAndCount.js +28 -26
- package/src/generic/logic.js +31 -85
- package/src/identity/index.js +6 -2
- package/src/identity/providers/session.js +14 -12
- package/src/identity/providers/token.js +14 -7
- package/src/init/lib/sessions/index.js +1 -1
- package/src/manifest/manifest.filter.js +118 -17
- package/src/manifest/manifest.js +8 -2
- package/src/manifest/module.js +21 -16
- package/src/manifest/registrator/fields.js +8 -1
- package/src/manifest/registrator/forms.js +1 -0
- package/src/manifest/registrator/locales.js +9 -1
- package/src/manifest/registrator/logics.js +2 -2
- package/src/manifest/registrator/models.js +2 -2
- package/src/manifest/registrator/routes.js +8 -8
- package/src/manifest/result.filter.js +3 -2
- package/src/manifest/route.js +42 -14
- package/src/model/default.js +1 -1
- package/src/model/proto.js +1 -1
- package/src/obsolete.js +23 -7
- package/src/types.js +83 -0
- package/test/auth/fields.js +2 -2
- package/test/auth/obsolete.js +16 -9
- package/test/extractors.js +60 -0
- package/test/filter.js +286 -0
- package/test/init/sessions.js +14 -2
- package/test/notManifestFilter.js +358 -19
- package/test/notModule.js +41 -1
- package/test/transformers.js +21 -0
- package/tmpl/files/module.server/layers/routes.manifest.ejs +9 -0
package/src/manifest/route.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const CONST_BEFORE_ACTION = "before";
|
|
2
2
|
const CONST_AFTER_ACTION = "after";
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const { obsoleteRuleFields, obsoleteActionFields } = require("../obsolete");
|
|
5
5
|
|
|
6
6
|
const notAppIdentity = require("../identity");
|
|
7
7
|
const Auth = require("../auth"),
|
|
@@ -32,17 +32,22 @@ class notRoute {
|
|
|
32
32
|
/**
|
|
33
33
|
* Cycle throu rules of action and checking user credentials against them
|
|
34
34
|
* If user creds comply to some rule - returns copy of rule
|
|
35
|
-
* @param {
|
|
35
|
+
* @param {import('../types').notActionData & import('../types').notRouteRule } action action rules object
|
|
36
36
|
* @param {object} user user credentials (auth, role, root)
|
|
37
37
|
* @return {object|null} returns rule or null
|
|
38
38
|
**/
|
|
39
|
-
static actionAvailableByRule(action, user) {
|
|
39
|
+
static actionAvailableByRule(action, user, url = "") {
|
|
40
40
|
if (!action) {
|
|
41
41
|
return null;
|
|
42
42
|
}
|
|
43
|
-
if (
|
|
43
|
+
if (
|
|
44
|
+
action.rules &&
|
|
45
|
+
Array.isArray(action.rules) &&
|
|
46
|
+
action.rules.length > 0
|
|
47
|
+
) {
|
|
44
48
|
return notRoute.cycleThruRules(action.rules, user);
|
|
45
49
|
} else {
|
|
50
|
+
obsoleteActionFields(action, url);
|
|
46
51
|
if (
|
|
47
52
|
Auth.checkCredentials(action, user.auth, user.role, user.root)
|
|
48
53
|
) {
|
|
@@ -54,7 +59,7 @@ class notRoute {
|
|
|
54
59
|
|
|
55
60
|
static cycleThruRules(rules, user, url = "") {
|
|
56
61
|
for (let i = 0; i < rules.length; i++) {
|
|
57
|
-
|
|
62
|
+
obsoleteRuleFields(rules[i], url);
|
|
58
63
|
if (
|
|
59
64
|
Auth.checkCredentials(rules[i], user.auth, user.role, user.root)
|
|
60
65
|
) {
|
|
@@ -66,8 +71,8 @@ class notRoute {
|
|
|
66
71
|
|
|
67
72
|
/**
|
|
68
73
|
* Select rule from available or return null
|
|
69
|
-
* @param {
|
|
70
|
-
* @return {
|
|
74
|
+
* @param {import('../types').ExtendedExpressRequest} req Express Request Object
|
|
75
|
+
* @return {import('../types').notRouteRule | null} rule or null
|
|
71
76
|
*/
|
|
72
77
|
selectRule(req) {
|
|
73
78
|
const user = notAppIdentity.extractAuthData(req);
|
|
@@ -77,8 +82,27 @@ class notRoute {
|
|
|
77
82
|
return null;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
*
|
|
88
|
+
* @param {import('../types').ExtendedExpressRequest} req
|
|
89
|
+
* @param {import('../types').notRouteData} notRouteData
|
|
90
|
+
* @memberof notRoute
|
|
91
|
+
*/
|
|
92
|
+
setRequestRouteData(req, notRouteData) {
|
|
93
|
+
req.notRouteData = notRouteData;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
*
|
|
99
|
+
* @param {string} actionName
|
|
100
|
+
* @param {import('../types').notRouteRule} rule
|
|
101
|
+
* @return {import('../types').notRouteData}
|
|
102
|
+
* @memberof notRoute
|
|
103
|
+
*/
|
|
104
|
+
createRequestRouteData(actionName, rule) {
|
|
105
|
+
return {
|
|
82
106
|
actionName,
|
|
83
107
|
modelName: this.routeName,
|
|
84
108
|
rule: copyObj(rule),
|
|
@@ -88,9 +112,9 @@ class notRoute {
|
|
|
88
112
|
|
|
89
113
|
/**
|
|
90
114
|
* Executes route action if such exist
|
|
91
|
-
* @param {
|
|
92
|
-
* @param {
|
|
93
|
-
* @param {function}
|
|
115
|
+
* @param {import('../types').ExtendedExpressRequest} req Express Request Object
|
|
116
|
+
* @param {import('express').Response} res Express Response Object
|
|
117
|
+
* @param {function} next
|
|
94
118
|
* @return {object} result of execution or HttpError
|
|
95
119
|
**/
|
|
96
120
|
exec(req, res, next) {
|
|
@@ -109,7 +133,7 @@ class notRoute {
|
|
|
109
133
|
);
|
|
110
134
|
}
|
|
111
135
|
console.log(rule);
|
|
112
|
-
|
|
136
|
+
obsoleteRuleFields(rule, req.originalUrl);
|
|
113
137
|
let actionName = this.selectActionName(rule);
|
|
114
138
|
let mod = this.notApp.getModule(this.moduleName);
|
|
115
139
|
if (!mod) {
|
|
@@ -126,7 +150,10 @@ class notRoute {
|
|
|
126
150
|
);
|
|
127
151
|
}
|
|
128
152
|
let modRoute = mod.getRoute(this.routeName);
|
|
129
|
-
this.setRequestRouteData(
|
|
153
|
+
this.setRequestRouteData(
|
|
154
|
+
req,
|
|
155
|
+
this.createRequestRouteData(actionName, rule)
|
|
156
|
+
);
|
|
130
157
|
if (this.routeIsRunnable(modRoute, actionName)) {
|
|
131
158
|
return this.executeRoute(modRoute, actionName, {
|
|
132
159
|
req,
|
|
@@ -148,6 +175,7 @@ class notRoute {
|
|
|
148
175
|
}
|
|
149
176
|
} catch (e) {
|
|
150
177
|
this.notApp.report(e);
|
|
178
|
+
next(e);
|
|
151
179
|
}
|
|
152
180
|
}
|
|
153
181
|
|
package/src/model/default.js
CHANGED
|
@@ -327,7 +327,7 @@ function countWithFilter(filter) {
|
|
|
327
327
|
* Starts add routine
|
|
328
328
|
* @static
|
|
329
329
|
* @param {object} data data
|
|
330
|
-
* @return {Promise<
|
|
330
|
+
* @return {Promise<import('mongoose').Document>} Promise of saved document
|
|
331
331
|
*/
|
|
332
332
|
function add(data) {
|
|
333
333
|
return routine.add(this, data);
|
package/src/model/proto.js
CHANGED
|
@@ -164,7 +164,7 @@ module.exports = class ModelFabricate {
|
|
|
164
164
|
//creating unique indexes
|
|
165
165
|
ModelFabricate.createIndexesForFields(schema, fieldsForIndexes);
|
|
166
166
|
ModelFabricate.createIndexesForText(schema, targetModule);
|
|
167
|
-
//adding specific fields and
|
|
167
|
+
//adding specific fields and identificators
|
|
168
168
|
ModelFabricate.markFor(schema, targetModule);
|
|
169
169
|
//extending schema methods, statics, virtuals by user defined and default content
|
|
170
170
|
ModelFabricate.extendBySource(schema, targetModule);
|
package/src/obsolete.js
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
const log = require("not-log")(module, "Auth");
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const obsoleteRuleFields = function (rule, url = "") {
|
|
4
4
|
if (Object.prototype.hasOwnProperty.call(rule, "user")) {
|
|
5
|
-
log
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
log &&
|
|
6
|
+
log.error(
|
|
7
|
+
`Missformed rule, field "user" is not allowed, use "auth" instead: ${url}`
|
|
8
|
+
);
|
|
8
9
|
}
|
|
9
10
|
if (Object.prototype.hasOwnProperty.call(rule, "admin")) {
|
|
10
|
-
log
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
log &&
|
|
12
|
+
log.error(
|
|
13
|
+
`Missformed rule, field "admin" is obsolete, use "root" instead: ${url}`
|
|
14
|
+
);
|
|
13
15
|
}
|
|
14
16
|
};
|
|
17
|
+
|
|
18
|
+
const obsoleteActionFields = function (action, url = "") {
|
|
19
|
+
if (!Object.prototype.hasOwnProperty.call(action, "rules")) {
|
|
20
|
+
log &&
|
|
21
|
+
log.error(
|
|
22
|
+
`Missformed action, access rule should be moved to object inside property 'rules' (array<object>): ${url}`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
obsoleteRuleFields,
|
|
29
|
+
obsoleteActionFields,
|
|
30
|
+
};
|
package/src/types.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} Query
|
|
3
|
+
* @property {number} skip
|
|
4
|
+
* @property {number} size
|
|
5
|
+
* @property {object} sorter
|
|
6
|
+
* @property {object} [filter]
|
|
7
|
+
* @property {string} [search]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {Object} PreparedData
|
|
12
|
+
* @property {Object} [data]
|
|
13
|
+
* @property {string} [action]
|
|
14
|
+
* @property {Query} [query]
|
|
15
|
+
* @property {number} [targetID] target item ID
|
|
16
|
+
* @property {Object} [activeUser] current user info
|
|
17
|
+
* @property {import('mongoose').Types.ObjectId} [activeUserId] current user document objectId
|
|
18
|
+
* @property {import('mongoose').Types.ObjectId} [targetId] target item objectId
|
|
19
|
+
* @property {string} [ip] current user ip
|
|
20
|
+
* @property {boolean} [root] current user is root
|
|
21
|
+
* @property {boolean} [shouldOwn] if user should be owner of targ
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {object} notRouteRule
|
|
27
|
+
* @property {string} [actionName]
|
|
28
|
+
* @property {string} [actionPrefix]
|
|
29
|
+
* @property {string} [actionSignature]
|
|
30
|
+
* @property {boolean} [root]
|
|
31
|
+
* @property {boolean} [admin]
|
|
32
|
+
* @property {string|Array<string>} [role]
|
|
33
|
+
* @property {boolean} [safe]
|
|
34
|
+
* @property {boolean} [auth]
|
|
35
|
+
* @property {boolean} [user]
|
|
36
|
+
* @property {Array<string | Array<string>>} [fields]
|
|
37
|
+
* @property {Array<string>} [return]
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @typedef {object} notActionData
|
|
42
|
+
* @property {string} [method]
|
|
43
|
+
* @property {string} [actionSignature]
|
|
44
|
+
* @property {string} [postFix]
|
|
45
|
+
* @property {Array<notRouteRule>} rules
|
|
46
|
+
* @property {boolean} [ws]
|
|
47
|
+
* @property {Array<string & Array<string>>} [fields]
|
|
48
|
+
* @property {Array<string>} [return]
|
|
49
|
+
* @property {boolean} [isArray]
|
|
50
|
+
* @property {Array<string>} [data]
|
|
51
|
+
* @property {string} [title]
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {Object} notRouteData
|
|
56
|
+
* @property {string} actionName
|
|
57
|
+
* @property {string} modelName
|
|
58
|
+
* @property {notRouteRule} rule
|
|
59
|
+
* @property {notActionData} actionData
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @typedef {object} notUserDocumentProperties
|
|
64
|
+
* @property {import('mongoose').Types.ObjectId} _id
|
|
65
|
+
* @property {function} isRoot
|
|
66
|
+
* @property {function} isAdmin
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @typedef {import('mongoose').Document & notUserDocumentProperties} notUserDocument
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @typedef {object} notNodeExpressRequestProperties
|
|
75
|
+
* @property {notRouteData} notRouteData
|
|
76
|
+
* @property {notUserDocument} user
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @typedef {import('express').Request & notNodeExpressRequestProperties} notNodeExpressRequest
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
module.exports = {};
|
package/test/auth/fields.js
CHANGED
|
@@ -156,7 +156,7 @@ module.exports = ({ Auth, expect }) => {
|
|
|
156
156
|
expect(result).to.deep.equal(false);
|
|
157
157
|
});
|
|
158
158
|
|
|
159
|
-
it("field.safe.action:Array<string> with special, action:string, roles:Array<string>, special:Array<string>", () => {
|
|
159
|
+
it("field.safe.action:Array<string> with special, action:string, roles:Array<string>, special:Array<string> = ['@owner']", () => {
|
|
160
160
|
const field = {
|
|
161
161
|
safe: {
|
|
162
162
|
update: ["root", "@owner"],
|
|
@@ -169,7 +169,7 @@ module.exports = ({ Auth, expect }) => {
|
|
|
169
169
|
expect(result).to.deep.equal(true);
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
-
it("field.safe.action:Array<string> with special, action:string, roles:Array<string>, special:Array<string>", () => {
|
|
172
|
+
it("field.safe.action:Array<string> with special, action:string, roles:Array<string>, special:Array<string> = ['@system']", () => {
|
|
173
173
|
const field = {
|
|
174
174
|
safe: {
|
|
175
175
|
update: ["root", "@owner"],
|
package/test/auth/obsolete.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
const obsolete = require(
|
|
1
|
+
const obsolete = require("../../src/obsolete");
|
|
2
2
|
module.exports = () => {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
describe("Obsolete rules params warnings", () => {
|
|
4
|
+
it("'user' field presented", () => {
|
|
5
|
+
const obj = {
|
|
6
|
+
user: false,
|
|
7
|
+
};
|
|
8
|
+
obsolete.obsoleteRuleFields(obj);
|
|
9
|
+
});
|
|
9
10
|
});
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
describe("Obsolete action params warnings", () => {
|
|
13
|
+
it("'rules' field not presented", () => {
|
|
14
|
+
const obj = {
|
|
15
|
+
user: false,
|
|
16
|
+
};
|
|
17
|
+
obsolete.obsoleteActionFields(obj);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
13
20
|
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const expect = require("chai").expect,
|
|
2
|
+
extractors = require("../src/form/extractors");
|
|
3
|
+
|
|
4
|
+
describe("Form//Extractors", () => {
|
|
5
|
+
describe("activeUserId", () => {
|
|
6
|
+
it("user object exists ", () => {
|
|
7
|
+
const _id = Math.random();
|
|
8
|
+
const res = extractors.activeUserId({ user: { _id } });
|
|
9
|
+
expect(_id).to.be.equal(res);
|
|
10
|
+
});
|
|
11
|
+
it("user object doesnt exists ", () => {
|
|
12
|
+
const res = extractors.activeUserId({});
|
|
13
|
+
expect(res).to.be.undefined;
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("activeUserModelName", () => {
|
|
18
|
+
const res = extractors.activeUserModelName();
|
|
19
|
+
expect("User").to.be.equal(res);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("fromBody", () => {
|
|
23
|
+
const req = {
|
|
24
|
+
body: {
|
|
25
|
+
a: 1,
|
|
26
|
+
b: 2,
|
|
27
|
+
c: 3,
|
|
28
|
+
d: 4,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
expect(extractors.fromBody(req, "b")).to.be.equal(2);
|
|
32
|
+
expect(extractors.fromBody(req, "e")).to.be.undefined;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("fromParams", () => {
|
|
36
|
+
const req = {
|
|
37
|
+
params: {
|
|
38
|
+
a: 1,
|
|
39
|
+
b: 2,
|
|
40
|
+
c: 3,
|
|
41
|
+
d: 4,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
expect(extractors.fromParams(req, "b")).to.be.equal(2);
|
|
45
|
+
expect(extractors.fromParams(req, "e")).to.be.undefined;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("fromQuery", () => {
|
|
49
|
+
const req = {
|
|
50
|
+
query: {
|
|
51
|
+
a: 1,
|
|
52
|
+
b: 2,
|
|
53
|
+
c: 3,
|
|
54
|
+
d: 4,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
expect(extractors.fromQuery(req, "b")).to.be.equal(2);
|
|
58
|
+
expect(extractors.fromQuery(req, "e")).to.be.undefined;
|
|
59
|
+
});
|
|
60
|
+
});
|
package/test/filter.js
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
const mongoose = require("mongoose");
|
|
2
|
+
const Schema = mongoose.Schema;
|
|
3
|
+
const expect = require("chai").expect,
|
|
4
|
+
notFieldsFilter = require("../src/fields/filter");
|
|
5
|
+
|
|
6
|
+
const SCHEMA = () => {
|
|
7
|
+
return {
|
|
8
|
+
role: {
|
|
9
|
+
type: [String],
|
|
10
|
+
required: true,
|
|
11
|
+
searchable: true,
|
|
12
|
+
default: ["user"],
|
|
13
|
+
validate: [],
|
|
14
|
+
safe: {
|
|
15
|
+
update: ["root", "admin"],
|
|
16
|
+
read: ["@owner", "root", "admin"],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
name: {
|
|
20
|
+
type: String,
|
|
21
|
+
safe: {
|
|
22
|
+
update: ["@system", "@owner", "root", "admin"],
|
|
23
|
+
read: ["*"],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
salt: {
|
|
27
|
+
type: String,
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
telephone: {
|
|
31
|
+
type: String,
|
|
32
|
+
unique: false,
|
|
33
|
+
searchable: true,
|
|
34
|
+
required: false,
|
|
35
|
+
safe: {
|
|
36
|
+
update: ["@owner", "root", "admin"],
|
|
37
|
+
read: ["@owner", "root", "admin"],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
username: {
|
|
41
|
+
type: String,
|
|
42
|
+
unique: true,
|
|
43
|
+
searchable: true,
|
|
44
|
+
required: true,
|
|
45
|
+
safe: {
|
|
46
|
+
read: ["*"],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
confirm: {
|
|
50
|
+
type: Schema.Types.Mixed,
|
|
51
|
+
required: false,
|
|
52
|
+
searchable: true,
|
|
53
|
+
safe: {
|
|
54
|
+
update: ["@system", "root", "admin"],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
code: {
|
|
58
|
+
type: String,
|
|
59
|
+
searchable: true,
|
|
60
|
+
required: true,
|
|
61
|
+
},
|
|
62
|
+
country: {
|
|
63
|
+
type: String,
|
|
64
|
+
required: false,
|
|
65
|
+
searchable: true,
|
|
66
|
+
default: "ru",
|
|
67
|
+
safe: {
|
|
68
|
+
update: ["@system", "@owner", "root", "admin"],
|
|
69
|
+
read: ["*"],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
email: {
|
|
73
|
+
type: String,
|
|
74
|
+
unique: true,
|
|
75
|
+
searchable: true,
|
|
76
|
+
required: true,
|
|
77
|
+
safe: {
|
|
78
|
+
update: ["@owner", "root", "admin"],
|
|
79
|
+
read: ["@owner", "root", "admin"],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
describe("Fields/notFieldsFilter", function () {
|
|
86
|
+
describe("userSets", () => {
|
|
87
|
+
it("static getter", () => {
|
|
88
|
+
expect(notFieldsFilter.userSets).to.be.deep.equal({});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("addSet", () => {
|
|
93
|
+
it("add new", () => {
|
|
94
|
+
const result = notFieldsFilter.addSet("test1", [
|
|
95
|
+
"field1",
|
|
96
|
+
"-field2",
|
|
97
|
+
]);
|
|
98
|
+
expect(result).to.be.true;
|
|
99
|
+
expect(notFieldsFilter.userSets).to.have.key("test1");
|
|
100
|
+
expect(notFieldsFilter.userSets.test1).to.be.deep.equal([
|
|
101
|
+
"field1",
|
|
102
|
+
"-field2",
|
|
103
|
+
]);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("add new with faulty items, discarded", () => {
|
|
107
|
+
const result = notFieldsFilter.addSet("test2", [123123, "-field2"]);
|
|
108
|
+
expect(result).to.be.false;
|
|
109
|
+
expect(notFieldsFilter.userSets).to.not.have.key("test2");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("add new with restricted name, discarded", () => {
|
|
113
|
+
const result = notFieldsFilter.addSet("*", ["-field2"]);
|
|
114
|
+
expect(result).to.be.false;
|
|
115
|
+
expect(notFieldsFilter.userSets).to.not.have.key("test2");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe("removeSet", () => {
|
|
120
|
+
it("set exists", () => {
|
|
121
|
+
const result = notFieldsFilter.removeSet("test1");
|
|
122
|
+
expect(result).to.be.true;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("set not exists", () => {
|
|
126
|
+
const result = notFieldsFilter.removeSet("test1");
|
|
127
|
+
expect(result).to.be.false;
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe("isSpecialSet", () => {
|
|
132
|
+
it("exclude special set", () => {
|
|
133
|
+
const name = "-@*";
|
|
134
|
+
const result = notFieldsFilter.isSpecialSet(name);
|
|
135
|
+
expect(result).to.be.true;
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe("specials", () => {
|
|
139
|
+
it("static specials getter", () => {
|
|
140
|
+
const result = notFieldsFilter.specials;
|
|
141
|
+
expect(result).to.be.instanceOf(Object);
|
|
142
|
+
expect(result).to.have.all.keys([
|
|
143
|
+
"ALL",
|
|
144
|
+
"SAFE",
|
|
145
|
+
"UNSAFE",
|
|
146
|
+
"TIMESTAMPS",
|
|
147
|
+
"OWNAGE",
|
|
148
|
+
"VERSIONING",
|
|
149
|
+
"ID_NUMERIC",
|
|
150
|
+
"ID_UUID",
|
|
151
|
+
]);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it("SPECIAL_SET_SAFE; action=update other undefined", () => {
|
|
155
|
+
const result = notFieldsFilter.getSpecialSetContent(
|
|
156
|
+
notFieldsFilter.specials.SAFE,
|
|
157
|
+
SCHEMA(),
|
|
158
|
+
{ action: "update" }
|
|
159
|
+
);
|
|
160
|
+
expect(result).to.be.deep.equal([]);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("SPECIAL_SET_SAFE; action=read other undefined", () => {
|
|
164
|
+
const result = notFieldsFilter.getSpecialSetContent(
|
|
165
|
+
notFieldsFilter.specials.SAFE,
|
|
166
|
+
SCHEMA(),
|
|
167
|
+
{ action: "read" }
|
|
168
|
+
);
|
|
169
|
+
expect(result).to.be.deep.equal(["name", "username", "country"]);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
describe("specialsToPlain", () => {
|
|
174
|
+
it("get all fields ['@*']", () => {
|
|
175
|
+
const result = notFieldsFilter.specialsToPlain(["@*"], SCHEMA(), {
|
|
176
|
+
modelName: "SomeModel",
|
|
177
|
+
});
|
|
178
|
+
const target = ["_id", "someModelID", ...Object.keys(SCHEMA())];
|
|
179
|
+
expect(Array.isArray(result)).to.be.true;
|
|
180
|
+
expect(result.length).to.be.equal(target.length);
|
|
181
|
+
expect(result).to.be.deep.equal(target);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("get all fields ['@*']", () => {
|
|
185
|
+
const result = notFieldsFilter.specialsToPlain(["@*"], SCHEMA(), {
|
|
186
|
+
modelName: "SomeModel",
|
|
187
|
+
});
|
|
188
|
+
const target = ["_id", "someModelID", ...Object.keys(SCHEMA())];
|
|
189
|
+
expect(Array.isArray(result)).to.be.true;
|
|
190
|
+
expect(result.length).to.be.equal(target.length);
|
|
191
|
+
expect(result).to.be.deep.equal(target);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it("list with special set exclusions", () => {
|
|
195
|
+
const list = ["id", "name", "-@versioning"];
|
|
196
|
+
const result = notFieldsFilter.specialsToPlain(list, SCHEMA(), {
|
|
197
|
+
modelName: "SomeModel",
|
|
198
|
+
});
|
|
199
|
+
expect(result).to.be.deep.equal([
|
|
200
|
+
"id",
|
|
201
|
+
"name",
|
|
202
|
+
"-__version",
|
|
203
|
+
"-__versions",
|
|
204
|
+
"-__closed",
|
|
205
|
+
"-__latest",
|
|
206
|
+
"-__v",
|
|
207
|
+
]);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
describe("removeExcludedFields", () => {
|
|
212
|
+
it("empty list", () => {
|
|
213
|
+
const list = [];
|
|
214
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
215
|
+
expect(result).to.be.deep.equal([]);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("list without exclusions", () => {
|
|
219
|
+
const list = ["id", "name"];
|
|
220
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
221
|
+
expect(result).to.be.deep.equal(["id", "name"]);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("list with exclusions but no target fields presentation in list", () => {
|
|
225
|
+
const list = ["-gag", "id", "name", "-data", "-time"];
|
|
226
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
227
|
+
expect(result).to.be.deep.equal(["id", "name"]);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("list with exclusions predicating includsions", () => {
|
|
231
|
+
const list = ["-id", "id", "name", "-name", "-time"];
|
|
232
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
233
|
+
expect(result).to.be.deep.equal(["id"]);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
it("list with exclusions, end up empty", () => {
|
|
237
|
+
const list = ["id", "-id", "name", "-name", "-time"];
|
|
238
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
239
|
+
expect(result).to.be.deep.equal([]);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("list with exclusions, but later inclusions", () => {
|
|
243
|
+
const list = ["id", "-id", "name", "-name", "id"];
|
|
244
|
+
const result = notFieldsFilter.removeExcludedFields(list);
|
|
245
|
+
expect(result).to.be.deep.equal(["id"]);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe("fieldsListIsNotPlain", () => {
|
|
250
|
+
it("plain list", () => {
|
|
251
|
+
const fields = ["field1", "field2"];
|
|
252
|
+
expect(notFieldsFilter.fieldsListIsNotPlain(fields)).to.be.false;
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it("not plain list, exlusion", () => {
|
|
256
|
+
const fields = ["field1", "-field2"];
|
|
257
|
+
expect(notFieldsFilter.fieldsListIsNotPlain(fields)).to.be.true;
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("not plain list, special set", () => {
|
|
261
|
+
const fields = ["@safe"];
|
|
262
|
+
expect(notFieldsFilter.fieldsListIsNotPlain(fields)).to.be.true;
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
describe("filter", () => {
|
|
267
|
+
it("complex operations exclude/include with deep of 3", () => {
|
|
268
|
+
notFieldsFilter.addSet("user1", ["-@safe"]);
|
|
269
|
+
notFieldsFilter.addSet("user2", ["-@user1"]);
|
|
270
|
+
const result = notFieldsFilter.filter(
|
|
271
|
+
["id", "name", "@user2"],
|
|
272
|
+
SCHEMA(),
|
|
273
|
+
{
|
|
274
|
+
action: "read",
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
expect(result).to.be.deep.equal([
|
|
278
|
+
"id",
|
|
279
|
+
"name",
|
|
280
|
+
"name",
|
|
281
|
+
"username",
|
|
282
|
+
"country",
|
|
283
|
+
]);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
});
|