nodester 0.3.4 → 0.4.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/lib/body/extract.js +18 -3
- package/lib/facades/methods/index.js +5 -6
- package/lib/middlewares/ql/sequelize/interpreter/ModelsTree.js +3 -2
- package/lib/models/mixins.js +87 -50
- package/lib/query/{traverse.js → traverse/index.js} +61 -55
- package/lib/query/traverse/parsers.js +41 -0
- package/lib/query/traverse/utils.js +40 -0
- package/lib/utils/modelAssociations.util.js +18 -4
- package/lib/utils/sanitizations.util.js +53 -25
- package/package.json +2 -2
package/lib/body/extract.js
CHANGED
|
@@ -65,17 +65,32 @@ function extract(body, filter=null, model) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
if (isInclude) {
|
|
68
|
-
const
|
|
68
|
+
const availableIncludeFilters = Object.keys(filter.includes);
|
|
69
69
|
|
|
70
|
-
if (
|
|
70
|
+
if (availableIncludeFilters.indexOf(key) === -1) {
|
|
71
71
|
const err = new Error(`Include '${ key }' is not available.`);
|
|
72
72
|
err.status = httpCodes.NOT_ACCEPTABLE;
|
|
73
73
|
throw err;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
const thisIncludeFilter = filter.includes[key];
|
|
77
|
+
|
|
76
78
|
const association = model.associations[key];
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
// Mutliple includes:
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
filteredBody[key] = [];
|
|
83
|
+
|
|
84
|
+
for (let thisIncludeBody of value) {
|
|
85
|
+
filteredBody[key].push(
|
|
86
|
+
extract(thisIncludeBody, thisIncludeFilter, association.target)
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const thisIncludeBody = value;
|
|
92
|
+
filteredBody[key] = extract(thisIncludeBody, thisIncludeFilter, association.target);
|
|
93
|
+
}
|
|
79
94
|
|
|
80
95
|
continue;
|
|
81
96
|
}
|
|
@@ -106,8 +106,8 @@ async function _createOne(params) {
|
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
const instance = await this.model.create({ ...data }, {
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
include: this.model.getIncludesTree(data)
|
|
110
|
+
});
|
|
111
111
|
|
|
112
112
|
const result = {
|
|
113
113
|
[this.outputName.singular]: instance,
|
|
@@ -145,12 +145,11 @@ async function _updateOne(params) {
|
|
|
145
145
|
data: null
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
const instance = await this.model.updateOne(query.where, data, {
|
|
149
|
+
include: this.model.getIncludesTree(data)
|
|
150
|
+
});
|
|
151
151
|
|
|
152
152
|
const result = {
|
|
153
|
-
success: isNewRecord === false,
|
|
154
153
|
[this.outputName.singular]: instance,
|
|
155
154
|
count: 0 + (instance !== null)
|
|
156
155
|
}
|
|
@@ -29,8 +29,9 @@ class ModelsTreeNode {
|
|
|
29
29
|
this.limit = -1; // No limit
|
|
30
30
|
|
|
31
31
|
this._includes = opts.includes ?? [];
|
|
32
|
-
|
|
33
|
-
this.
|
|
32
|
+
|
|
33
|
+
this.order = opts.order ?? undefined;
|
|
34
|
+
this.order_by = opts.order_by ?? undefined;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// Getters:
|
package/lib/models/mixins.js
CHANGED
|
@@ -86,7 +86,7 @@ async function _createWithIncludes(
|
|
|
86
86
|
associatedModel,
|
|
87
87
|
foreignKey,
|
|
88
88
|
associationType
|
|
89
|
-
} = getModelAssociationProps(associationDefinition
|
|
89
|
+
} = getModelAssociationProps(associationDefinition);
|
|
90
90
|
|
|
91
91
|
// If association type is HasMany or HasOne (We don't work with any other):
|
|
92
92
|
if (associationType === 'HasMany' || associationType === 'HasOne') {
|
|
@@ -189,71 +189,108 @@ function _findMany(opts={}) {
|
|
|
189
189
|
async function _updateOne(
|
|
190
190
|
where,
|
|
191
191
|
data,
|
|
192
|
-
|
|
192
|
+
opts={}
|
|
193
193
|
) {
|
|
194
194
|
try {
|
|
195
|
-
const
|
|
195
|
+
const include = opts.include ?? [];
|
|
196
|
+
let instance = await this.findOne({ where, include });
|
|
197
|
+
let isNewRecord = false;
|
|
196
198
|
|
|
197
199
|
if (!instance) {
|
|
198
|
-
const err = new Error(`Model not found`);
|
|
199
|
-
err.name = 'NotFound';
|
|
200
|
-
throw err;
|
|
201
|
-
}
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
if (opts.findOrCreate === true) {
|
|
202
|
+
instance = await this.create(data);
|
|
203
|
+
isNewRecord = true;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
const err = new Error(`Model not found`);
|
|
207
|
+
err.name = 'NotFound';
|
|
208
|
+
throw err;
|
|
209
|
+
}
|
|
210
210
|
|
|
211
|
-
|
|
212
|
-
if (modelHasAssociations(this)) {
|
|
211
|
+
}
|
|
213
212
|
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
// Will contain data from parent instance and associations.
|
|
214
|
+
const fullInstanceData = instance.toJSON();
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
associatedModel,
|
|
223
|
-
foreignKey,
|
|
224
|
-
associationType
|
|
225
|
-
} = getModelAssociationProps(associationDefinition, data);
|
|
216
|
+
const parentData = {
|
|
217
|
+
...data
|
|
218
|
+
}
|
|
219
|
+
for (let includeConfig of include) {
|
|
220
|
+
const { association } = includeConfig;
|
|
226
221
|
|
|
227
|
-
|
|
228
|
-
|
|
222
|
+
if (parentData[association] === undefined) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
229
225
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
226
|
+
delete parentData[association];
|
|
227
|
+
|
|
228
|
+
const associationDefinition = this.associations[association];
|
|
229
|
+
const includeData = data[association];
|
|
230
|
+
|
|
231
|
+
const {
|
|
232
|
+
associatedModel,
|
|
233
|
+
associationType,
|
|
234
|
+
|
|
235
|
+
foreignKey,
|
|
236
|
+
sourceKey
|
|
237
|
+
} = getModelAssociationProps(associationDefinition);
|
|
238
|
+
|
|
239
|
+
const associationUpdateOpts = {
|
|
240
|
+
findOrCreate: true,
|
|
241
|
+
include: associatedModel.getIncludesTree(includeData)
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const pkField = associatedModel.primaryKeyField;
|
|
245
|
+
|
|
246
|
+
// If association type is HasMany or HasOne (We don't work with any other):
|
|
247
|
+
switch(associationType) {
|
|
248
|
+
case 'HasMany': {
|
|
249
|
+
const promises = includeData.map(singleData => {
|
|
250
|
+
// Note: for now we are only able to work with a model with single PrimaryKey:
|
|
251
|
+
const where = {
|
|
252
|
+
[pkField]: singleData[pkField]
|
|
253
|
+
}
|
|
254
|
+
return associatedModel.updateOne(
|
|
255
|
+
where,
|
|
256
|
+
singleData,
|
|
257
|
+
associationUpdateOpts
|
|
258
|
+
)
|
|
259
|
+
});
|
|
260
|
+
fullInstanceData[association] = await Promise.all(promises);
|
|
261
|
+
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
237
264
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
265
|
+
case 'HasOne': {
|
|
266
|
+
// Note: for now we are only able to work with a model with single PrimaryKey:
|
|
267
|
+
const where = {
|
|
268
|
+
[pkField]: includeData[pkField]
|
|
242
269
|
}
|
|
270
|
+
fullInstanceData[association] = await associatedModel.updateOne(
|
|
271
|
+
where,
|
|
272
|
+
includeData,
|
|
273
|
+
associationUpdateOpts
|
|
274
|
+
);
|
|
243
275
|
|
|
244
|
-
|
|
276
|
+
continue;
|
|
245
277
|
}
|
|
246
|
-
}
|
|
247
278
|
|
|
279
|
+
default:
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
248
282
|
}
|
|
249
|
-
|
|
250
|
-
//
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
283
|
+
|
|
284
|
+
// Update parent model instance:
|
|
285
|
+
if (isNewRecord === false) {
|
|
286
|
+
instance.set(parentData);
|
|
287
|
+
const saveResult = await instance.save();
|
|
254
288
|
}
|
|
255
289
|
|
|
256
|
-
return Promise.resolve(
|
|
290
|
+
return Promise.resolve({
|
|
291
|
+
_is_new_record: isNewRecord,
|
|
292
|
+
...fullInstanceData
|
|
293
|
+
});
|
|
257
294
|
}
|
|
258
295
|
catch(error) {
|
|
259
296
|
return Promise.reject(error);
|
|
@@ -263,13 +300,13 @@ async function _updateOne(
|
|
|
263
300
|
async function _updateById(
|
|
264
301
|
id=null,
|
|
265
302
|
data={},
|
|
266
|
-
|
|
303
|
+
opts={}
|
|
267
304
|
) {
|
|
268
305
|
const where = { id };
|
|
269
306
|
return this.updateOne(
|
|
270
307
|
where,
|
|
271
308
|
data,
|
|
272
|
-
|
|
309
|
+
opts
|
|
273
310
|
);
|
|
274
311
|
}
|
|
275
312
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const BOUNDS = require('
|
|
8
|
+
const BOUNDS = require('../../constants/Bounds');
|
|
9
9
|
|
|
10
10
|
const { Op } = require('sequelize');
|
|
11
11
|
const { NodesterQueryError } = require('nodester/errors');
|
|
@@ -13,6 +13,20 @@ const httpCodes = require('nodester/http/codes');
|
|
|
13
13
|
|
|
14
14
|
const { ensure } = require('nodester/validators/arguments');
|
|
15
15
|
|
|
16
|
+
const {
|
|
17
|
+
parseValue,
|
|
18
|
+
parseWhereEntry,
|
|
19
|
+
} = require('./parsers');
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
disassembleQueryNode,
|
|
23
|
+
addAssociationQuery,
|
|
24
|
+
} = require('./utils');
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
getModelAssociationProps
|
|
28
|
+
} = require('../../utils/modelAssociations.util');
|
|
29
|
+
|
|
16
30
|
|
|
17
31
|
module.exports = traverse;
|
|
18
32
|
|
|
@@ -58,7 +72,7 @@ function traverse(queryNode, filter=null, model=null) {
|
|
|
58
72
|
where,
|
|
59
73
|
|
|
60
74
|
includes,
|
|
61
|
-
} =
|
|
75
|
+
} = disassembleQueryNode(queryNode);
|
|
62
76
|
|
|
63
77
|
|
|
64
78
|
// Attribute:
|
|
@@ -200,10 +214,16 @@ function traverse(queryNode, filter=null, model=null) {
|
|
|
200
214
|
continue;
|
|
201
215
|
}
|
|
202
216
|
case 'order':
|
|
217
|
+
if (value === undefined)
|
|
218
|
+
continue;
|
|
219
|
+
|
|
203
220
|
order.order = value;
|
|
204
221
|
continue;
|
|
205
222
|
|
|
206
223
|
case 'order_by':
|
|
224
|
+
if (value === undefined)
|
|
225
|
+
continue;
|
|
226
|
+
|
|
207
227
|
order.by = value;
|
|
208
228
|
continue;
|
|
209
229
|
|
|
@@ -303,13 +323,13 @@ function traverse(queryNode, filter=null, model=null) {
|
|
|
303
323
|
// Set aatributes from Query:
|
|
304
324
|
const whereEntries = Object.entries(where);
|
|
305
325
|
for (let [ attribute, value ] of whereEntries) {
|
|
306
|
-
|
|
326
|
+
parseWhereEntry(attribute, value, newQuery.where);
|
|
307
327
|
}
|
|
308
328
|
|
|
309
329
|
// Static attributes override previously set attributes:
|
|
310
330
|
const staticAttributesEntries = Object.entries(filter.statics.attributes);
|
|
311
331
|
for (let [ attribute, staticValue ] of staticAttributesEntries) {
|
|
312
|
-
newQuery.where[attribute] =
|
|
332
|
+
newQuery.where[attribute] = parseValue(staticValue, attribute);
|
|
313
333
|
}
|
|
314
334
|
|
|
315
335
|
// If "where" was not set in any way,
|
|
@@ -319,6 +339,12 @@ function traverse(queryNode, filter=null, model=null) {
|
|
|
319
339
|
}
|
|
320
340
|
// Where\
|
|
321
341
|
|
|
342
|
+
// Combine included orders into one at the top level:
|
|
343
|
+
// - Why?
|
|
344
|
+
// - Sequelize ingores included orders for association types like:
|
|
345
|
+
// • HasMany
|
|
346
|
+
_traverseIncludedOrders(newQuery, _model);
|
|
347
|
+
|
|
322
348
|
return newQuery;
|
|
323
349
|
}
|
|
324
350
|
|
|
@@ -355,66 +381,46 @@ function _traverseIncludes(includes, rootModel, filter, resultQuery) {
|
|
|
355
381
|
// Build query for this include.
|
|
356
382
|
const associationQuery = traverse(include, filter.includes[includeName], includeModel);
|
|
357
383
|
|
|
358
|
-
|
|
384
|
+
addAssociationQuery(associationQuery, includeName, resultQuery);
|
|
359
385
|
}
|
|
360
386
|
}
|
|
361
387
|
|
|
388
|
+
function _traverseIncludedOrders(resultQuery, rootModel) {
|
|
389
|
+
for (let i=0; i < resultQuery.include.length; i++) {
|
|
390
|
+
const include = resultQuery.include[i];
|
|
362
391
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
association: includeName,
|
|
368
|
-
...associationQuery
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
function _parseWhereEntry(attribute, value, whereHolder) {
|
|
374
|
-
let _value = value;
|
|
375
|
-
|
|
376
|
-
// If attribute is Op (not, like, or, etc.):
|
|
377
|
-
if (attribute in Op) {
|
|
378
|
-
// Parse value:
|
|
379
|
-
_value = _parseValue(_value, attribute);
|
|
380
|
-
|
|
381
|
-
const op = Op[attribute];
|
|
382
|
-
whereHolder[op] = _value;
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
whereHolder[attribute] = _parseValue(_value, attribute);
|
|
387
|
-
}
|
|
392
|
+
console.log({ irder: include?.order });
|
|
393
|
+
if (!include?.order) {
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
388
396
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
attributes,
|
|
393
|
-
functions,
|
|
394
|
-
where,
|
|
395
|
-
includes,
|
|
396
|
-
...clauses
|
|
397
|
-
} = queryNode;
|
|
398
|
-
|
|
399
|
-
return {
|
|
400
|
-
attributes: attributes ?? [],
|
|
401
|
-
clauses: clauses ?? [],
|
|
402
|
-
functions: functions ?? [],
|
|
403
|
-
where: where ?? {},
|
|
404
|
-
includes: includes ?? [],
|
|
405
|
-
};
|
|
406
|
-
}
|
|
397
|
+
if (!resultQuery.order) {
|
|
398
|
+
resultQuery.order = [];
|
|
399
|
+
}
|
|
407
400
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
401
|
+
const { association } = include;
|
|
402
|
+
const {
|
|
403
|
+
associatedModel,
|
|
404
|
+
associationType
|
|
405
|
+
} = getModelAssociationProps(rootModel.associations[association]);
|
|
406
|
+
|
|
407
|
+
switch(associationType) {
|
|
408
|
+
case 'HasMany': {
|
|
409
|
+
resultQuery.order.push([
|
|
410
|
+
{ association },
|
|
411
|
+
...include.order[0]
|
|
412
|
+
]);
|
|
413
|
+
delete resultQuery.include[i].order;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
default:
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
412
419
|
|
|
413
|
-
|
|
414
|
-
return { [op]: rawValue };
|
|
420
|
+
_traverseIncludedOrders(resultQuery.include[i], associatedModel);
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
return
|
|
423
|
+
return resultQuery;
|
|
418
424
|
}
|
|
419
425
|
|
|
420
426
|
function _setValueWithBounds(value, type, bounds) {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodester
|
|
3
|
+
* MIT Licensed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
parseValue: _parseValue,
|
|
11
|
+
parseWhereEntry: _parseWhereEntry,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function _parseValue(value, attribute) {
|
|
15
|
+
// If value is Object:
|
|
16
|
+
if (typeof value === 'object' && Array.isArray(value) === false) {
|
|
17
|
+
const [ opKey, rawValue ] = (Object.entries(value))[0];
|
|
18
|
+
|
|
19
|
+
const op = Op[opKey];
|
|
20
|
+
return { [op]: rawValue };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function _parseWhereEntry(attribute, value, whereHolder) {
|
|
27
|
+
let _value = value;
|
|
28
|
+
|
|
29
|
+
// If attribute is Op (not, like, or, etc.):
|
|
30
|
+
if (attribute in Op) {
|
|
31
|
+
// Parse value:
|
|
32
|
+
_value = _parseValue(_value, attribute);
|
|
33
|
+
|
|
34
|
+
const op = Op[attribute];
|
|
35
|
+
whereHolder[op] = _value;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
whereHolder[attribute] = _parseValue(_value, attribute);
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodester
|
|
3
|
+
* MIT Licensed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
disassembleQueryNode: _disassembleQueryNode,
|
|
11
|
+
addAssociationQuery: _addAssociationQuery,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function _disassembleQueryNode(queryNode) {
|
|
15
|
+
// Disassemble current query node:
|
|
16
|
+
const {
|
|
17
|
+
attributes,
|
|
18
|
+
functions,
|
|
19
|
+
where,
|
|
20
|
+
includes,
|
|
21
|
+
...clauses
|
|
22
|
+
} = queryNode;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
attributes: attributes ?? [],
|
|
26
|
+
clauses: clauses ?? [],
|
|
27
|
+
functions: functions ?? [],
|
|
28
|
+
where: where ?? {},
|
|
29
|
+
includes: includes ?? [],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function _addAssociationQuery(associationQuery, includeName, resultQuery) {
|
|
34
|
+
|
|
35
|
+
// Add all association info into query.
|
|
36
|
+
resultQuery.include.push({
|
|
37
|
+
association: includeName,
|
|
38
|
+
...associationQuery
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nodester
|
|
3
|
+
* MIT Licensed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
1
8
|
|
|
2
9
|
module.exports = {
|
|
3
10
|
modelHasAssociations: _modelHasAssociations,
|
|
@@ -10,12 +17,16 @@ function _modelHasAssociations(modelDifinition) {
|
|
|
10
17
|
}
|
|
11
18
|
|
|
12
19
|
function _getModelAssociationProps(
|
|
13
|
-
associationDefinition
|
|
14
|
-
requestData
|
|
20
|
+
associationDefinition
|
|
15
21
|
) {
|
|
16
22
|
// Extract neccessary variables and functions:
|
|
17
23
|
const associatedModel = associationDefinition.target;
|
|
18
|
-
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
foreignKey,
|
|
27
|
+
sourceKey
|
|
28
|
+
} = associationDefinition;
|
|
29
|
+
|
|
19
30
|
const {
|
|
20
31
|
associationType,
|
|
21
32
|
accessors,
|
|
@@ -23,8 +34,11 @@ function _getModelAssociationProps(
|
|
|
23
34
|
|
|
24
35
|
return {
|
|
25
36
|
associatedModel,
|
|
26
|
-
foreignKey,
|
|
27
37
|
associationType,
|
|
38
|
+
|
|
39
|
+
foreignKey,
|
|
40
|
+
sourceKey,
|
|
41
|
+
|
|
28
42
|
accessors,
|
|
29
43
|
};
|
|
30
44
|
}
|
|
@@ -7,8 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
|
+
UUID: _UUID,
|
|
11
|
+
|
|
10
12
|
CHAR: _STRING,
|
|
11
13
|
VARCHAR: _STRING,
|
|
14
|
+
STRING: _STRING,
|
|
15
|
+
TEXT: _TEXT,
|
|
16
|
+
|
|
17
|
+
ENUM: _ENUM,
|
|
12
18
|
|
|
13
19
|
NUMBER: _NUMBER,
|
|
14
20
|
|
|
@@ -17,8 +23,6 @@ module.exports = {
|
|
|
17
23
|
|
|
18
24
|
BOOLEAN: _BOOLEAN,
|
|
19
25
|
|
|
20
|
-
STRING: _STRING,
|
|
21
|
-
TEXT: _TEXT,
|
|
22
26
|
|
|
23
27
|
DATE: _DATE,
|
|
24
28
|
DATETIME: _DATE,
|
|
@@ -26,6 +30,52 @@ module.exports = {
|
|
|
26
30
|
JSON: _JSON
|
|
27
31
|
}
|
|
28
32
|
|
|
33
|
+
function _UUID(value=undefined, options={ fallback:undefined }) {
|
|
34
|
+
try {
|
|
35
|
+
if (typeof value !== 'string')
|
|
36
|
+
throw new Error(`Not a valid UUID`);
|
|
37
|
+
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
catch(ex) {
|
|
41
|
+
return options?.fallback;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
function _STRING(value=undefined, options={ fallback:undefined }) {
|
|
47
|
+
try {
|
|
48
|
+
if (typeof value !== 'string')
|
|
49
|
+
throw new Error(`Not a String`);
|
|
50
|
+
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
catch(ex) {
|
|
54
|
+
return options?.fallback;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function _TEXT(value=undefined, options={ fallback:undefined }) {
|
|
59
|
+
try {
|
|
60
|
+
if (typeof value !== 'string')
|
|
61
|
+
throw new Error(`Not a String`);
|
|
62
|
+
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
catch(ex) {
|
|
66
|
+
return options?.fallback;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
function _ENUM(value=undefined, options={ fallback:undefined }) {
|
|
72
|
+
if (value === undefined)
|
|
73
|
+
return options.fallback;
|
|
74
|
+
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
29
79
|
function _isNumber(value) {
|
|
30
80
|
return !isNaN(`${value}`);
|
|
31
81
|
}
|
|
@@ -70,29 +120,6 @@ function _BOOLEAN(value=undefined, options={ fallback:undefined }) {
|
|
|
70
120
|
}
|
|
71
121
|
}
|
|
72
122
|
|
|
73
|
-
function _STRING(value=undefined, options={ fallback:undefined }) {
|
|
74
|
-
try {
|
|
75
|
-
if (typeof value !== 'string')
|
|
76
|
-
throw new Error(`Not a String`);
|
|
77
|
-
|
|
78
|
-
return value;
|
|
79
|
-
}
|
|
80
|
-
catch(ex) {
|
|
81
|
-
return options?.fallback;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function _TEXT(value=undefined, options={ fallback:undefined }) {
|
|
86
|
-
try {
|
|
87
|
-
if (typeof value !== 'string')
|
|
88
|
-
throw new Error(`Not a String`);
|
|
89
|
-
|
|
90
|
-
return value;
|
|
91
|
-
}
|
|
92
|
-
catch(ex) {
|
|
93
|
-
return options?.fallback;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
123
|
|
|
97
124
|
function _DATE(value=undefined, options={ fallback:undefined }) {
|
|
98
125
|
try {
|
|
@@ -123,6 +150,7 @@ function _DATE(value=undefined, options={ fallback:undefined }) {
|
|
|
123
150
|
}
|
|
124
151
|
}
|
|
125
152
|
|
|
153
|
+
|
|
126
154
|
function _JSON(value=undefined, options={ fallback:undefined }) {
|
|
127
155
|
try {
|
|
128
156
|
if (typeof value === 'string')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodester",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A versatile REST framework for Node.js",
|
|
5
5
|
"directories": {
|
|
6
6
|
"docs": "docs",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"./params": "./lib/structures/Params.js",
|
|
58
58
|
|
|
59
59
|
"./ql/sequelize": "./lib/middlewares/ql/sequelize/index.js",
|
|
60
|
-
"./query/traverse": "./lib/query/traverse.js",
|
|
60
|
+
"./query/traverse": "./lib/query/traverse/index.js",
|
|
61
61
|
|
|
62
62
|
"./route": "./lib/router/route.js",
|
|
63
63
|
"./router": "./lib/router/index.js",
|