nodester 0.1.4 → 0.2.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/Readme.md +16 -55
- package/lib/application/index.js +174 -63
- package/lib/body/extract.js +89 -0
- package/lib/constants/Bounds.js +15 -0
- package/lib/constants/Clauses.js +13 -0
- package/lib/constants/ResponseFormats.js +2 -2
- package/lib/controllers/methods/index.js +7 -0
- package/lib/controllers/mixins/index.js +36 -36
- package/lib/database/connection.js +6 -0
- package/lib/database/migration.js +14 -4
- package/lib/facades/methods/index.js +16 -16
- package/lib/facades/mixins/index.js +67 -13
- package/lib/factories/responses/rest.js +25 -13
- package/lib/http/codes/descriptions.js +82 -0
- package/lib/http/codes/index.js +70 -145
- package/lib/http/codes/symbols.js +82 -0
- package/lib/http/{request.js → request/index.js} +53 -75
- package/lib/http/request/utils.js +27 -0
- package/lib/http/response/headers.js +138 -0
- package/lib/http/response/index.js +248 -0
- package/lib/http/response/utils.js +38 -0
- package/lib/middlewares/SearchParams/index.js +25 -0
- package/lib/middlewares/cookies/index.js +44 -0
- package/lib/middlewares/etag/index.js +32 -15
- package/lib/middlewares/formidable/index.js +30 -25
- package/lib/middlewares/ql/sequelize/index.js +13 -4
- package/lib/middlewares/ql/sequelize/interpreter/QueryLexer.js +4 -3
- package/lib/middlewares/render/index.js +62 -0
- package/lib/models/associate.js +25 -1
- package/lib/models/define.js +26 -19
- package/lib/models/mixins.js +8 -1
- package/lib/{queries → query}/traverse.js +118 -77
- package/lib/router/handlers.util.js +1 -0
- package/lib/router/index.js +194 -99
- package/lib/router/markers.js +7 -0
- package/lib/router/route.js +5 -0
- package/lib/router/routes.util.js +16 -14
- package/lib/router/utils.js +7 -0
- package/lib/stacks/MarkersStack.js +41 -3
- package/lib/stacks/MiddlewaresStack.js +200 -0
- package/lib/structures/Enum.js +46 -0
- package/lib/structures/Filter.js +156 -0
- package/lib/structures/Params.js +55 -0
- package/lib/tools/sql.tool.js +7 -0
- package/lib/utils/objects.util.js +31 -24
- package/lib/utils/sanitizations.util.js +10 -4
- package/lib/validators/arguments.js +68 -0
- package/lib/validators/dates.js +7 -0
- package/lib/validators/numbers.js +7 -0
- package/package.json +20 -10
- package/lib/database/utils.js +0 -19
- package/lib/enums/Enum.js +0 -16
- package/lib/http/response.js +0 -1074
- package/lib/http/utils.js +0 -254
- package/lib/params/Params.js +0 -37
- package/lib/policies/Role.js +0 -77
- package/lib/policies/RoleExtracting.js +0 -97
- package/lib/preprocessors/BodyPreprocessor.js +0 -61
- package/lib/queries/Colander.js +0 -107
- package/lib/queries/NodesterQueryParams.js +0 -145
- package/lib/services/includes.service.js +0 -79
- package/lib/services/jwt.service.js +0 -147
- package/lib/stacks/MiddlewareStack.js +0 -159
package/lib/http/utils.js
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* /nodester
|
|
3
|
-
* MIT Licensed
|
|
4
|
-
*/
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const contentType = require('content-type');
|
|
8
|
-
const mime = require('send').mime;
|
|
9
|
-
const etag = require('etag');
|
|
10
|
-
const proxyaddr = require('proxy-addr');
|
|
11
|
-
const qs = require('qs');
|
|
12
|
-
const querystring = require('querystring');
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
exports = module.exports = {
|
|
16
|
-
acceptParams: _acceptParams,
|
|
17
|
-
normalizeType: _normalizeType,
|
|
18
|
-
normalizeTypes: _normalizeTypes,
|
|
19
|
-
compileETag: _compileETag,
|
|
20
|
-
setCharset: _setCharset
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Parse accept params `str` returning an
|
|
26
|
-
* object with `.value`, `.quality` and `.params`.
|
|
27
|
-
* also includes `.originalIndex` for stable sorting
|
|
28
|
-
*
|
|
29
|
-
* @param {String} str
|
|
30
|
-
* @param {Number} index
|
|
31
|
-
* @return {Object}
|
|
32
|
-
*
|
|
33
|
-
* @api private
|
|
34
|
-
*/
|
|
35
|
-
function _acceptParams(str, index) {
|
|
36
|
-
const parts = str.split(/ *; */);
|
|
37
|
-
let result = { value: parts[0], quality: 1, params: {}, originalIndex: index };
|
|
38
|
-
|
|
39
|
-
for (let i = 1; i < parts.length; i++) {
|
|
40
|
-
const pms = parts[i].split(/ *= */);
|
|
41
|
-
if ('q' === pms[0]) {
|
|
42
|
-
result.quality = parseFloat(pms[1]);
|
|
43
|
-
} else {
|
|
44
|
-
result.params[pms[0]] = pms[1];
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return result;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Create an ETag generator function, generating ETags with
|
|
54
|
-
* the given options.
|
|
55
|
-
*
|
|
56
|
-
* @param {object} options
|
|
57
|
-
* @return {function}
|
|
58
|
-
*
|
|
59
|
-
* @private
|
|
60
|
-
*/
|
|
61
|
-
function _createETagGenerator (options) {
|
|
62
|
-
return function generateETag (body, encoding) {
|
|
63
|
-
const buf = !Buffer.isBuffer(body)
|
|
64
|
-
? Buffer.from(body, encoding)
|
|
65
|
-
: body
|
|
66
|
-
|
|
67
|
-
return etag(buf, options)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Normalize the given `type`, for example "html" becomes "text/html".
|
|
74
|
-
*
|
|
75
|
-
* @param {String} type
|
|
76
|
-
* @return {Object}
|
|
77
|
-
*
|
|
78
|
-
* @api private
|
|
79
|
-
*/
|
|
80
|
-
function _normalizeType(type){
|
|
81
|
-
return ~type.indexOf('/')
|
|
82
|
-
? acceptParams(type)
|
|
83
|
-
: { value: mime.lookup(type), params: {} };
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Normalize `types`, for example "html" becomes "text/html".
|
|
89
|
-
*
|
|
90
|
-
* @param {Array} types
|
|
91
|
-
* @return {Array}
|
|
92
|
-
*
|
|
93
|
-
* @api private
|
|
94
|
-
*/
|
|
95
|
-
function _normalizeTypes(types){
|
|
96
|
-
const ret = [];
|
|
97
|
-
|
|
98
|
-
for (let i = 0; i < types.length; ++i) {
|
|
99
|
-
ret.push(
|
|
100
|
-
_normalizeType(types[i])
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return ret;
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Compile "etag" value to function.
|
|
110
|
-
*
|
|
111
|
-
* @param {Boolean|String|Function} val
|
|
112
|
-
* @return {Function}
|
|
113
|
-
*
|
|
114
|
-
* @alias compileETag
|
|
115
|
-
* @api public
|
|
116
|
-
*/
|
|
117
|
-
function _compileETag(val) {
|
|
118
|
-
let fn;
|
|
119
|
-
|
|
120
|
-
if (typeof val === 'function') {
|
|
121
|
-
return val;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
switch (val) {
|
|
125
|
-
case true:
|
|
126
|
-
case 'weak':
|
|
127
|
-
fn = _createETagGenerator({ weak: true });
|
|
128
|
-
break;
|
|
129
|
-
case false:
|
|
130
|
-
break;
|
|
131
|
-
case 'strong':
|
|
132
|
-
fn = _createETagGenerator({ weak: false });
|
|
133
|
-
break;
|
|
134
|
-
default:
|
|
135
|
-
throw new TypeError('unknown value for etag function: ' + val);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return fn;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Compile "query parser" value to function.
|
|
143
|
-
*
|
|
144
|
-
* @param {String|Function} val
|
|
145
|
-
* @return {Function}
|
|
146
|
-
*
|
|
147
|
-
* @api private
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
|
-
exports.compileQueryParser = function compileQueryParser(val) {
|
|
151
|
-
let fn;
|
|
152
|
-
|
|
153
|
-
if (typeof val === 'function') {
|
|
154
|
-
return val;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
switch (val) {
|
|
158
|
-
case true:
|
|
159
|
-
case 'simple':
|
|
160
|
-
fn = querystring.parse;
|
|
161
|
-
break;
|
|
162
|
-
case false:
|
|
163
|
-
fn = newObject;
|
|
164
|
-
break;
|
|
165
|
-
case 'extended':
|
|
166
|
-
fn = parseExtendedQueryString;
|
|
167
|
-
break;
|
|
168
|
-
default:
|
|
169
|
-
throw new TypeError('unknown value for query parser function: ' + val);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return fn;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Compile "proxy trust" value to function.
|
|
177
|
-
*
|
|
178
|
-
* @param {Boolean|String|Number|Array|Function} val
|
|
179
|
-
* @return {Function}
|
|
180
|
-
*
|
|
181
|
-
* @api private
|
|
182
|
-
*/
|
|
183
|
-
exports.compileTrust = function(val) {
|
|
184
|
-
if (typeof val === 'function') return val;
|
|
185
|
-
|
|
186
|
-
if (val === true) {
|
|
187
|
-
// Support plain true/false
|
|
188
|
-
return function(){ return true };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (typeof val === 'number') {
|
|
192
|
-
// Support trusting hop count
|
|
193
|
-
return function(a, i){ return i < val };
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (typeof val === 'string') {
|
|
197
|
-
// Support comma-separated values
|
|
198
|
-
val = val.split(',')
|
|
199
|
-
.map(function (v) { return v.trim() })
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return proxyaddr.compile(val || []);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Set the charset in a given Content-Type string.
|
|
208
|
-
*
|
|
209
|
-
* @param {String} type
|
|
210
|
-
* @param {String} charset
|
|
211
|
-
* @return {String}
|
|
212
|
-
*
|
|
213
|
-
* @api private
|
|
214
|
-
*/
|
|
215
|
-
function _setCharset(type, charset) {
|
|
216
|
-
if (!type || !charset) {
|
|
217
|
-
return type;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// parse type
|
|
221
|
-
const parsed = contentType.parse(type);
|
|
222
|
-
|
|
223
|
-
// set charset
|
|
224
|
-
parsed.parameters.charset = charset;
|
|
225
|
-
|
|
226
|
-
// format type
|
|
227
|
-
return contentType.format(parsed);
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Parse an extended query string with qs.
|
|
233
|
-
*
|
|
234
|
-
* @return {Object}
|
|
235
|
-
* @private
|
|
236
|
-
*/
|
|
237
|
-
function parseExtendedQueryString(str) {
|
|
238
|
-
return qs.parse(str, {
|
|
239
|
-
allowPrototypes: true
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Return new empty object.
|
|
246
|
-
*
|
|
247
|
-
* @return {Object}
|
|
248
|
-
*
|
|
249
|
-
* @api private
|
|
250
|
-
*/
|
|
251
|
-
function newObject() {
|
|
252
|
-
return {};
|
|
253
|
-
}
|
|
254
|
-
|
package/lib/params/Params.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
module.exports = Params;
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Extracts only values in second argument
|
|
6
|
-
* from first argument.
|
|
7
|
-
* If such values is missing in first atgument,
|
|
8
|
-
* will fallback to the value in second argument.
|
|
9
|
-
*
|
|
10
|
-
* @param {Object} sourceObj
|
|
11
|
-
* @param {Object} defaultValuesList
|
|
12
|
-
*
|
|
13
|
-
* @return {Object} result
|
|
14
|
-
*
|
|
15
|
-
* @api public
|
|
16
|
-
*/
|
|
17
|
-
function Params(
|
|
18
|
-
sourceObj={},
|
|
19
|
-
defaultValuesList={}
|
|
20
|
-
) {
|
|
21
|
-
const result = {};
|
|
22
|
-
|
|
23
|
-
const keys = Object.keys(defaultValuesList);
|
|
24
|
-
for (const key of keys) {
|
|
25
|
-
|
|
26
|
-
// If value is not set,
|
|
27
|
-
// use default one from 'defaultValuesList':
|
|
28
|
-
if (sourceObj[key] === undefined) {
|
|
29
|
-
result[key] = defaultValuesList[key];
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
result[key] = sourceObj[key];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return result;
|
|
37
|
-
}
|
package/lib/policies/Role.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// Reponse protocol generator.
|
|
2
|
-
const APIResponseFactory = require('nodester/factories/responses/api');
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
module.exports = class RolePolicy {
|
|
6
|
-
constructor({
|
|
7
|
-
roleName,
|
|
8
|
-
jwtFacade,
|
|
9
|
-
apiResponseFactory,
|
|
10
|
-
}) {
|
|
11
|
-
if (!roleName)
|
|
12
|
-
throw new Error('"roleName" argument is invalid.');
|
|
13
|
-
|
|
14
|
-
if (!jwtFacade)
|
|
15
|
-
throw new Error('"jwtFacade" argument is invalid.');
|
|
16
|
-
|
|
17
|
-
this.roleName = roleName;
|
|
18
|
-
this.jwtFacade = jwtFacade;
|
|
19
|
-
|
|
20
|
-
// Init standard API response factory.
|
|
21
|
-
const standardAPIResponseFactory = new APIResponseFactory();
|
|
22
|
-
|
|
23
|
-
// Set response factory:
|
|
24
|
-
this.createOKResponse = apiResponseFactory?.createOKResponse ??
|
|
25
|
-
standardAPIResponseFactory.createOKResponse.bind(standardAPIResponseFactory);;
|
|
26
|
-
this.createErrorResponse = apiResponseFactory?.createErrorResponse ??
|
|
27
|
-
standardAPIResponseFactory.createErrorResponse.bind(standardAPIResponseFactory);;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async dryRun(req, res, next) {
|
|
31
|
-
try {
|
|
32
|
-
const jwtService = this.jwtFacade.service;
|
|
33
|
-
|
|
34
|
-
// Get token either from header, query or body.
|
|
35
|
-
const token = jwtService.extractTokenFromRequest(req);
|
|
36
|
-
|
|
37
|
-
// Verifys and parses token. On failed validation will throw error.
|
|
38
|
-
const parsedToken = await jwtService.verifyAccessToken(token);
|
|
39
|
-
|
|
40
|
-
// Check role:
|
|
41
|
-
if (parsedToken.role !== this.roleName) {
|
|
42
|
-
const err = new Error(`Unauthorized.`);
|
|
43
|
-
err.name = 'UnauthorizedError';
|
|
44
|
-
err.status = 401;
|
|
45
|
-
throw err;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Everything's good, procceed:
|
|
49
|
-
req.token = {
|
|
50
|
-
parsed: parsedToken,
|
|
51
|
-
initial: token
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return Promise.resolve();
|
|
55
|
-
}
|
|
56
|
-
catch(error) {
|
|
57
|
-
// If error is not 401
|
|
58
|
-
// or
|
|
59
|
-
// error is not "NoToken",
|
|
60
|
-
// log it:
|
|
61
|
-
if (
|
|
62
|
-
['NoToken', 'UnauthorizedError'].indexOf(error?.name) === -1
|
|
63
|
-
) {
|
|
64
|
-
console.error(`${ this.roleName }.policy error:`, error);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const statusCode = error?.status ?? 401;
|
|
68
|
-
|
|
69
|
-
const err = new Error(error.message);
|
|
70
|
-
err.name = error.name ?? 'UnknownError';
|
|
71
|
-
err.details = { message: 'Unauthorized.' }
|
|
72
|
-
err.status = statusCode;
|
|
73
|
-
|
|
74
|
-
return Promise.reject(err);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
// Format for Role header.
|
|
2
|
-
const CLAIMED_ROLE_HEADER_NAME = 'x-claimed-role';
|
|
3
|
-
// Reponse protocol generator.
|
|
4
|
-
const APIResponseFactory = require('nodester/factories/responses/api');
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
module.exports = class RoleExtractingPolicy {
|
|
8
|
-
constructor({
|
|
9
|
-
jwtFacade,
|
|
10
|
-
apiResponseFactory,
|
|
11
|
-
name
|
|
12
|
-
}) {
|
|
13
|
-
|
|
14
|
-
if (!jwtFacade)
|
|
15
|
-
throw new Error('"jwtFacade" argument is invalid.');
|
|
16
|
-
|
|
17
|
-
this.jwtFacade = jwtFacade;
|
|
18
|
-
this.name = name ?? 'RoleExtracting';
|
|
19
|
-
|
|
20
|
-
// Init standard API response factory.
|
|
21
|
-
const standardAPIResponseFactory = new APIResponseFactory();
|
|
22
|
-
|
|
23
|
-
// Set response factory:
|
|
24
|
-
this.createOKResponse = apiResponseFactory?.createOKResponse ??
|
|
25
|
-
standardAPIResponseFactory.createOKResponse.bind(standardAPIResponseFactory);;
|
|
26
|
-
this.createErrorResponse = apiResponseFactory?.createErrorResponse ??
|
|
27
|
-
standardAPIResponseFactory.createErrorResponse.bind(standardAPIResponseFactory);;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async dryRun(req, res, next) {
|
|
31
|
-
try {
|
|
32
|
-
// Get claimed role.
|
|
33
|
-
const claimedRole = req.header(CLAIMED_ROLE_HEADER_NAME);
|
|
34
|
-
|
|
35
|
-
// If claimed role is not set or it's a visitor:
|
|
36
|
-
if (!claimedRole || claimedRole === 'visitor') {
|
|
37
|
-
// Set role as 'visitor'.
|
|
38
|
-
req.user = { role: 'visitor' };
|
|
39
|
-
|
|
40
|
-
return Promise.resolve();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Unwrap JWT service.
|
|
44
|
-
const jwtService = this.jwtFacade.service;
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
// Get access token either from header, query or body.
|
|
48
|
-
const token = jwtService.extractTokenFromRequest(req);
|
|
49
|
-
|
|
50
|
-
// Verifys and parses token. On failed validation will throw error.
|
|
51
|
-
const parsedToken = await jwtService.verifyAccessToken(token);
|
|
52
|
-
|
|
53
|
-
// If parsed token's role is not the same as claimed role,
|
|
54
|
-
// immediately throw error:
|
|
55
|
-
if ( parsedToken?.role !== claimedRole ) {
|
|
56
|
-
const err = new Error('Roles do not match');
|
|
57
|
-
err.name = 'RolesMismatch';
|
|
58
|
-
err.details = { message: 'Unauthorized.' }
|
|
59
|
-
err.status = 401;
|
|
60
|
-
return Promise.reject(err);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Everything's good, procceed:
|
|
64
|
-
req.token = {
|
|
65
|
-
parsed: parsedToken,
|
|
66
|
-
initial: token
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
req.user = { role: parsedToken?.role };
|
|
70
|
-
}
|
|
71
|
-
catch(accessTokenError) {
|
|
72
|
-
// If error is not "NoToken", something bad has happened:
|
|
73
|
-
if (accessTokenError?.name !== 'NoToken') {
|
|
74
|
-
throw accessTokenError;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// If error is "NoToken":
|
|
78
|
-
// Set role as 'visitor'.
|
|
79
|
-
req.user = { role: 'visitor' };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return Promise.resolve();
|
|
83
|
-
}
|
|
84
|
-
catch(error) {
|
|
85
|
-
console.error(`${ this.name }.policy error:`, error);
|
|
86
|
-
|
|
87
|
-
const statusCode = error?.status ?? 401;
|
|
88
|
-
|
|
89
|
-
const err = new Error(error.message);
|
|
90
|
-
err.name = error.name ?? 'UnknownError';
|
|
91
|
-
err.details = { message: 'Unauthorized.' }
|
|
92
|
-
err.status = statusCode;
|
|
93
|
-
|
|
94
|
-
return Promise.reject(err);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Constants.
|
|
2
|
-
const VISITOR = 'visitor';
|
|
3
|
-
|
|
4
|
-
// Custom error.
|
|
5
|
-
const { Err } = require('nodester/factories/errors');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
module.exports = class BodyPreprocessor {
|
|
9
|
-
constructor(
|
|
10
|
-
availableParamsForRoles,
|
|
11
|
-
staticParamsForRoles,
|
|
12
|
-
customProcessFunction
|
|
13
|
-
) {
|
|
14
|
-
this.availableParamsForRoles = availableParamsForRoles ?? {};
|
|
15
|
-
this.staticParamsForRoles = staticParamsForRoles ?? {};
|
|
16
|
-
|
|
17
|
-
this.customProcessFunction = customProcessFunction ? customProcessFunction : ()=>{};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async extract(
|
|
21
|
-
req,
|
|
22
|
-
role
|
|
23
|
-
) {
|
|
24
|
-
try {
|
|
25
|
-
const requestBody = req.body;
|
|
26
|
-
|
|
27
|
-
if (!requestBody || typeof requestBody !== 'object') {
|
|
28
|
-
const err = new Err();
|
|
29
|
-
err.name = 'ValidationError';
|
|
30
|
-
throw err;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Get role or set "visitor"
|
|
34
|
-
const _role = typeof role === 'string' && role.length > 1 ? role : VISITOR;
|
|
35
|
-
|
|
36
|
-
const resultBody = {};
|
|
37
|
-
|
|
38
|
-
const params = this.availableParamsForRoles[_role] ?? [];
|
|
39
|
-
const staticValues = this.staticParamsForRoles[_role] ?? {};
|
|
40
|
-
|
|
41
|
-
params.forEach((param) => {
|
|
42
|
-
// If such param is set in body:
|
|
43
|
-
if (!!requestBody[param]) {
|
|
44
|
-
resultBody[param] = staticValues[param] ?? requestBody[param];
|
|
45
|
-
}
|
|
46
|
-
// If such param is not set, but we have a "static" for it:
|
|
47
|
-
else if (!requestBody[param] && !!staticValues[param]) {
|
|
48
|
-
resultBody[param] = staticValues[param];
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Make further preprocessing using customly defined function.
|
|
53
|
-
await this.customProcessFunction.call(this, req, role, resultBody);
|
|
54
|
-
|
|
55
|
-
return Promise.resolve(resultBody);
|
|
56
|
-
}
|
|
57
|
-
catch(error) {
|
|
58
|
-
return Promise.reject(error);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
package/lib/queries/Colander.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* /nodester
|
|
3
|
-
* MIT Licensed
|
|
4
|
-
*/
|
|
5
|
-
'use strict';
|
|
6
|
-
|
|
7
|
-
const CLAUSES = ['limit', 'skip', 'order', 'order_by'];
|
|
8
|
-
|
|
9
|
-
const { isModel } = require('../utils/models');
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
module.exports = class Colander {
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
*
|
|
16
|
-
* @param {Object|Model} optsOrModelDefinition
|
|
17
|
-
@ - @param {Model} model
|
|
18
|
-
* - @param {Array} fields
|
|
19
|
-
* - @param {Array} clauses
|
|
20
|
-
* - @param {Object} includes
|
|
21
|
-
* - @param {Object} statics
|
|
22
|
-
* -- @param {Object} attributes
|
|
23
|
-
* -- @param {Object} clauses
|
|
24
|
-
*
|
|
25
|
-
* @param {Boolean} noLimit
|
|
26
|
-
*
|
|
27
|
-
*/
|
|
28
|
-
constructor(optsOrModelDefinition, noLimit=false) {
|
|
29
|
-
this._fields = [];
|
|
30
|
-
this._clauses = [];
|
|
31
|
-
this._includes = {};
|
|
32
|
-
|
|
33
|
-
this._statics = {
|
|
34
|
-
attributes: {},
|
|
35
|
-
clauses: {
|
|
36
|
-
limit: 3
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (noLimit === true) {
|
|
40
|
-
delete this._statics.clauses.limit;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// If model:
|
|
44
|
-
if (isModel(optsOrModelDefinition)) {
|
|
45
|
-
this._fields = Object.keys(optsOrModelDefinition.tableAttributes);
|
|
46
|
-
this._clauses = CLAUSES;
|
|
47
|
-
}
|
|
48
|
-
// If options:
|
|
49
|
-
else {
|
|
50
|
-
const {
|
|
51
|
-
model,
|
|
52
|
-
fields,
|
|
53
|
-
clauses,
|
|
54
|
-
includes,
|
|
55
|
-
statics,
|
|
56
|
-
} = optsOrModelDefinition;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// If fields are array:
|
|
60
|
-
if (Array.isArray(fields)) {
|
|
61
|
-
this._fields = fields;
|
|
62
|
-
}
|
|
63
|
-
// If fields were not provided,
|
|
64
|
-
// but we have full model definition:
|
|
65
|
-
else if (isModel(model)) {
|
|
66
|
-
this._fields = Object.keys(model.tableAttributes);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (Array.isArray(clauses)) {
|
|
71
|
-
this._clauses = clauses;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (typeof includes === 'object') {
|
|
75
|
-
this._includes = includes;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (typeof statics === 'object') {
|
|
79
|
-
if (typeof statics.attributes === 'object') {
|
|
80
|
-
this._statics.attributes = statics.attributes;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (typeof statics.clauses === 'object') {
|
|
84
|
-
this._statics.clauses = statics.clauses;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Getters:
|
|
91
|
-
get fields() {
|
|
92
|
-
return this._fields;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get clauses() {
|
|
96
|
-
return this._clauses;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
get includes() {
|
|
100
|
-
return this._includes;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
get statics() {
|
|
104
|
-
return this._statics;
|
|
105
|
-
}
|
|
106
|
-
// Getters\
|
|
107
|
-
}
|