nodester 0.0.9 → 0.1.4
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 -2
- package/lib/application/index.js +29 -8
- package/lib/constants/ErrorCodes.js +19 -0
- package/lib/constants/Operations.js +1 -1
- package/lib/controllers/methods/index.js +34 -10
- package/lib/controllers/mixins/index.js +72 -24
- 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 +180 -0
- package/lib/facades/mixins/index.js +111 -0
- package/lib/factories/errors/CustomError.js +7 -0
- package/lib/factories/errors/NodesterQueryError.js +23 -0
- package/lib/factories/errors/index.js +10 -3
- package/lib/loggers/dev.js +28 -0
- package/lib/middlewares/formidable/index.js +37 -0
- package/lib/middlewares/ql/sequelize/interpreter/ModelsTree.js +26 -3
- package/lib/middlewares/ql/sequelize/interpreter/QueryLexer.js +67 -15
- package/lib/models/define.js +49 -1
- package/lib/models/mixins.js +76 -67
- package/lib/params/Params.js +10 -7
- package/lib/queries/Colander.js +107 -0
- package/lib/queries/NodesterQueryParams.js +6 -0
- package/lib/queries/traverse.js +381 -0
- package/lib/router/handlers.util.js +22 -2
- package/lib/router/index.js +97 -76
- 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/lib/stacks/MarkersStack.js +1 -1
- package/lib/stacks/MiddlewareStack.js +1 -1
- package/lib/utils/models.js +14 -0
- package/package.json +36 -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/Extractor.js +0 -320
- package/lib/preprocessors/IncludesPreprocessor.js +0 -55
- package/lib/preprocessors/QueryPreprocessor.js +0 -64
- package/lib/utils/forms.util.js +0 -22
- /package/lib/{logger → loggers}/console.js +0 -0
package/Readme.md
CHANGED
|
@@ -28,8 +28,22 @@ app.listen(8080, function() {
|
|
|
28
28
|
|
|
29
29
|
## Documentation
|
|
30
30
|
|
|
31
|
+
|
|
31
32
|
### Core concepts
|
|
32
|
-
[
|
|
33
|
+
[Core concepts documentation ➡️](docs/CoreConcepts.md)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Queries & Querying - Nodester Query Language (NQR)
|
|
37
|
+
One of the main power points of nodester is it's query language. It's an extension of a REST API syntaxis for a broader integration with a database SQL. Read more about it in the documentation:
|
|
38
|
+
|
|
39
|
+
[NQR documentaion ➡️](docs/Queries.md)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
### Database
|
|
43
|
+
Nodester is built upon a powerful [Sequelize](https://sequelize.org/).
|
|
44
|
+
Supported drivers:
|
|
45
|
+
- MySQL
|
|
46
|
+
- PostgreSQL
|
|
33
47
|
|
|
34
48
|
|
|
35
49
|
### Extending Application functionality
|
|
@@ -95,7 +109,7 @@ The Philosophy of `nodester` is to provide a developer with a tool that can buil
|
|
|
95
109
|
|
|
96
110
|
### Goal
|
|
97
111
|
|
|
98
|
-
The goal of `nodester` is to be a robust and flexible framework that makes
|
|
112
|
+
The goal of `nodester` is to be a robust and flexible framework that makes development in iteratations easy, and further scale possible.
|
|
99
113
|
|
|
100
114
|
|
|
101
115
|
## LICENSE
|
package/lib/application/index.js
CHANGED
|
@@ -7,19 +7,27 @@
|
|
|
7
7
|
|
|
8
8
|
const Emitter = require('events');
|
|
9
9
|
const DefaultRouter = require('../router');
|
|
10
|
+
|
|
10
11
|
// Server:
|
|
11
12
|
const http = require('http');
|
|
12
13
|
const request = require('../http/request');
|
|
13
14
|
const response = require('../http/response');
|
|
15
|
+
|
|
14
16
|
// Middlewares:
|
|
15
17
|
const nodesterQL = require('../middlewares/ql/sequelize');
|
|
18
|
+
const bodyParser = require('body-parser');
|
|
19
|
+
|
|
16
20
|
// Utils:
|
|
17
21
|
const {
|
|
18
22
|
typeOf,
|
|
19
23
|
isConstructor
|
|
20
24
|
} = require('../utils/types.util');
|
|
25
|
+
const {
|
|
26
|
+
associateModels
|
|
27
|
+
} = require('../database/utils');
|
|
28
|
+
|
|
21
29
|
const { merge } = require('../utils/objects.util');
|
|
22
|
-
const consl = require('
|
|
30
|
+
const consl = require('nodester/loggers/console');
|
|
23
31
|
const debug = require('debug')('nodester:application');
|
|
24
32
|
|
|
25
33
|
|
|
@@ -52,6 +60,13 @@ module.exports = class Application extends Emitter {
|
|
|
52
60
|
beforeStart: ()=>{}
|
|
53
61
|
};
|
|
54
62
|
|
|
63
|
+
// Default middlewares:
|
|
64
|
+
const _withoutMiddlewares = opts?.middlewares?.without ?? [];
|
|
65
|
+
|
|
66
|
+
if (_withoutMiddlewares.indexOf('body-parser') === -1) {
|
|
67
|
+
this.use(bodyParser.json());
|
|
68
|
+
}
|
|
69
|
+
|
|
55
70
|
// Indicatorors.
|
|
56
71
|
this.isListening = false;
|
|
57
72
|
}
|
|
@@ -104,7 +119,7 @@ module.exports = class Application extends Emitter {
|
|
|
104
119
|
*
|
|
105
120
|
* @public
|
|
106
121
|
*/
|
|
107
|
-
setDatabase(sequilizeConnection, crashOnError=true) {
|
|
122
|
+
async setDatabase(sequilizeConnection, crashOnError=true) {
|
|
108
123
|
try {
|
|
109
124
|
if (!sequilizeConnection) {
|
|
110
125
|
const err = new TypeError('Connection to database (Sequilize) can not be null or undefined.');
|
|
@@ -116,10 +131,14 @@ module.exports = class Application extends Emitter {
|
|
|
116
131
|
throw err;
|
|
117
132
|
}
|
|
118
133
|
|
|
119
|
-
|
|
134
|
+
// Test connection.
|
|
135
|
+
const result = await sequilizeConnection.authenticate();
|
|
136
|
+
// Associate models.
|
|
137
|
+
await associateModels(sequilizeConnection.models);
|
|
138
|
+
// Set database.
|
|
120
139
|
this._database = sequilizeConnection;
|
|
121
140
|
|
|
122
|
-
return result;
|
|
141
|
+
return Promise.resolve(result);
|
|
123
142
|
}
|
|
124
143
|
catch(error) {
|
|
125
144
|
if (crashOnError === true) {
|
|
@@ -128,6 +147,8 @@ module.exports = class Application extends Emitter {
|
|
|
128
147
|
else {
|
|
129
148
|
consl.error(error);
|
|
130
149
|
}
|
|
150
|
+
|
|
151
|
+
return Promise.reject(error);
|
|
131
152
|
}
|
|
132
153
|
}
|
|
133
154
|
|
|
@@ -188,14 +209,14 @@ module.exports = class Application extends Emitter {
|
|
|
188
209
|
|
|
189
210
|
|
|
190
211
|
/*
|
|
191
|
-
* Proxy to .
|
|
212
|
+
* Proxy to router.use()
|
|
192
213
|
*
|
|
193
|
-
* @param {Function}
|
|
214
|
+
* @param {Function|NodesterRouter} fnOrRouter
|
|
194
215
|
*
|
|
195
216
|
* @api public
|
|
196
217
|
*/
|
|
197
|
-
use(
|
|
198
|
-
return this._router.
|
|
218
|
+
use(fnOrRouter) {
|
|
219
|
+
return this._router.use(fnOrRouter);
|
|
199
220
|
}
|
|
200
221
|
|
|
201
222
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const Enum = require('nodester/enum');
|
|
2
|
+
|
|
3
|
+
const NODESTER_QUERY_ERROR = 'NodesterQueryError';
|
|
4
|
+
const UNAUTHORIZED_ERROR = 'Unauthorized';
|
|
5
|
+
const NOT_FOUND_ERROR = 'NotFound';
|
|
6
|
+
const VALIDATION_ERROR = 'ValidationError';
|
|
7
|
+
const CONFLICT_ERROR = 'ConflictError';
|
|
8
|
+
const SEQUELIZE_UNIQUE_CONSTRAINT_ERROR = 'SequelizeUniqueConstraintError';
|
|
9
|
+
const INTERNAL_VALIDATION_ERROR = 'InternalValidationError';
|
|
10
|
+
|
|
11
|
+
module.exports = new Enum({
|
|
12
|
+
NODESTER_QUERY_ERROR,
|
|
13
|
+
UNAUTHORIZED_ERROR,
|
|
14
|
+
NOT_FOUND_ERROR,
|
|
15
|
+
VALIDATION_ERROR,
|
|
16
|
+
CONFLICT_ERROR,
|
|
17
|
+
SEQUELIZE_UNIQUE_CONSTRAINT_ERROR,
|
|
18
|
+
INTERNAL_VALIDATION_ERROR,
|
|
19
|
+
});
|
|
@@ -14,8 +14,13 @@ module.exports = {
|
|
|
14
14
|
*/
|
|
15
15
|
async function _getOne(req, res) {
|
|
16
16
|
try {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const params = {
|
|
18
|
+
query: {
|
|
19
|
+
...req.query,
|
|
20
|
+
where: req.params
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const result = await this.facade.getOne(params);
|
|
19
24
|
|
|
20
25
|
if (this.afterGetOne) {
|
|
21
26
|
await this.afterGetOne(req, res, result);
|
|
@@ -26,7 +31,6 @@ async function _getOne(req, res) {
|
|
|
26
31
|
});
|
|
27
32
|
}
|
|
28
33
|
catch(error) {
|
|
29
|
-
console.error('getOne', error);
|
|
30
34
|
if (this.processError) {
|
|
31
35
|
return this.processError(error, req, res);
|
|
32
36
|
}
|
|
@@ -47,7 +51,10 @@ async function _getOne(req, res) {
|
|
|
47
51
|
*/
|
|
48
52
|
async function _getMany(req, res) {
|
|
49
53
|
try {
|
|
50
|
-
const
|
|
54
|
+
const params = {
|
|
55
|
+
query: req.query
|
|
56
|
+
}
|
|
57
|
+
const result = await this.facade.getMany(params);
|
|
51
58
|
|
|
52
59
|
if (this.afterGetMany) {
|
|
53
60
|
await this.afterGetMany(req, res, result);
|
|
@@ -78,8 +85,14 @@ async function _getMany(req, res) {
|
|
|
78
85
|
*/
|
|
79
86
|
async function _createOne(req, res) {
|
|
80
87
|
try {
|
|
81
|
-
|
|
82
|
-
|
|
88
|
+
const params = {
|
|
89
|
+
query: {
|
|
90
|
+
...req.query,
|
|
91
|
+
where: req.params
|
|
92
|
+
},
|
|
93
|
+
data: req.body,
|
|
94
|
+
}
|
|
95
|
+
const result = await this.facade.createOne(params);
|
|
83
96
|
|
|
84
97
|
if (this.afterCreateOne) {
|
|
85
98
|
await this.afterCreateOne(req, res, result);
|
|
@@ -110,8 +123,14 @@ async function _createOne(req, res) {
|
|
|
110
123
|
*/
|
|
111
124
|
async function _updateOne(req, res) {
|
|
112
125
|
try {
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
const params = {
|
|
127
|
+
query: {
|
|
128
|
+
...req.query,
|
|
129
|
+
where: req.params
|
|
130
|
+
},
|
|
131
|
+
data: req.body,
|
|
132
|
+
}
|
|
133
|
+
const result = await this.facade.updateOne(params);
|
|
115
134
|
|
|
116
135
|
if (this.afterUpdateOne) {
|
|
117
136
|
await this.afterUpdateOne(req, res, result);
|
|
@@ -142,8 +161,13 @@ async function _updateOne(req, res) {
|
|
|
142
161
|
*/
|
|
143
162
|
async function _deleteOne(req, res) {
|
|
144
163
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
164
|
+
const params = {
|
|
165
|
+
query: {
|
|
166
|
+
...req.query,
|
|
167
|
+
where: req.params
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const result = await this.facade.deleteOne(params);
|
|
147
171
|
|
|
148
172
|
if (this.afterDeleteOn) {
|
|
149
173
|
await this.afterDeleteOne(req, res, result);
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
const {
|
|
2
|
+
NODESTER_QUERY_ERROR,
|
|
3
|
+
UNAUTHORIZED_ERROR,
|
|
4
|
+
NOT_FOUND_ERROR,
|
|
5
|
+
VALIDATION_ERROR,
|
|
6
|
+
CONFLICT_ERROR,
|
|
7
|
+
SEQUELIZE_UNIQUE_CONSTRAINT_ERROR,
|
|
8
|
+
INTERNAL_VALIDATION_ERROR
|
|
9
|
+
} = require('nodester/constants/ErrorCodes');
|
|
10
|
+
|
|
1
11
|
const {
|
|
2
12
|
getOne,
|
|
3
13
|
getMany,
|
|
@@ -10,6 +20,8 @@ const {
|
|
|
10
20
|
module.exports = {
|
|
11
21
|
withDefaultCRUD: _withDefaultCRUD,
|
|
12
22
|
withDefaultErrorProcessing: _withDefaultErrorProcessing,
|
|
23
|
+
|
|
24
|
+
setFacade: _setFacade,
|
|
13
25
|
setMethod: _setMethod
|
|
14
26
|
}
|
|
15
27
|
|
|
@@ -42,18 +54,7 @@ function _withDefaultCRUD(controller, opts={}) {
|
|
|
42
54
|
throw err;
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
|
|
46
|
-
const err = new TypeError(`'opts.facade' argument is invalid.`);
|
|
47
|
-
throw err;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Set main facade:
|
|
51
|
-
if (facade.constructor.name === 'Function') {
|
|
52
|
-
controller.facade = new facade();
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
controller.facade = facade;
|
|
56
|
-
}
|
|
57
|
+
_setFacade(controller, facade);
|
|
57
58
|
|
|
58
59
|
// Set model info:
|
|
59
60
|
const model = facade.model;
|
|
@@ -134,6 +135,7 @@ function _withDefaultErrorProcessing(controller, opts={}) {
|
|
|
134
135
|
|
|
135
136
|
// Set processError:
|
|
136
137
|
controller.processError = function (error, req, res) {
|
|
138
|
+
|
|
137
139
|
// Default error message.
|
|
138
140
|
let errorMessage = error?.message ?? 'Internal server error';
|
|
139
141
|
// Default HTTP status code.
|
|
@@ -142,56 +144,102 @@ function _withDefaultErrorProcessing(controller, opts={}) {
|
|
|
142
144
|
let errorResponse = {};
|
|
143
145
|
|
|
144
146
|
switch(error.name) {
|
|
145
|
-
case
|
|
147
|
+
case UNAUTHORIZED_ERROR: {
|
|
146
148
|
statusCode = 401;
|
|
147
149
|
errorResponse.details = { message: 'Unauthorized' };
|
|
148
150
|
break;
|
|
149
151
|
}
|
|
150
|
-
case
|
|
152
|
+
case NOT_FOUND_ERROR: {
|
|
151
153
|
statusCode = 404;
|
|
152
154
|
errorResponse.details = { message: errorMessage };
|
|
153
155
|
break;
|
|
154
156
|
}
|
|
155
|
-
case
|
|
156
|
-
statusCode =
|
|
157
|
+
case NODESTER_QUERY_ERROR: {
|
|
158
|
+
statusCode = 422;
|
|
159
|
+
errorResponse.details = { message: errorMessage };
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case VALIDATION_ERROR: {
|
|
163
|
+
statusCode = 422;
|
|
157
164
|
errorResponse.details = error?.details;
|
|
158
165
|
break;
|
|
159
166
|
}
|
|
160
|
-
case
|
|
167
|
+
case CONFLICT_ERROR: {
|
|
161
168
|
statusCode = 409;
|
|
162
169
|
errorResponse.details = error?.details ?? error?.message;
|
|
163
170
|
break;
|
|
164
171
|
}
|
|
165
|
-
case
|
|
172
|
+
case SEQUELIZE_UNIQUE_CONSTRAINT_ERROR: {
|
|
166
173
|
statusCode = 409;
|
|
167
174
|
errorResponse.details = error?.errors;
|
|
168
175
|
break;
|
|
169
176
|
}
|
|
170
|
-
case
|
|
177
|
+
case INTERNAL_VALIDATION_ERROR: {
|
|
171
178
|
statusCode = 500;
|
|
172
|
-
errorResponse.details = { message:
|
|
179
|
+
errorResponse.details = { message: errorMessage };
|
|
173
180
|
break;
|
|
174
181
|
}
|
|
175
182
|
default: {
|
|
176
|
-
errorResponse.details = { message:errorMessage };
|
|
183
|
+
errorResponse.details = { message: errorMessage };
|
|
177
184
|
break;
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
|
|
181
|
-
// Send error response with provided status code
|
|
182
|
-
|
|
188
|
+
// Send error response with provided status code:
|
|
189
|
+
const data = {
|
|
183
190
|
error: {
|
|
184
191
|
...errorResponse,
|
|
185
192
|
code: statusCode
|
|
186
193
|
},
|
|
187
194
|
status: statusCode
|
|
188
|
-
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!!this.respondNotOk) {
|
|
198
|
+
return this.respondNotOk(res, data);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Barebones response:
|
|
202
|
+
res.status(statusCode);
|
|
203
|
+
res.json(data);
|
|
189
204
|
}
|
|
190
205
|
|
|
191
206
|
return controller;
|
|
192
207
|
}
|
|
193
208
|
|
|
194
209
|
|
|
210
|
+
/**
|
|
211
|
+
* Sets one of or all of CRUD methods to Controller.
|
|
212
|
+
*
|
|
213
|
+
* @param {Function|Object} controller
|
|
214
|
+
* @param {Function|Object} facade
|
|
215
|
+
* @param {String} facadeName
|
|
216
|
+
*
|
|
217
|
+
* @return {Function|Object} controller
|
|
218
|
+
*
|
|
219
|
+
* @api public
|
|
220
|
+
* @alias setFacade
|
|
221
|
+
*/
|
|
222
|
+
function _setFacade(controller, facade, facadeName=null) {
|
|
223
|
+
if (!controller) {
|
|
224
|
+
const err = new TypeError(`'controller' argument is not provided.`);
|
|
225
|
+
throw err;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!facade) {
|
|
229
|
+
const err = new TypeError(`'facade' argument is invalid.`);
|
|
230
|
+
throw err;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Set main facade:
|
|
234
|
+
if (facade.constructor.name === 'Function') {
|
|
235
|
+
controller[facadeName ?? 'facade'] = new facade();
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
controller[facadeName ?? 'facade'] = facade;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
195
243
|
/**
|
|
196
244
|
* Sets one of CRUD methods to Controller.
|
|
197
245
|
*
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// ORM.
|
|
2
|
+
const Sequelize = require('sequelize');
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
buildConnection: _buildConnection
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function _buildConnection(opts={}) {
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const dbName = opts.name;
|
|
13
|
+
const username = opts.username;
|
|
14
|
+
const password = opts.password;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
const connection = new Sequelize(
|
|
18
|
+
dbName,
|
|
19
|
+
username,
|
|
20
|
+
password,
|
|
21
|
+
{
|
|
22
|
+
host: opts.host,
|
|
23
|
+
port: opts.port,
|
|
24
|
+
dialect: opts.dialect,
|
|
25
|
+
pool: opts.pool,
|
|
26
|
+
charset: opts.charset,
|
|
27
|
+
collate: opts.collate,
|
|
28
|
+
timestamps: opts.timestamps,
|
|
29
|
+
logging: opts.logging
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return connection;
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const { associateModels } = require('./utils');
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
migrate: _migrate
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async function _migrate(databaseConnection, force=false) {
|
|
9
|
+
try {
|
|
10
|
+
// Validation of 'force' parameter.
|
|
11
|
+
if (typeof force !== 'boolean') {
|
|
12
|
+
const err = new Error('Wrong "force" parameter; must be boolean.');
|
|
13
|
+
throw err;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Test connection.
|
|
17
|
+
await databaseConnection.authenticate();
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
const models = databaseConnection.models;
|
|
21
|
+
const modelNames = Object.keys(models);
|
|
22
|
+
console.info('Models to sync:', modelNames);
|
|
23
|
+
console.info('Forcefully?', force);
|
|
24
|
+
console.info('Syncing...\n');
|
|
25
|
+
await associateModels(models);
|
|
26
|
+
await databaseConnection.sync({ force });
|
|
27
|
+
console.info('Successful migration!');
|
|
28
|
+
|
|
29
|
+
const output = {
|
|
30
|
+
synced: true,
|
|
31
|
+
modelNames: modelNames,
|
|
32
|
+
models: models
|
|
33
|
+
}
|
|
34
|
+
return Promise.resolve(output);
|
|
35
|
+
}
|
|
36
|
+
catch(error) {
|
|
37
|
+
console.error('Migration failed!');
|
|
38
|
+
console.error(error);
|
|
39
|
+
return Promise.reject(error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = {
|
|
3
|
+
associateModels: _associateModels
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async function _associateModels(models) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
try {
|
|
9
|
+
Object.keys(models).map(modelName => (
|
|
10
|
+
models[modelName].associate(models)
|
|
11
|
+
));
|
|
12
|
+
|
|
13
|
+
return resolve(models);
|
|
14
|
+
}
|
|
15
|
+
catch(error) {
|
|
16
|
+
reject(error);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const Params = require('nodester/params');
|
|
2
|
+
|
|
3
|
+
const log = require('nodester/loggers/dev');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
getOne: _getOne,
|
|
8
|
+
getMany: _getMany,
|
|
9
|
+
createOne: _createOne,
|
|
10
|
+
updateOne: _updateOne,
|
|
11
|
+
deleteOne: _deleteOne
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
*
|
|
17
|
+
* @param {Object} params
|
|
18
|
+
*
|
|
19
|
+
* @alias getOne
|
|
20
|
+
* @api public
|
|
21
|
+
*/
|
|
22
|
+
async function _getOne(params) {
|
|
23
|
+
try {
|
|
24
|
+
const {
|
|
25
|
+
query
|
|
26
|
+
} = Params(params, {
|
|
27
|
+
query: {}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const instance = await this.model.findOne(query);
|
|
31
|
+
|
|
32
|
+
const result = {
|
|
33
|
+
[this.modelName.singular]: instance,
|
|
34
|
+
count: 0 + (instance !== null)
|
|
35
|
+
}
|
|
36
|
+
return Promise.resolve(result);
|
|
37
|
+
}
|
|
38
|
+
catch(error) {
|
|
39
|
+
log.error(`${ [this.modelName.singular] }Facade.getOne error:`, error);
|
|
40
|
+
return Promise.reject(error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
*
|
|
47
|
+
* @param {Object} params
|
|
48
|
+
*
|
|
49
|
+
* @alias getMany
|
|
50
|
+
* @api public
|
|
51
|
+
*/
|
|
52
|
+
async function _getMany(params) {
|
|
53
|
+
try {
|
|
54
|
+
const {
|
|
55
|
+
query
|
|
56
|
+
} = Params(params, {
|
|
57
|
+
query: {}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const instances = await this.model.findAll(query);
|
|
61
|
+
|
|
62
|
+
const result = {
|
|
63
|
+
[this.modelName.plural]: instances,
|
|
64
|
+
count: instances.length
|
|
65
|
+
}
|
|
66
|
+
return Promise.resolve(result);
|
|
67
|
+
}
|
|
68
|
+
catch(error) {
|
|
69
|
+
log.error(`${ [this.modelName.singular] }Facade.getMany error:`, error);
|
|
70
|
+
return Promise.reject(error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
*
|
|
77
|
+
* @param {Object} params
|
|
78
|
+
*
|
|
79
|
+
* @alias createOne
|
|
80
|
+
* @api public
|
|
81
|
+
*/
|
|
82
|
+
async function _createOne(params) {
|
|
83
|
+
try {
|
|
84
|
+
const {
|
|
85
|
+
data,
|
|
86
|
+
includes,
|
|
87
|
+
} = Params(params, {
|
|
88
|
+
data: null,
|
|
89
|
+
includes: null,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const instance = await this.model.create({ ...data }, {
|
|
93
|
+
include: this.model.getIncludesList(data)
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// If includes are set, "find" this record with includes:
|
|
97
|
+
if (!!includes && includes?.length > 0) {
|
|
98
|
+
await instance.reload({ include: includes });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const result = {
|
|
102
|
+
[this.modelName.singular]: instance,
|
|
103
|
+
count: 0 + (instance !== null)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Call after create.
|
|
107
|
+
await this.afterCreateOne(instance, params, result);
|
|
108
|
+
|
|
109
|
+
return Promise.resolve(result);
|
|
110
|
+
}
|
|
111
|
+
catch(error) {
|
|
112
|
+
log.error(`${ [this.modelName.singular] }Facade.createOne error:`, error);
|
|
113
|
+
return Promise.reject(error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
*
|
|
120
|
+
* @param {Object} params
|
|
121
|
+
*
|
|
122
|
+
* @alias updateOne
|
|
123
|
+
* @api public
|
|
124
|
+
*/
|
|
125
|
+
async function _updateOne(params) {
|
|
126
|
+
try {
|
|
127
|
+
const {
|
|
128
|
+
query,
|
|
129
|
+
data
|
|
130
|
+
} = Params(params, {
|
|
131
|
+
query: {},
|
|
132
|
+
data: null
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const updateResult = await this.model.updateOne(query.where, data);;
|
|
136
|
+
|
|
137
|
+
const [ isNewRecord, instance ] = updateResult;
|
|
138
|
+
|
|
139
|
+
const result = {
|
|
140
|
+
success: isNewRecord === false,
|
|
141
|
+
[this.modelName.singular]: instance,
|
|
142
|
+
count: 0 + (instance !== null)
|
|
143
|
+
}
|
|
144
|
+
return Promise.resolve(result);
|
|
145
|
+
}
|
|
146
|
+
catch(error) {
|
|
147
|
+
log.error(`${ [this.modelName.singular] }Facade.updateOne error:`, error);
|
|
148
|
+
return Promise.reject(error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
*
|
|
155
|
+
* @param {Object} params
|
|
156
|
+
*
|
|
157
|
+
* @alias deleteOne
|
|
158
|
+
* @api public
|
|
159
|
+
*/
|
|
160
|
+
async function _deleteOne(params) {
|
|
161
|
+
try {
|
|
162
|
+
const {
|
|
163
|
+
query
|
|
164
|
+
} = Params(params, {
|
|
165
|
+
query: null
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const count = await this.model.deleteOne(query);
|
|
169
|
+
|
|
170
|
+
const result = {
|
|
171
|
+
success: count > 0,
|
|
172
|
+
count: count
|
|
173
|
+
};
|
|
174
|
+
return Promise.resolve(result);
|
|
175
|
+
}
|
|
176
|
+
catch(error) {
|
|
177
|
+
log.error(`${ [this.modelName.singular] }Facade.deleteOne error:`, error);
|
|
178
|
+
return Promise.reject(error);
|
|
179
|
+
}
|
|
180
|
+
}
|