axe-api 0.19.1 → 0.20.0-rc10

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.
Files changed (106) hide show
  1. package/build/index.d.ts +8 -0
  2. package/build/index.js +32 -0
  3. package/build/src/Builders/ModelTreeBuilder.d.ts +9 -0
  4. package/build/src/Builders/ModelTreeBuilder.js +64 -0
  5. package/build/src/Builders/RouterBuilder.d.ts +15 -0
  6. package/build/src/Builders/RouterBuilder.js +219 -0
  7. package/build/src/Builders/index.d.ts +3 -0
  8. package/build/src/Builders/index.js +10 -0
  9. package/build/src/Enums.d.ts +77 -0
  10. package/build/src/Enums.js +90 -0
  11. package/build/src/Exceptions/ApiError.d.ts +8 -0
  12. package/build/src/Exceptions/ApiError.js +12 -0
  13. package/build/src/Handlers/AllHandler.d.ts +4 -0
  14. package/build/src/Handlers/AllHandler.js +44 -0
  15. package/build/src/Handlers/DestroyHandler.d.ts +4 -0
  16. package/build/src/Handlers/DestroyHandler.js +37 -0
  17. package/build/src/Handlers/HandlerFactory.d.ts +6 -0
  18. package/build/src/Handlers/HandlerFactory.js +36 -0
  19. package/build/src/Handlers/Helpers.d.ts +14 -0
  20. package/build/src/Handlers/Helpers.js +231 -0
  21. package/build/src/Handlers/PaginateHandler.d.ts +4 -0
  22. package/build/src/Handlers/PaginateHandler.js +48 -0
  23. package/build/src/Handlers/PatchHandler.d.ts +4 -0
  24. package/build/src/Handlers/PatchHandler.js +62 -0
  25. package/build/src/Handlers/ShowHandler.d.ts +4 -0
  26. package/build/src/Handlers/ShowHandler.js +51 -0
  27. package/build/src/Handlers/StoreHandler.d.ts +4 -0
  28. package/build/src/Handlers/StoreHandler.js +59 -0
  29. package/build/src/Handlers/UpdateHandler.d.ts +4 -0
  30. package/build/src/Handlers/UpdateHandler.js +62 -0
  31. package/build/src/Interfaces.d.ts +165 -0
  32. package/build/src/Interfaces.js +3 -0
  33. package/build/src/Model.d.ts +24 -0
  34. package/build/src/Model.js +108 -0
  35. package/build/src/Resolvers/FileResolver.d.ts +5 -0
  36. package/build/src/Resolvers/FileResolver.js +76 -0
  37. package/build/src/Resolvers/FolderResolver.d.ts +5 -0
  38. package/build/src/Resolvers/FolderResolver.js +19 -0
  39. package/build/src/Resolvers/GeneralHookResolver.d.ts +5 -0
  40. package/build/src/Resolvers/GeneralHookResolver.js +35 -0
  41. package/build/src/Resolvers/ModelMiddlewareResolver.d.ts +7 -0
  42. package/build/src/Resolvers/ModelMiddlewareResolver.js +29 -0
  43. package/build/src/Resolvers/ModelResolver.d.ts +9 -0
  44. package/build/src/Resolvers/ModelResolver.js +101 -0
  45. package/build/src/Resolvers/TransactionResolver.d.ts +8 -0
  46. package/build/src/Resolvers/TransactionResolver.js +75 -0
  47. package/build/src/Resolvers/index.d.ts +7 -0
  48. package/build/src/Resolvers/index.js +18 -0
  49. package/build/src/Server.d.ts +8 -0
  50. package/build/src/Server.js +101 -0
  51. package/build/src/Services/DocumentationService.d.ts +9 -0
  52. package/build/src/Services/DocumentationService.js +22 -0
  53. package/build/src/Services/IoCService.d.ts +9 -0
  54. package/build/src/Services/IoCService.js +51 -0
  55. package/build/src/Services/LogService.d.ts +12 -0
  56. package/build/src/Services/LogService.js +41 -0
  57. package/build/src/Services/ModelListService.d.ts +8 -0
  58. package/build/src/Services/ModelListService.js +18 -0
  59. package/build/src/Services/ModelService.d.ts +20 -0
  60. package/build/src/Services/ModelService.js +38 -0
  61. package/build/src/Services/QueryService.d.ts +39 -0
  62. package/build/src/Services/QueryService.js +447 -0
  63. package/build/src/Services/SchemaValidatorService.d.ts +12 -0
  64. package/build/src/Services/SchemaValidatorService.js +114 -0
  65. package/build/src/Services/index.d.ts +8 -0
  66. package/build/src/Services/index.js +20 -0
  67. package/build/src/constants.d.ts +23 -0
  68. package/build/src/constants.js +62 -0
  69. package/package.json +65 -56
  70. package/readme.md +152 -145
  71. package/.eslintrc.cjs +0 -24
  72. package/.github/PULL_REQUEST_TEMPLATE.md +0 -32
  73. package/.github/workflows/auto-tag.yml +0 -15
  74. package/.github/workflows/npm-publish.yml +0 -18
  75. package/.github/workflows/test-integration.yml +0 -29
  76. package/.github/workflows/test-unit.yml +0 -23
  77. package/CHANGELOG.md +0 -144
  78. package/babel.config.cjs +0 -12
  79. package/index.js +0 -21
  80. package/jest.config.js +0 -4
  81. package/src/Server.js +0 -118
  82. package/src/constants.js +0 -148
  83. package/src/core/Config.js +0 -38
  84. package/src/core/Docs.js +0 -43
  85. package/src/core/HttpResponse.js +0 -10
  86. package/src/core/IoC.js +0 -41
  87. package/src/core/Logger.js +0 -46
  88. package/src/core/Model.js +0 -86
  89. package/src/core/QueryParser.js +0 -544
  90. package/src/handlers/all.js +0 -73
  91. package/src/handlers/destroy.js +0 -50
  92. package/src/handlers/helpers.js +0 -320
  93. package/src/handlers/index.js +0 -9
  94. package/src/handlers/paginate.js +0 -77
  95. package/src/handlers/patch.js +0 -95
  96. package/src/handlers/show.js +0 -81
  97. package/src/handlers/store.js +0 -82
  98. package/src/handlers/update.js +0 -92
  99. package/src/resolvers/checkModelColumns.js +0 -113
  100. package/src/resolvers/detectDbColumns.js +0 -42
  101. package/src/resolvers/getModelInstanceArray.js +0 -27
  102. package/src/resolvers/getModelTree.js +0 -63
  103. package/src/resolvers/index.js +0 -17
  104. package/src/resolvers/setExpressRoutes.js +0 -286
  105. package/src/resolvers/setModelHooks.js +0 -25
  106. package/src/resolvers/setModelRelations.js +0 -41
