nodester 0.0.8 → 0.1.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 +18 -59
- package/lib/application/index.js +28 -7
- package/lib/controllers/methods/index.js +34 -10
- package/lib/controllers/mixins/index.js +14 -5
- package/lib/database/connection.js +34 -0
- package/lib/database/migration.js +42 -0
- package/lib/database/utils.js +19 -0
- package/lib/facades/methods/index.js +173 -0
- package/lib/facades/mixins/index.js +111 -0
- package/lib/middlewares/formidable/index.js +37 -0
- package/lib/middlewares/ql/sequelize/interpreter/ModelsTree.js +2 -2
- package/lib/middlewares/ql/sequelize/interpreter/QueryLexer.js +3 -3
- package/lib/models/associate.js +17 -0
- package/lib/models/define.js +50 -1
- package/lib/models/mixins.js +81 -72
- package/lib/params/Params.js +10 -7
- package/lib/queries/Colander.js +84 -0
- package/lib/queries/traverse.js +311 -0
- package/lib/router/handlers.util.js +22 -2
- package/lib/router/index.js +96 -75
- package/lib/router/markers.js +78 -0
- package/lib/router/route.js +4 -4
- package/lib/router/routes.util.js +35 -5
- package/lib/router/utils.js +30 -0
- package/package.json +20 -7
- package/tests/nql.test.js +3 -3
- package/lib/_/n_controllers/Controller.js +0 -474
- package/lib/_/n_controllers/JWTController.js +0 -240
- package/lib/_/n_controllers/ServiceController.js +0 -109
- package/lib/_/n_controllers/WebController.js +0 -75
- package/lib/_facades/Facade.js +0 -388
- package/lib/_facades/FacadeParams.js +0 -11
- package/lib/_facades/ServiceFacade.js +0 -17
- package/lib/_facades/jwt.facade.js +0 -273
- package/lib/models/DisabledRefreshToken.js +0 -68
- package/lib/models/Extractor.js +0 -320
- package/lib/utils/forms.util.js +0 -22
|
@@ -11,10 +11,21 @@ const { parseRouteHandler } = require('./handlers.util');
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
module.exports = {
|
|
14
|
+
validateParsedRouteMethood: _validateParsedRouteMethood,
|
|
14
15
|
wrapRouteHandler: _wrapRouteHandler
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
function _validateParsedRouteMethood(parsedRoute) {
|
|
20
|
+
if (!parsedRoute || parsedRoute?.method === undefined) {
|
|
21
|
+
const err = new TypeError(`"route" should start with one of the following methods: [GET, POST, PUT, DELETE, QUERY, HEADER, OPTIONS]`);
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
18
29
|
/**
|
|
19
30
|
* Wraps route handler.
|
|
20
31
|
*
|
|
@@ -48,17 +59,36 @@ function _wrapRouteHandler(routeInstance, handler) {
|
|
|
48
59
|
else {
|
|
49
60
|
const parsedHandler = parseRouteHandler(handler);
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
let providedAction = null;
|
|
63
|
+
|
|
64
|
+
// If Controller:
|
|
65
|
+
if (parsedHandler.controllerName !== undefined) {
|
|
66
|
+
// Get method (action) from Controller:
|
|
67
|
+
const controller = this._controllers.get(parsedHandler.controllerName);
|
|
68
|
+
const controllerAction = controller[parsedHandler.actionName];
|
|
54
69
|
|
|
55
|
-
|
|
70
|
+
providedAction = controllerAction;
|
|
71
|
+
}
|
|
72
|
+
// If Controller\
|
|
73
|
+
|
|
74
|
+
// If Provider:
|
|
75
|
+
else {
|
|
76
|
+
// Get method (action) from Provider:
|
|
77
|
+
const provider = this._providers.get(parsedHandler.providerName);
|
|
78
|
+
const providerAction = provider[parsedHandler.actionName];
|
|
79
|
+
|
|
80
|
+
providedAction = providerAction;
|
|
81
|
+
}
|
|
82
|
+
// If Provider\
|
|
83
|
+
|
|
84
|
+
// If User set any handler before,
|
|
85
|
+
// call it first:
|
|
56
86
|
if (typeOf(parsedHandler.before) === 'function') {
|
|
57
87
|
// Expose nquery first.
|
|
58
88
|
await parsedHandler.before(req.nquery, req, res);
|
|
59
89
|
}
|
|
60
90
|
|
|
61
|
-
await
|
|
91
|
+
await providedAction(req, res);
|
|
62
92
|
}
|
|
63
93
|
};
|
|
64
94
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = {
|
|
3
|
+
parseProviderFileNames: _parseProviderFileNames
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function _parseProviderFileNames(fileNames, availableFileExtensions, term='controller') {
|
|
7
|
+
const resultNames = [];
|
|
8
|
+
|
|
9
|
+
for (const fileName of fileNames) {
|
|
10
|
+
|
|
11
|
+
const nameParts = fileName.split('.');
|
|
12
|
+
const extension = nameParts.pop();
|
|
13
|
+
if (availableFileExtensions.indexOf(extension) === -1) {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// If the name format is <model>.<term>,
|
|
18
|
+
// but second part is not "term":
|
|
19
|
+
if (nameParts.length > 1 && nameParts[1] !== term)
|
|
20
|
+
continue;
|
|
21
|
+
|
|
22
|
+
const result = {
|
|
23
|
+
fileName: fileName,
|
|
24
|
+
[`${ term }Name`]: nameParts[0]
|
|
25
|
+
}
|
|
26
|
+
resultNames.push(result);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return resultNames;
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodester",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "A boilerplate framework for Node.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/application/index.js",
|
|
7
|
+
"./controllers/methods": "./lib/controllers/methods/index.js",
|
|
7
8
|
"./controllers/mixins": "./lib/controllers/mixins/index.js",
|
|
8
|
-
"./
|
|
9
|
+
"./database/connection": "./lib/database/connection.js",
|
|
10
|
+
"./database/migration": "./lib/database/migration.js",
|
|
11
|
+
"./database/utils": "./lib/database/utils.js",
|
|
9
12
|
"./enum": "./lib/enums/Enum.js",
|
|
13
|
+
"./facades/methods": "./lib/facades/methods/index.js",
|
|
14
|
+
"./facades/mixins": "./lib/facades/mixins/index.js",
|
|
10
15
|
"./factories/errors": "./lib/factories/errors/index.js",
|
|
11
16
|
"./factories/responses/rest": "./lib/factories/responses/rest/index.js",
|
|
12
17
|
"./http/codes": "./lib/http/codes/index.js",
|
|
18
|
+
"./middlewares/formidable": "./lib/middlewares/formidable/index.js",
|
|
19
|
+
"./models/associate": "./lib/models/associate.js",
|
|
13
20
|
"./models/define": "./lib/models/define.js",
|
|
14
21
|
"./params": "./lib/params/Params.js",
|
|
15
22
|
"./ql/sequelize": "./lib/middlewares/ql/sequelize",
|
|
23
|
+
"./queries/Colander": "./lib/queries/Colander.js",
|
|
24
|
+
"./queries/traverse": "./lib/queries/traverse.js",
|
|
16
25
|
"./route": "./lib/router/route.js",
|
|
17
|
-
"./router": "./lib/router/index.js"
|
|
26
|
+
"./router": "./lib/router/index.js",
|
|
27
|
+
"./utils/strings": "./lib/utils/strings.util.js"
|
|
18
28
|
},
|
|
19
29
|
"directories": {
|
|
20
30
|
"doc": "docs"
|
|
@@ -23,9 +33,8 @@
|
|
|
23
33
|
"lib"
|
|
24
34
|
],
|
|
25
35
|
"scripts": {
|
|
26
|
-
"
|
|
27
|
-
"examples:
|
|
28
|
-
"test": "jest"
|
|
36
|
+
"test": "jest",
|
|
37
|
+
"examples:rest": "node ./examples/rest/index.js"
|
|
29
38
|
},
|
|
30
39
|
"author": "Mark Khramko <markkhramko@gmail.com>",
|
|
31
40
|
"license": "MIT",
|
|
@@ -49,6 +58,7 @@
|
|
|
49
58
|
"dependencies": {
|
|
50
59
|
"@js-temporal/polyfill": "^0.4.3",
|
|
51
60
|
"accepts": "^1.3.8",
|
|
61
|
+
"body-parser": "^1.20.2",
|
|
52
62
|
"common-js-file-extensions": "^1.0.4",
|
|
53
63
|
"content-disposition": "^0.5.4",
|
|
54
64
|
"content-type": "^1.0.5",
|
|
@@ -57,10 +67,13 @@
|
|
|
57
67
|
"debug": "^4.3.4",
|
|
58
68
|
"etag": "^1.8.1",
|
|
59
69
|
"finalhandler": "^1.2.0",
|
|
60
|
-
"formidable": "^
|
|
70
|
+
"formidable": "^3.5.1",
|
|
61
71
|
"fresh": "^0.5.2",
|
|
62
72
|
"http-errors": "^2.0.0",
|
|
63
73
|
"inflection": "^2.0.1",
|
|
74
|
+
"mysql2": "^3.6.0",
|
|
75
|
+
"pg": "^8.11.3",
|
|
76
|
+
"pg-hstore": "^2.3.4",
|
|
64
77
|
"proxy-addr": "^2.0.7",
|
|
65
78
|
"qs": "^6.11.0",
|
|
66
79
|
"range-parser": "^1.2.1",
|
package/tests/nql.test.js
CHANGED
|
@@ -73,7 +73,7 @@ describe('nodester Query Language', () => {
|
|
|
73
73
|
tree.node.limit = 3;
|
|
74
74
|
tree.node.skip = 10;
|
|
75
75
|
tree.node.order = 'desc';
|
|
76
|
-
tree.node.
|
|
76
|
+
tree.node.order_by = 'index';
|
|
77
77
|
const expected = tree.root.toObject();
|
|
78
78
|
|
|
79
79
|
expect(result).toMatchObject(expected);
|
|
@@ -103,7 +103,7 @@ describe('nodester Query Language', () => {
|
|
|
103
103
|
tree.node.limit = 3;
|
|
104
104
|
tree.node.skip = 10;
|
|
105
105
|
tree.node.order = 'desc';
|
|
106
|
-
tree.node.
|
|
106
|
+
tree.node.order_by = 'index';
|
|
107
107
|
const expected = tree.root.toObject();
|
|
108
108
|
|
|
109
109
|
expect(result).toMatchObject(expected);
|
|
@@ -157,7 +157,7 @@ describe('nodester Query Language', () => {
|
|
|
157
157
|
tree.include('users');
|
|
158
158
|
tree.include('likes') && tree.use('likes');
|
|
159
159
|
tree.node.order = 'rand';
|
|
160
|
-
tree.node.
|
|
160
|
+
tree.node.order_by = 'position';
|
|
161
161
|
tree.up();
|
|
162
162
|
const expected = tree.root.toObject();
|
|
163
163
|
|
|
@@ -1,474 +0,0 @@
|
|
|
1
|
-
// Constants.
|
|
2
|
-
const VISITOR = 'visitor';
|
|
3
|
-
// Data extractor:
|
|
4
|
-
const Extractor = require('nodester/models/Extractor');
|
|
5
|
-
// Preprocessors:
|
|
6
|
-
const QueryPreprocessor = require('nodester/preprocessors/QueryPreprocessor');
|
|
7
|
-
const BodyPreprocessor = require('nodester/preprocessors/BodyPreprocessor');
|
|
8
|
-
// Reponse protocol generator.
|
|
9
|
-
const APIResponseFactory = require('nodester/factories/responses/api');
|
|
10
|
-
// Custom error.
|
|
11
|
-
const { Err } = require('nodester/factories/errors');
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
module.exports = class Controller {
|
|
15
|
-
constructor({
|
|
16
|
-
modelFacade,
|
|
17
|
-
|
|
18
|
-
queryPreprocessor,
|
|
19
|
-
bodyPreprocessor,
|
|
20
|
-
|
|
21
|
-
apiResponseFactory,
|
|
22
|
-
|
|
23
|
-
// Options.
|
|
24
|
-
withFiles,
|
|
25
|
-
}) {
|
|
26
|
-
if (!modelFacade) {
|
|
27
|
-
throw new Error('"modelFacade" argument is invalid.');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Main model.
|
|
31
|
-
const model = modelFacade?.model;
|
|
32
|
-
|
|
33
|
-
// Set main services & utils:
|
|
34
|
-
this.extractor = new Extractor(model, { withFiles: !!withFiles });
|
|
35
|
-
this.facade = modelFacade;
|
|
36
|
-
|
|
37
|
-
// Set preprocessors:
|
|
38
|
-
// TODO: includes preprocessor.
|
|
39
|
-
this.queryPreprocessor = queryPreprocessor ?? new QueryPreprocessor();
|
|
40
|
-
this.bodyPreprocessor = bodyPreprocessor ?? null;
|
|
41
|
-
|
|
42
|
-
// Extract plural name of model.
|
|
43
|
-
const modelPluralName = model?.options?.name?.plural;
|
|
44
|
-
// Set private name of this controller.
|
|
45
|
-
this.name = `${modelPluralName ?? '_INVALID_NAME_'}Controller`;
|
|
46
|
-
|
|
47
|
-
// Init standard API response factory.
|
|
48
|
-
const standardAPIResponseFactory = new APIResponseFactory();
|
|
49
|
-
// Set response factory:
|
|
50
|
-
this.createOKResponse = apiResponseFactory?.createOKResponse ??
|
|
51
|
-
standardAPIResponseFactory.createOKResponse.bind(standardAPIResponseFactory);
|
|
52
|
-
this.createErrorResponse = apiResponseFactory?.createErrorResponse ??
|
|
53
|
-
standardAPIResponseFactory.createErrorResponse.bind(standardAPIResponseFactory);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
processError(error, req, res) {
|
|
57
|
-
// Default error message.
|
|
58
|
-
let errorMessage = error?.message ?? 'Internal server error';
|
|
59
|
-
// Default HTTP status code.
|
|
60
|
-
let statusCode = error?.status ?? error?.statusCode ?? 500;
|
|
61
|
-
// Error response object.
|
|
62
|
-
let errorResponse = {};
|
|
63
|
-
|
|
64
|
-
switch(error.name) {
|
|
65
|
-
case('Unauthorized'): {
|
|
66
|
-
statusCode = 401;
|
|
67
|
-
errorResponse.details = { message: 'Unauthorized' };
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
case('NotFound'): {
|
|
71
|
-
statusCode = 404;
|
|
72
|
-
errorResponse.details = { message: errorMessage };
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
case('ValidationError'): {
|
|
76
|
-
statusCode = 406;
|
|
77
|
-
errorResponse.details = error?.details;
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
case('ConflictError'): {
|
|
81
|
-
statusCode = 409;
|
|
82
|
-
errorResponse.details = error?.details ?? error?.message;
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
case('SequelizeUniqueConstraintError'): {
|
|
86
|
-
statusCode = 409;
|
|
87
|
-
errorResponse.details = error?.errors;
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
case('InternalValidationError'): {
|
|
91
|
-
statusCode = 500;
|
|
92
|
-
errorResponse.details = { message:'Error' };
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
default: {
|
|
96
|
-
errorResponse.details = { message:errorMessage };
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Send error response with provided status code.
|
|
102
|
-
return this.createErrorResponse({
|
|
103
|
-
res,
|
|
104
|
-
error: {
|
|
105
|
-
...errorResponse,
|
|
106
|
-
code: statusCode
|
|
107
|
-
},
|
|
108
|
-
status: statusCode
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/* POST: */
|
|
113
|
-
async createOne(req, res) {
|
|
114
|
-
try {
|
|
115
|
-
// Extract all required info:
|
|
116
|
-
const {
|
|
117
|
-
// query,
|
|
118
|
-
includes
|
|
119
|
-
} = await this.extractQuery(req, res);
|
|
120
|
-
|
|
121
|
-
// Extract request's body.
|
|
122
|
-
const { body } = await this.extractBody(req, res);
|
|
123
|
-
|
|
124
|
-
// Extract new instance data.
|
|
125
|
-
const data = this.extractor.extractInstanceDataFromObject(
|
|
126
|
-
body,
|
|
127
|
-
includes,
|
|
128
|
-
{
|
|
129
|
-
skipIdValidation: true
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const result = await this.facade.createOne({ data, includes });
|
|
133
|
-
|
|
134
|
-
// Hook.
|
|
135
|
-
await this.afterCreateOne(req, res, result);
|
|
136
|
-
|
|
137
|
-
return this.createOKResponse({
|
|
138
|
-
res,
|
|
139
|
-
content: { ...result }
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch(error) {
|
|
143
|
-
console.error(`${ this.name }.createOne error:`, error);
|
|
144
|
-
return this.processError(error, req, res);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
/* POST\ */
|
|
148
|
-
|
|
149
|
-
/* GET: */
|
|
150
|
-
async getOne(req, res) {
|
|
151
|
-
try {
|
|
152
|
-
// Extract all required info:
|
|
153
|
-
const {
|
|
154
|
-
query,
|
|
155
|
-
includes
|
|
156
|
-
} = await this.extractQuery(req, res);
|
|
157
|
-
|
|
158
|
-
const params = {
|
|
159
|
-
query,
|
|
160
|
-
includes,
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// If Query or Params contains main identifier (id),
|
|
164
|
-
// validate it:
|
|
165
|
-
if (!!query.id) {
|
|
166
|
-
// Extract main identifier.
|
|
167
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
168
|
-
query,
|
|
169
|
-
null,
|
|
170
|
-
{
|
|
171
|
-
skipValidation: true
|
|
172
|
-
});
|
|
173
|
-
params.id = id;
|
|
174
|
-
}
|
|
175
|
-
// If Request's Params contains main identifier (id),
|
|
176
|
-
// validate it:
|
|
177
|
-
else if (!!req.params.id) {
|
|
178
|
-
// Extract main identifier.
|
|
179
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
180
|
-
req.params,
|
|
181
|
-
null,
|
|
182
|
-
{
|
|
183
|
-
skipValidation: true
|
|
184
|
-
});
|
|
185
|
-
params.id = id;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const result = await this.facade.getOne(params);
|
|
189
|
-
|
|
190
|
-
return this.createOKResponse({
|
|
191
|
-
res,
|
|
192
|
-
content: { ...result }
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
catch(error) {
|
|
196
|
-
console.error(`${ this.name }.getOne error:`, error);
|
|
197
|
-
return this.processError(error, req, res);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async getMany(req, res) {
|
|
202
|
-
try {
|
|
203
|
-
// Extract all required info:
|
|
204
|
-
const {
|
|
205
|
-
query,
|
|
206
|
-
includes
|
|
207
|
-
} = await this.extractQuery(req, res);
|
|
208
|
-
|
|
209
|
-
const params = {
|
|
210
|
-
query,
|
|
211
|
-
includes,
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// If Query contains main identifier (id),
|
|
215
|
-
// validate it:
|
|
216
|
-
if (!!query.id) {
|
|
217
|
-
// Extract main identifier.
|
|
218
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
219
|
-
query,
|
|
220
|
-
null,
|
|
221
|
-
{
|
|
222
|
-
skipValidation: true
|
|
223
|
-
});
|
|
224
|
-
params.query.id = id;
|
|
225
|
-
}
|
|
226
|
-
// If Request's Params contains main identifier (id),
|
|
227
|
-
// validate it:
|
|
228
|
-
else if (!!req.params.id) {
|
|
229
|
-
// Extract main identifier.
|
|
230
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
231
|
-
req.params,
|
|
232
|
-
null,
|
|
233
|
-
{
|
|
234
|
-
skipValidation: true
|
|
235
|
-
});
|
|
236
|
-
params.query.id = id;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const result = await this.facade.getMany(params);
|
|
240
|
-
|
|
241
|
-
return this.createOKResponse({
|
|
242
|
-
res,
|
|
243
|
-
content: { ...result }
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
catch(error) {
|
|
247
|
-
console.error(`${ this.name }.getMany error:`, error);
|
|
248
|
-
return this.processError(error, req, res);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
/* GET\ */
|
|
252
|
-
|
|
253
|
-
/* PUT: */
|
|
254
|
-
async updateOne(req, res) {
|
|
255
|
-
try {
|
|
256
|
-
// Extract all required info:
|
|
257
|
-
const {
|
|
258
|
-
query,
|
|
259
|
-
includes
|
|
260
|
-
} = await this.extractQuery(req, res);
|
|
261
|
-
|
|
262
|
-
// Extract request's body.
|
|
263
|
-
const { body } = await this.extractBody(req, res);
|
|
264
|
-
|
|
265
|
-
// Init facade params.
|
|
266
|
-
const facadeParams = {
|
|
267
|
-
query,
|
|
268
|
-
includes,
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
// If request params contain main identifier (id),
|
|
272
|
-
// extract & validate it:
|
|
273
|
-
if (!!req.params.id) {
|
|
274
|
-
// Extract main identifier.
|
|
275
|
-
facadeParams.query.id = parseInt(req.params.id);
|
|
276
|
-
}
|
|
277
|
-
// If Query contains main identifier (id),
|
|
278
|
-
// validate it:
|
|
279
|
-
else if (!!query.id) {
|
|
280
|
-
// Extract main identifier.
|
|
281
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
282
|
-
query,
|
|
283
|
-
null,
|
|
284
|
-
{
|
|
285
|
-
skipValidation: true
|
|
286
|
-
});
|
|
287
|
-
facadeParams.query.id = id;
|
|
288
|
-
}
|
|
289
|
-
// Extract instance data.
|
|
290
|
-
const data = this.extractor.extractInstanceDataFromObject(
|
|
291
|
-
body,
|
|
292
|
-
includes,
|
|
293
|
-
{
|
|
294
|
-
skipIdValidation: true,
|
|
295
|
-
skipValidation: true
|
|
296
|
-
});
|
|
297
|
-
facadeParams.data = data;
|
|
298
|
-
|
|
299
|
-
const result = await this.facade.updateOne(facadeParams);
|
|
300
|
-
|
|
301
|
-
// Hook.
|
|
302
|
-
await this.afterUpdateOne(req, res, result);
|
|
303
|
-
|
|
304
|
-
return this.createOKResponse({
|
|
305
|
-
res,
|
|
306
|
-
content: { ...result }
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
catch(error) {
|
|
310
|
-
console.error(`${ this.name }.updateOne error:`, error);
|
|
311
|
-
return this.processError(error, req, res);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/* ! Warning !
|
|
316
|
-
* Unfinished method
|
|
317
|
-
* Do not use!
|
|
318
|
-
*/
|
|
319
|
-
async updateMany(req, res) {
|
|
320
|
-
try {
|
|
321
|
-
// Extract all required info:
|
|
322
|
-
const {
|
|
323
|
-
query,
|
|
324
|
-
includes
|
|
325
|
-
} = await this.extractQuery(req, res);
|
|
326
|
-
|
|
327
|
-
// If Query contains main identifier (id),
|
|
328
|
-
// extract & validate it:
|
|
329
|
-
if (!!query.id) {
|
|
330
|
-
// Extract main identifier.
|
|
331
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
332
|
-
query,
|
|
333
|
-
null,
|
|
334
|
-
{
|
|
335
|
-
skipValidation: true
|
|
336
|
-
});
|
|
337
|
-
query.id = id;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
// Extract data array:
|
|
341
|
-
const data = this.extractor.extractArrayDataFromObject(
|
|
342
|
-
req.body,
|
|
343
|
-
{
|
|
344
|
-
skipIdValidation: true,
|
|
345
|
-
skipValidation: true
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
console.log("Controller.updateMany", { data });
|
|
349
|
-
|
|
350
|
-
// TODO: Finish procedure
|
|
351
|
-
return;
|
|
352
|
-
// const result = await this.facade.updateMany({ data, includes });
|
|
353
|
-
|
|
354
|
-
// return this.createOKResponse({
|
|
355
|
-
// res,
|
|
356
|
-
// content: { ...result }
|
|
357
|
-
// });
|
|
358
|
-
}
|
|
359
|
-
catch(error) {
|
|
360
|
-
console.error(`${ this.name }.updateMany error:`, error);
|
|
361
|
-
return this.processError(error, req, res);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/* PUT\ */
|
|
365
|
-
|
|
366
|
-
/* DELETE: */
|
|
367
|
-
async deleteOne(req, res) {
|
|
368
|
-
try {
|
|
369
|
-
// Extract main identifier.
|
|
370
|
-
const { id } = this.extractor.extractInstanceDataFromObject(
|
|
371
|
-
req.params,
|
|
372
|
-
null,
|
|
373
|
-
{
|
|
374
|
-
skipValidation: true
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
const result = await this.facade.deleteOne({ id });
|
|
378
|
-
|
|
379
|
-
// Hook.
|
|
380
|
-
await this.afterDeleteOne(req, res, result);
|
|
381
|
-
|
|
382
|
-
return this.createOKResponse({
|
|
383
|
-
res,
|
|
384
|
-
content: { ...result }
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
catch(error) {
|
|
388
|
-
console.error(`${ this.name }.deleteOne error:`, error);
|
|
389
|
-
return this.processError(error, req, res);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
/* DELETE\ */
|
|
393
|
-
|
|
394
|
-
/*
|
|
395
|
-
* Hooks:
|
|
396
|
-
*/
|
|
397
|
-
async afterCreateOne(
|
|
398
|
-
req, res,
|
|
399
|
-
facadeResult
|
|
400
|
-
) {
|
|
401
|
-
// This method is empty, as it should be overwritten.
|
|
402
|
-
const content = { ...facadeResult };
|
|
403
|
-
return Promise.resolve(content);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
async afterUpdateOne(
|
|
407
|
-
req, res,
|
|
408
|
-
facadeResult
|
|
409
|
-
) {
|
|
410
|
-
// This method is empty, as it should be overwritten.
|
|
411
|
-
const content = { ...facadeResult };
|
|
412
|
-
return Promise.resolve(content);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
async afterDeleteOne(
|
|
416
|
-
req, res,
|
|
417
|
-
facadeResult
|
|
418
|
-
) {
|
|
419
|
-
// This method is empty, as it should be overwritten.
|
|
420
|
-
const content = { ...facadeResult };
|
|
421
|
-
return Promise.resolve(content);
|
|
422
|
-
}
|
|
423
|
-
/*
|
|
424
|
-
* Hooks\
|
|
425
|
-
*/
|
|
426
|
-
|
|
427
|
-
// Preprocessors:
|
|
428
|
-
async extractQuery(req, res) {
|
|
429
|
-
try {
|
|
430
|
-
// Extract role.
|
|
431
|
-
const role = req?.token?.parsed?.role ?? VISITOR;
|
|
432
|
-
|
|
433
|
-
// Extract query:
|
|
434
|
-
const query = await this.queryPreprocessor.extract(
|
|
435
|
-
req,
|
|
436
|
-
role,
|
|
437
|
-
);
|
|
438
|
-
const { includes } = req.query;
|
|
439
|
-
|
|
440
|
-
return Promise.resolve({
|
|
441
|
-
query,
|
|
442
|
-
includes,
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
catch(error) {
|
|
446
|
-
return Promise.reject(error);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
async extractBody(req, res, externalBodyObject=null) {
|
|
451
|
-
try {
|
|
452
|
-
// Extract role.
|
|
453
|
-
const role = req?.token?.parsed?.role ?? VISITOR;
|
|
454
|
-
|
|
455
|
-
// Extract body:
|
|
456
|
-
let body = externalBodyObject ?? req.body;
|
|
457
|
-
|
|
458
|
-
if (!!this.bodyPreprocessor) {
|
|
459
|
-
body = await this.bodyPreprocessor.extract(
|
|
460
|
-
req,
|
|
461
|
-
role,
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
return Promise.resolve({
|
|
466
|
-
body,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
catch(error) {
|
|
470
|
-
return Promise.reject(error);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
// Preprocessors\
|
|
474
|
-
}
|