package/src/core/Model.js DELETED
@@ -1,86 +0,0 @@
1
- import pluralize from "pluralize";
2
- import { snakeCase } from "snake-case";
3
- import { RELATIONSHIPS, DEFAULT_HANDLERS } from "./../constants.js";
4
-
5
- class Model {
6
- constructor() {
7
- this.relations = [];
8
- }
9
-
10
- get primaryKey() {
11
- return "id";
12
- }
13
-
14
- get table() {
15
- return pluralize(snakeCase(this.constructor.name));
16
- }
17
-
18
- get fillable() {
19
- return [];
20
- }
21
-
22
- get validations() {
23
- return null;
24
- }
25
-
26
- get handlers() {
27
- return [...DEFAULT_HANDLERS];
28
- }
29
-
30
- get middlewares() {
31
- return [];
32
- }
33
-
34
- get hiddens() {
35
- return [];
36
- }
37
-
38
- get createdAtColumn() {
39
- return "created_at";
40
- }
41
-
42
- get updatedAtColumn() {
43
- return "updated_at";
44
- }
45
-
46
- get transaction() {
47
- return null;
48
- }
49
-
50
- get ignore() {
51
- return false;
52
- }
53
-
54
- hasMany(relatedModel, primaryKey = "id", foreignKey = null) {
55
- if (!foreignKey) {
56
- const currentModelName = pluralize.singular(
57
- this.constructor.name.toLowerCase()
58
- );
59
- foreignKey = `${currentModelName}_id`;
60
- }
61
- return {
62
- type: RELATIONSHIPS.HAS_MANY,
63
- model: relatedModel,
64
- primaryKey,
65
- foreignKey,
66
- };
67
- }
68
-
69
- hasOne(relatedModel, primaryKey = "id", foreignKey = null) {
70
- if (!foreignKey) {
71
- foreignKey = `${pluralize.singular(relatedModel.toLowerCase())}_id`;
72
- }
73
- return {
74
- type: RELATIONSHIPS.HAS_ONE,
75
- model: relatedModel,
76
- primaryKey,
77
- foreignKey,
78
- };
79
- }
80
-
81
- belongsTo(relatedModel, primaryKey, foreignKey) {
82
- return this.hasOne(relatedModel, foreignKey, primaryKey);
83
- }
84
- }
85
-
86
- export default Model;
@@ -1,544 +0,0 @@
1
- import HttpResponse from "./../core/HttpResponse.js";
2
- import { RELATIONSHIPS } from "../constants.js";
3
-
4
- class QueryParser {
5
- constructor({ model, models }) {
6
- this.model = model;
7
- this.models = models;
8
- this.createdJoins = [];
9
- this.relationColumns = [];
10
- this.usedConditionColumns = new Set();
11
- }
12
-
13
- applyFields(query, fields) {
14
- // Users should be able to select some fields to show.
15
- if (!Array.isArray(fields)) {
16
- query.select(`${this.model.instance.table}.${fields}`);
17
- } else if (fields.length > 0 && fields != "*") {
18
- const fullPathFields = fields.map((field) => {
19
- if (field.includes(".") === false) {
20
- return `${this.model.instance.table}.${field}`;
21
- }
22
- return field;
23
- });
24
- query.select([...fullPathFields, ...this.relationColumns]);
25
- } else {
26
- query.select(`${this.model.instance.table}.*`);
27
- }
28
- }
29
-
30
- applySorting(query, sort) {
31
- if (sort.length === 0) {
32
- return;
33
- }
34
-
35
- sort.forEach((item) => {
36
- query.orderBy(item.field, item.type);
37
- });
38
- }
39
-
40
- applyWheresInsideGroup(sub, ruleSet) {
41
- // If there is not any query, we don't have to filter the data.
42
- if (!ruleSet) {
43
- return;
44
- }
45
-
46
- if (Array.isArray(ruleSet)) {
47
- for (const item of ruleSet) {
48
- // If the item is not an array, it means that it is a standard condition
49
- if (Array.isArray(item) === false) {
50
- this._applyConditionRule(sub, item);
51
- } else {
52
- // If the item is an array, we should create the query recursively.
53
- if (item[0].prefix === "or") {
54
- sub.orWhere((sub) => {
55
- this.applyWheresInsideGroup(sub, item);
56
- });
57
- } else {
58
- sub.where((sub) => {
59
- this.applyWheresInsideGroup(sub, item);
60
- });
61
- }
62
- }
63
- }
64
- } else {
65
- this._applyConditionRule(sub, ruleSet);
66
- }
67
- }
68
-
69
- applyWheres(query, ruleSet) {
70
- query.where((sub) => {
71
- this.applyWheresInsideGroup(sub, ruleSet);
72
- });
73
-
74
- this._applyRelatedQueryJoins(query, ruleSet);
75
- }
76
-
77
- get(query) {
78
- const conditions = this._parseSections(this._getSections(query));
79
- const usedColumns = this._getUsedColumns(conditions);
80
- const undefinedColumns = usedColumns.filter((columnName) => {
81
- let currentModel = this.model;
82
- let realColumName = columnName;
83
- if (columnName.includes(".")) {
84
- const [table, splittedColumnName] = columnName.split(".");
85
- currentModel = this.models.find(
86
- (model) => model.instance.table === table
87
- );
88
- realColumName = splittedColumnName;
89
- }
90
- return !currentModel.instance.columnNames.includes(realColumName);
91
- });
92
-
93
- if (undefinedColumns.length > 0) {
94
- throw new HttpResponse(400, {
95
- message: `Undefined column names: ${undefinedColumns.join(",")}`,
96
- });
97
- }
98
-
99
- return conditions;
100
- }
101
-
102
- _getUsedColumns(conditions) {
103
- return [
104
- ...conditions.fields,
105
- ...conditions.sort.map((item) => item.field),
106
- ...Array.from(this.usedConditionColumns),
107
- ];
108
- }
109
-
110
- _applyConditionRule(sub, ruleSet) {
111
- const method = this._getConditionMethodName(ruleSet);
112
- const zeroArguments = ["Null", "NotNull"];
113
- const oneArguments = ["In", "NotIn", "Between", "NotBetween"];
114
-
115
- const fullFieldPath = `${ruleSet.table}.${ruleSet.field}`;
116
-
117
- if (zeroArguments.indexOf(ruleSet.condition) > -1) {
118
- return sub[`${method}${ruleSet.condition}`](fullFieldPath);
119
- }
120
-
121
- if (oneArguments.indexOf(ruleSet.condition) > -1) {
122
- return sub[`${method}${ruleSet.condition}`](fullFieldPath, ruleSet.value);
123
- }
124
-
125
- return sub[method](fullFieldPath, ruleSet.condition, ruleSet.value);
126
- }
127
-
128
- _applyRelatedQueryJoins(query, ruleSet) {
129
- if (!ruleSet) {
130
- return;
131
- }
132
-
133
- if (Array.isArray(ruleSet)) {
134
- for (const item of ruleSet) {
135
- // If the item is not an array, it means that it is a standard condition
136
- if (Array.isArray(item) === false) {
137
- this._applyJoinIfNecessary(query, item);
138
- } else {
139
- this._applyRelatedQueryJoins(query, item);
140
- }
141
- }
142
- } else {
143
- this._applyJoinIfNecessary(query, ruleSet);
144
- }
145
- }
146
-
147
- _applyJoinIfNecessary(query, ruleSet) {
148
- if (ruleSet.table !== this.model.instance.table) {
149
- this._addJoinOnce(query, ruleSet);
150
- }
151
- }
152
-
153
- _addJoinOnce(query, { model, relation }) {
154
- if (this.createdJoins.includes(relation.name)) {
155
- return;
156
- }
157
-
158
- const tableName = model.instance.table;
159
- const primaryKey = `${model.instance.table}.${relation.primaryKey}`;
160
- const foreignKey = `${this.model.instance.table}.${relation.foreignKey}`;
161
- query.leftJoin(tableName, primaryKey, foreignKey);
162
- this.createdJoins.push(relation.name);
163
- }
164
-
165
- _getSections(query) {
166
- if (typeof query !== "object") {
167
- throw new Error("You have to send an object to get sections.");
168
- }
169
-
170
- const sections = {
171
- q: null,
172
- page: null,
173
- per_page: null,
174
- sort: null,
175
- fields: null,
176
- with: null,
177
- };
178
-
179
- for (const key of Object.keys(query)) {
180
- if (sections[key] === undefined) {
181
- continue;
182
- }
183
-
184
- sections[key] = query[key];
185
- }
186
-
187
- return sections;
188
- }
189
-
190
- _parseSections(sections) {
191
- if (sections.q) {
192
- const queryContent = sections.q.replace(/%20/g, "").replace(/ /g, "");
193
-
194
- // Users can send an unacceptable query string. We shouldn't allow them to
195
- // send unacceptable structure because of security reasons.
196
- try {
197
- sections.q = JSON.parse(queryContent);
198
- } catch (err) {
199
- throw new HttpResponse(400, {
200
- message: `Unacceptable query string: ${queryContent}`,
201
- });
202
- }
203
- }
204
-
205
- sections.page = this._parsePage(sections.page);
206
- sections.per_page = this._parsePerPage(sections.per_page);
207
- sections.fields = this._parseFields(sections.fields);
208
- sections.sort = this._parseSortingOptions(sections.sort);
209
- sections.q = this._parseCondition(sections.q);
210
- sections.with = this._parseWith(this._parseWithSections(sections.with));
211
- this._addRelationColumns(sections.with);
212
-
213
- return sections;
214
- }
215
-
216
- _parsePage(content) {
217
- const value = parseInt(content);
218
-
219
- if (isNaN(value)) {
220
- return 1;
221
- }
222
-
223
- if (value <= 0) {
224
- return 1;
225
- }
226
-
227
- return value;
228
- }
229
-
230
- _parsePerPage(content) {
231
- const value = parseInt(content);
232
-
233
- if (isNaN(value) || value <= 1 || value > 10000) {
234
- return 10;
235
- }
236
-
237
- return value;
238
- }
239
-
240
- _parseFields(content) {
241
- if (!content) {
242
- return [];
243
- }
244
-
245
- // User should be able to select "all" fields.
246
- if (content.trim() === "*") {
247
- return "*";
248
- }
249
-
250
- const fields = content.split(",");
251
- fields.forEach((field) => {
252
- this._shouldBeAcceptableColumn(field);
253
- });
254
- return fields;
255
- }
256
-
257
- _parseSortingOptions(content) {
258
- // If there is not any sorting options, we don't have to return any value
259
- if (!content) {
260
- return [];
261
- }
262
-
263
- const result = [];
264
- for (let field of content.split(",")) {
265
- let type = "ASC";
266
- if (field.indexOf("-") === 0) {
267
- type = "DESC";
268
- field = field.substr(1);
269
- }
270
-
271
- if (field.indexOf("+") === 0) {
272
- field = field.substr(1);
273
- }
274
-
275
- this._shouldBeAcceptableColumn(field);
276
- result.push({
277
- field,
278
- type,
279
- });
280
- }
281
- return result;
282
- }
283
-
284
- _parseConditions(conditions) {
285
- if (!Array.isArray(conditions)) {
286
- throw new Error("An array should be sent to parseConditions() method.");
287
- }
288
-
289
- return conditions.map((condition) => {
290
- return this._parseCondition(condition);
291
- });
292
- }
293
-
294
- _parseCondition(content) {
295
- if (Array.isArray(content)) {
296
- return this._parseConditions(content);
297
- }
298
-
299
- if (!content) {
300
- return null;
301
- }
302
-
303
- const wheres = [];
304
- for (const key in content) {
305
- wheres.push(this._parseConditionObject(content, key));
306
- }
307
-
308
- return wheres;
309
- }
310
-
311
- _parseConditionObject(content, key) {
312
- const where = {
313
- prefix: null,
314
- model: this.model,
315
- table: this.model.instance.table,
316
- field: key,
317
- condition: "=",
318
- value: content[key],
319
- };
320
-
321
- // Sometimes we can have basic OR operations for queries
322
- if (where.field.indexOf("$or.") === 0) {
323
- where.prefix = "or";
324
- where.field = where.field.replace("$or.", "");
325
- }
326
-
327
- if (where.field.indexOf("$and.") === 0) {
328
- where.prefix = "and";
329
- where.field = where.field.replace("$and.", "");
330
- }
331
-
332
- // If there is not any value, it means that we should check nullable values
333
- if (where.value === null) {
334
- // If the client wants to see not nullable values
335
- if (this._hasSpecialStructure(where.field, ".$not")) {
336
- where.field = where.field.replace(".$not", "");
337
- where.condition = "NotNull";
338
- } else {
339
- // So, it means that the clients wants to see null valus
340
- where.condition = "Null";
341
- }
342
- } else {
343
- // If there is value, we should check it
344
- this._applySpecialCondition(where, "$not", "<>");
345
- this._applySpecialCondition(where, "$gt", ">");
346
- this._applySpecialCondition(where, "$gte", ">=");
347
- this._applySpecialCondition(where, "$lt", "<");
348
- this._applySpecialCondition(where, "$lte", "<=");
349
- this._applySpecialCondition(where, "$like", "LIKE");
350
- this._applySpecialCondition(where, "$notLike", "NOT LIKE");
351
- this._applySpecialCondition(where, "$in", "In");
352
- this._applySpecialCondition(where, "$notIn", "NotIn");
353
- this._applySpecialCondition(where, "$between", "Between");
354
- this._applySpecialCondition(where, "$notBetween", "NotBetween");
355
- }
356
-
357
- if (where.condition === "In" || where.condition === "NotIn") {
358
- where.value = where.value.split(",");
359
- }
360
-
361
- if (where.condition === "Between" || where.condition === "NotBetween") {
362
- where.value = where.value.split(":");
363
- }
364
-
365
- if (where.condition === "LIKE" || where.condition === "NOT LIKE") {
366
- where.value = where.value.replace(/\*/g, "%");
367
- }
368
-
369
- // This means that the condition is related with another table
370
- if (where.field.includes(".")) {
371
- const [relationName, field] = where.field.split(".");
372
-
373
- const relation = this.model.instance.relations.find(
374
- (item) =>
375
- item.name === relationName && item.type === RELATIONSHIPS.HAS_ONE
376
- );
377
-
378
- if (!relation) {
379
- throw new HttpResponse(400, {
380
- message: `Unacceptable query field: ${relationName}.${field}`,
381
- });
382
- }
383
-
384
- const relatedModel = this.models.find(
385
- (item) => item.name === relation.model
386
- );
387
-
388
- if (!relatedModel) {
389
- throw new HttpResponse(400, {
390
- message: `Undefined model name: ${relation.model}`,
391
- });
392
- }
393
-
394
- where.model = relatedModel;
395
- where.table = relatedModel.instance.table;
396
- where.relation = relation;
397
- where.field = field;
398
- }
399
-
400
- this._shouldBeAcceptableColumn(where.field);
401
- this.usedConditionColumns.add(`${where.table}.${where.field}`);
402
-
403
- return where;
404
- }
405
-
406
- _parseWithSections(content) {
407
- if (!content) {
408
- return [];
409
- }
410
- return content.split(",");
411
- }
412
-
413
- _parseWith(items) {
414
- const result = [];
415
- for (const item of items) {
416
- let relationship = item;
417
- let fields = [];
418
- let children = [];
419
-
420
- const columnIndex = relationship.indexOf("{");
421
- if (columnIndex > -1) {
422
- fields = this._splitWithRecursive(
423
- relationship.substr(
424
- columnIndex + 1,
425
- relationship.length - columnIndex - 2
426
- )
427
- );
428
-
429
- relationship = relationship.substr(0, columnIndex);
430
- }
431
-
432
- // We are checking there is any children
433
- children = fields.filter(
434
- (field) => field.indexOf("{") > -1 || field.indexOf(".") > -1
435
- );
436
-
437
- // Field list shouldn't have any related table
438
- fields = fields.filter(
439
- (field) => field.indexOf("{") === -1 && field.indexOf(".") === -1
440
- );
441
-
442
- // We should validate fields are correct.
443
- fields.forEach((field) => {
444
- this._shouldBeAcceptableColumn(field);
445
- });
446
-
447
- // We should calculate recursivly all of childre
448
- children = this._parseWith(children);
449
-
450
- result.push({
451
- relationship,
452
- fields,
453
- children,
454
- });
455
- }
456
- return result;
457
- }
458
-
459
- _splitWithRecursive(content) {
460
- const result = [];
461
- let startAt = 0;
462
- let subcounter = 0;
463
- for (let position = 0; position < content.length; position++) {
464
- const current = content[position];
465
-
466
- if (current === "{") {
467
- subcounter++;
468
- }
469
-
470
- if (current === "}") {
471
- subcounter--;
472
- }
473
-
474
- if (current === "|" && subcounter === 0) {
475
- result.push(content.substr(startAt, position - startAt));
476
- startAt = position + 1;
477
- }
478
- }
479
-
480
- result.push(content.substr(startAt));
481
- return result;
482
- }
483
-
484
- _applySpecialCondition(where, structure, condition) {
485
- structure = `.${structure}`;
486
- if (this._hasSpecialStructure(where.field, structure)) {
487
- where.field = where.field.replace(structure, "");
488
- where.condition = condition;
489
- }
490
- }
491
-
492
- _addRelationColumns(withs) {
493
- withs.forEach((item) => {
494
- const relation = this.model.instance.relations.find(
495
- (i) => i.name === item.relationship
496
- );
497
- if (!relation) {
498
- throw new HttpResponse(400, {
499
- message: `Undefined relation: ${item.relationship}`,
500
- });
501
- }
502
-
503
- this.relationColumns.push(
504
- `${this.model.instance.table}.${relation.foreignKey}`
505
- );
506
- });
507
- }
508
-
509
- _getConditionMethodName(ruleSet) {
510
- if (ruleSet.prefix === "or") {
511
- return "orWhere";
512
- }
513
- return "where";
514
- }
515
-
516
- _hasSpecialStructure(field, structure) {
517
- if (field.indexOf(structure) === -1) {
518
- return false;
519
- }
520
-
521
- if (field.indexOf(structure) === field.length - structure.length) {
522
- return true;
523
- }
524
-
525
- return false;
526
- }
527
-
528
- _shouldBeAcceptableColumn(field) {
529
- const regex = /^[0-9,a-z,A-Z_.]+$/;
530
- if (!field.match(regex)) {
531
- throw new HttpResponse(400, {
532
- message: `Unacceptable field name: ${field}`,
533
- });
534
- }
535
-
536
- if (field.indexOf(".") === 0 || field.indexOf(".") === field.length - 1) {
537
- throw new HttpResponse(400, {
538
- message: `You have to define the column specefically: ${field}`,
539
- });
540
- }
541
- }
542
- }
543
-
544
- export default QueryParser;
@@ -1,73 +0,0 @@
1
- import {
2
- callHooks,
3
- getRelatedData,
4
- filterHiddenFields,
5
- serializeData,
6
- addForeignKeyQuery,
7
- } from "./helpers.js";
8
- import { HOOK_FUNCTIONS, HANDLERS } from "./../constants.js";
9
- import QueryParser from "./../core/QueryParser.js";
10
-
11
- export default async (context) => {
12
- const { request, response, model, models, trx, relation, parentModel } =
13
- context;
14
-
15
- const queryParser = new QueryParser({ model, models });
16
-
17
- // We should parse URL query string to use as condition in Lucid query
18
- const conditions = queryParser.get(request.query);
19
-
20
- // Creating a new database query
21
- const query = trx.from(model.instance.table);
22
-
23
- // Users should be able to select some fields to show.
24
- queryParser.applyFields(query, conditions.fields);
25
-
26
- // Binding parent id if there is.
27
- addForeignKeyQuery(request, query, relation, parentModel);
28
-
29
- // Users should be able to filter records
30
- queryParser.applyWheres(query, conditions.q);
31
-
32
- await callHooks(model, HOOK_FUNCTIONS.onBeforeAll, {
33
- ...context,
34
- conditions,
35
- query,
36
- });
37
-
38
- // User should be able to select sorting fields and types
39
- queryParser.applySorting(query, conditions.sort);
40
-
41
- const result = await query;
42
-
43
- // We should try to get related data if there is any
44
- await getRelatedData(
45
- result.data,
46
- conditions.with,
47
- model,
48
- models,
49
- trx,
50
- HANDLERS.ALL,
51
- request
52
- );
53
-
54
- await callHooks(model, HOOK_FUNCTIONS.onAfterAll, {
55
- ...context,
56
- result,
57
- conditions,
58
- query,
59
- });
60
-
61
- // Serializing the data by the model's serialize method
62
- result.data = await serializeData(
63
- result.data,
64
- model.instance.serialize,
65
- HANDLERS.ALL,
66
- request
67
- );
68
-
69
- // Filtering hidden fields from the response data.
70
- filterHiddenFields(result.data, model.instance.hiddens);
71
-
72
- return response.json(result);
73
- };