axe-api 0.20.0-rc17 → 0.20.0-rc19

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.
@@ -43,16 +43,17 @@ class RouterBuilder {
43
43
  }
44
44
  build() {
45
45
  return __awaiter(this, void 0, void 0, function* () {
46
+ const app = yield Services_1.IoCService.useByType("App");
46
47
  const logger = yield Services_1.IoCService.useByType("LogService");
47
48
  const modelTree = yield Services_1.IoCService.useByType("ModelTree");
48
49
  const modelList = yield Services_1.IoCService.useByType("ModelListService");
49
50
  const generalHooks = yield Resolvers_1.GeneralHookResolver.resolve();
50
51
  if (generalHooks.onBeforeInit) {
51
- generalHooks.onBeforeInit();
52
+ generalHooks.onBeforeInit(app);
52
53
  }
53
54
  yield this.createRoutesByModelTree(modelTree, modelList);
54
55
  if (generalHooks.onAfterInit) {
55
- generalHooks.onAfterInit();
56
+ generalHooks.onAfterInit(app);
56
57
  }
57
58
  logger.info("Express routes have been created.");
58
59
  });
@@ -146,7 +146,7 @@ const getRelatedData = (data, withArray, model, modelList, database, handler, re
146
146
  for (const clientQuery of withArray) {
147
147
  // Find the relation of the model. If the model doesn't have any relationship like the
148
148
  // user wants, we can't show anything.
149
- const definedRelation = model.relations.find((relation) => relation.model === clientQuery.relationModel.name);
149
+ const definedRelation = model.relations.find((relation) => relation.name === clientQuery.relationship);
150
150
  if (!definedRelation) {
151
151
  throw new ApiError_1.default(`Undefined relation: ${clientQuery.relationship}`);
152
152
  }
@@ -191,6 +191,15 @@ const getRelatedData = (data, withArray, model, modelList, database, handler, re
191
191
  // };
192
192
  // }),
193
193
  // ];
194
+ console.log([
195
+ ...workList.map((relationship) => {
196
+ return {
197
+ relationship,
198
+ fields: [],
199
+ children: [],
200
+ };
201
+ }),
202
+ ]);
194
203
  // We should check if the column is defined on the table.
195
204
  const undefinedColumns = selectColumns.filter((column) => !foreignModel.columnNames.includes(column));
196
205
  if (undefinedColumns.length > 0) {
@@ -1,5 +1,5 @@
1
1
  import { Knex } from "knex";
2
- import { Request, Response, NextFunction } from "express";
2
+ import { Express, Request, Response, NextFunction } from "express";
3
3
  import { Column } from "knex-schema-inspector/lib/types/column";
4
4
  import { HandlerTypes, LogLevels, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes } from "./Enums";
5
5
  import Model from "./Model";
@@ -52,8 +52,8 @@ export interface IFolders {
52
52
  Models: string;
53
53
  }
54
54
  export interface IGeneralHooks {
55
- onBeforeInit: () => void | null;
56
- onAfterInit: () => void | null;
55
+ onBeforeInit: (app: Express) => void | null;
56
+ onAfterInit: (app: Express) => void | null;
57
57
  }
58
58
  export interface IHandlerBaseMiddleware {
59
59
  handler: HandlerTypes[];
@@ -39,7 +39,9 @@ class ModelResolver {
39
39
  if (typeof relationFunction !== "function") {
40
40
  throw new Error(`Model relation definition should be a function: ${model.name}.${relationMethod}`);
41
41
  }
42
- model.relations.push(relationFunction.call(model.instance));
42
+ const definition = relationFunction.call(model.instance);
43
+ definition.name = relationMethod;
44
+ model.relations.push(definition);
43
45
  }
44
46
  }
45
47
  });
@@ -0,0 +1,13 @@
1
+ import { IModelService, IWith } from "../Interfaces";
2
+ declare class WithQueryResolver {
3
+ model: IModelService;
4
+ models: IModelService[];
5
+ constructor(model: IModelService, models: IModelService[]);
6
+ resolve(expression: string): IWith[];
7
+ private resolveRelationsByKey;
8
+ private toNestedArray;
9
+ private getKey;
10
+ private getGroupValue;
11
+ private splitByGroups;
12
+ }
13
+ export default WithQueryResolver;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
7
+ class WithQueryResolver {
8
+ constructor(model, models) {
9
+ this.getKey = (group) => {
10
+ const firstIndex = group.indexOf("{");
11
+ if (firstIndex > -1) {
12
+ return group.substring(0, firstIndex);
13
+ }
14
+ return null;
15
+ };
16
+ this.getGroupValue = (group) => {
17
+ const firstIndex = group.indexOf("{");
18
+ if (firstIndex > -1) {
19
+ return group.substring(firstIndex + 1, group.length - 1);
20
+ }
21
+ return group;
22
+ };
23
+ this.model = model;
24
+ this.models = models;
25
+ }
26
+ resolve(expression) {
27
+ const result = [];
28
+ const root = {
29
+ key: "root",
30
+ children: [],
31
+ };
32
+ const currentModel = this.model;
33
+ this.toNestedArray(root, expression);
34
+ this.resolveRelationsByKey(result, null, root.children, currentModel);
35
+ return result;
36
+ }
37
+ resolveRelationsByKey(result, fields, expressions, model) {
38
+ for (const expression of expressions) {
39
+ const relationFunction = model.instance[expression.key];
40
+ if (typeof relationFunction === "function") {
41
+ const definition = relationFunction.call(model.instance);
42
+ const relationModel = this.models.find((item) => item.name === definition.model);
43
+ if (relationModel === undefined) {
44
+ throw new ApiError_1.default(`Undefined relation model: ${definition.model} (${expression.key})`);
45
+ }
46
+ const data = {
47
+ relationship: expression.key,
48
+ relationModel,
49
+ fields: [],
50
+ children: [],
51
+ };
52
+ if (expression.children.length > 0) {
53
+ this.resolveRelationsByKey(data.children, data.fields, expression.children, relationModel);
54
+ }
55
+ result.push(data);
56
+ }
57
+ else if (fields !== null) {
58
+ if (model.columnNames.includes(expression.key)) {
59
+ fields.push(expression.key);
60
+ }
61
+ else {
62
+ throw new ApiError_1.default(`It is not a field or a relation: ${expression.key}`);
63
+ }
64
+ }
65
+ else {
66
+ throw new ApiError_1.default(`Unknown expression: ${expression.key}`);
67
+ }
68
+ }
69
+ }
70
+ toNestedArray(root, expression) {
71
+ const groups = this.splitByGroups(expression);
72
+ for (const group of groups) {
73
+ const key = this.getKey(group);
74
+ if (key) {
75
+ const child = {
76
+ key,
77
+ children: [],
78
+ };
79
+ this.toNestedArray(child, this.getGroupValue(group));
80
+ root.children.push(child);
81
+ }
82
+ else {
83
+ root.children.push(...group.split("|").map((field) => {
84
+ return {
85
+ key: field,
86
+ children: [],
87
+ };
88
+ }));
89
+ }
90
+ }
91
+ }
92
+ splitByGroups(expression) {
93
+ const result = [];
94
+ let bracket = 0;
95
+ let startedAt = 0;
96
+ for (let index = 0; index < expression.length; index++) {
97
+ const char = expression[index];
98
+ if (char === "{") {
99
+ bracket++;
100
+ }
101
+ else if (char === "}") {
102
+ bracket--;
103
+ }
104
+ if (bracket === 0 && char === ",") {
105
+ result.push(expression.substring(startedAt, index));
106
+ startedAt = index + 1;
107
+ }
108
+ }
109
+ result.push(expression.substring(startedAt, expression.length));
110
+ return result;
111
+ }
112
+ }
113
+ exports.default = WithQueryResolver;
@@ -4,4 +4,5 @@ import GeneralHookResolver from "./GeneralHookResolver";
4
4
  import ModelMiddlewareResolver from "./ModelMiddlewareResolver";
5
5
  import ModelResolver from "./ModelResolver";
6
6
  import TransactionResolver from "./TransactionResolver";
7
- export { FileResolver, FolderResolver, GeneralHookResolver, ModelMiddlewareResolver, ModelResolver, TransactionResolver, };
7
+ import WithQueryResolver from "./WithQueryResolver";
8
+ export { FileResolver, FolderResolver, GeneralHookResolver, ModelMiddlewareResolver, ModelResolver, TransactionResolver, WithQueryResolver, };
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TransactionResolver = exports.ModelResolver = exports.ModelMiddlewareResolver = exports.GeneralHookResolver = exports.FolderResolver = exports.FileResolver = void 0;
6
+ exports.WithQueryResolver = exports.TransactionResolver = exports.ModelResolver = exports.ModelMiddlewareResolver = exports.GeneralHookResolver = exports.FolderResolver = exports.FileResolver = void 0;
7
7
  const FileResolver_1 = __importDefault(require("./FileResolver"));
8
8
  exports.FileResolver = FileResolver_1.default;
9
9
  const FolderResolver_1 = __importDefault(require("./FolderResolver"));
@@ -16,3 +16,5 @@ const ModelResolver_1 = __importDefault(require("./ModelResolver"));
16
16
  exports.ModelResolver = ModelResolver_1.default;
17
17
  const TransactionResolver_1 = __importDefault(require("./TransactionResolver"));
18
18
  exports.TransactionResolver = TransactionResolver_1.default;
19
+ const WithQueryResolver_1 = __importDefault(require("./WithQueryResolver"));
20
+ exports.WithQueryResolver = WithQueryResolver_1.default;
@@ -1,5 +1,4 @@
1
- import { ConditionTypes } from "../Enums";
2
- import { IRawQuery, IQuery, ISortField, NestedWhere, IWhere, IWith, IModelService } from "../Interfaces";
1
+ import { IQuery, ISortField, NestedWhere, IWhere, IModelService } from "../Interfaces";
3
2
  import { Knex } from "knex";
4
3
  declare class QueryService {
5
4
  model: IModelService;
@@ -13,27 +12,23 @@ declare class QueryService {
13
12
  applyWheresInsideGroup(sub: Knex.QueryBuilder, ruleSet: NestedWhere | IWhere): void;
14
13
  applyWheres(query: Knex.QueryBuilder, ruleSet: NestedWhere): void;
15
14
  get(query: any): IQuery;
16
- _getUsedColumns(conditions: IQuery): string[];
17
- _applyConditionRule(sub: Knex.QueryBuilder, ruleSet: IWhere): Knex.QueryBuilder;
18
- _applyRelatedQueryJoins(query: Knex.QueryBuilder, ruleSet: NestedWhere): void;
19
- _applyJoinIfNecessary(query: Knex.QueryBuilder, ruleSet: IWhere): void;
20
- _addJoinOnce(query: Knex.QueryBuilder, ruleSet: IWhere): void;
21
- _getSections(query: any): IRawQuery;
22
- _parseSections(sections: IRawQuery): IQuery;
23
- _parsePage(content: any): number;
24
- _parsePerPage(content: any): number;
25
- _parseFields(content: any): string[];
26
- _parseSortingOptions(content: any): ISortField[];
27
- _parseConditions(conditions: any): NestedWhere;
28
- _parseCondition(content: any): NestedWhere;
29
- _parseConditionObject(content: any, key: string): IWhere;
30
- _parseWithSections(content: any): string[];
31
- _parseWith(items: string[]): IWith[];
32
- _splitWithRecursive(content: string): string[];
33
- _applySpecialCondition(where: IWhere, structure: string, condition: ConditionTypes): void;
34
- _addRelationColumns(withs: IWith[]): void;
35
- _getConditionMethodName(ruleSet: IWhere): "orWhere" | "where";
36
- _hasSpecialStructure(field: string, structure: string): boolean;
37
- _shouldBeAcceptableColumn(field: string): void;
15
+ private getUsedColumns;
16
+ private applyConditionRule;
17
+ private applyRelatedQueryJoins;
18
+ private applyJoinIfNecessary;
19
+ private addJoinOnce;
20
+ private parseSections;
21
+ private parsePage;
22
+ private parsePerPage;
23
+ private parseFields;
24
+ private parseSortingOptions;
25
+ private parseConditions;
26
+ private parseCondition;
27
+ private parseConditionObject;
28
+ private applySpecialCondition;
29
+ private addRelationColumns;
30
+ private getConditionMethodName;
31
+ private hasSpecialStructure;
32
+ private shouldBeAcceptableColumn;
38
33
  }
39
34
  export default QueryService;
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const Enums_1 = require("../Enums");
7
7
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
8
+ const Resolvers_1 = require("../Resolvers");
8
9
  class QueryService {
9
10
  constructor(model, models) {
10
11
  this.model = model;
@@ -46,7 +47,7 @@ class QueryService {
46
47
  // If the item is not an array, it means that it is a standard condition
47
48
  if (Array.isArray(item) === false) {
48
49
  const condition = item;
49
- this._applyConditionRule(sub, condition);
50
+ this.applyConditionRule(sub, condition);
50
51
  }
51
52
  else {
52
53
  // If the item is an array, we should create the query recursively.
@@ -66,18 +67,18 @@ class QueryService {
66
67
  }
67
68
  else {
68
69
  const condition = ruleSet;
69
- this._applyConditionRule(sub, condition);
70
+ this.applyConditionRule(sub, condition);
70
71
  }
71
72
  }
72
73
  applyWheres(query, ruleSet) {
73
74
  query.where((sub) => {
74
75
  this.applyWheresInsideGroup(sub, ruleSet);
75
76
  });
76
- this._applyRelatedQueryJoins(query, ruleSet);
77
+ this.applyRelatedQueryJoins(query, ruleSet);
77
78
  }
78
79
  get(query) {
79
- const conditions = this._parseSections(query);
80
- const usedColumns = this._getUsedColumns(conditions);
80
+ const conditions = this.parseSections(query);
81
+ const usedColumns = this.getUsedColumns(conditions);
81
82
  const undefinedColumns = usedColumns.filter((columnName) => {
82
83
  let currentModel = this.model;
83
84
  let realColumName = columnName;
@@ -93,15 +94,15 @@ class QueryService {
93
94
  }
94
95
  return conditions;
95
96
  }
96
- _getUsedColumns(conditions) {
97
+ getUsedColumns(conditions) {
97
98
  return [
98
99
  ...conditions.fields,
99
100
  ...conditions.sort.map((item) => item.name),
100
101
  ...Array.from(this.usedConditionColumns),
101
102
  ];
102
103
  }
103
- _applyConditionRule(sub, ruleSet) {
104
- const method = this._getConditionMethodName(ruleSet);
104
+ applyConditionRule(sub, ruleSet) {
105
+ const method = this.getConditionMethodName(ruleSet);
105
106
  const zeroArguments = ["Null", "NotNull"];
106
107
  const oneArguments = ["In", "NotIn", "Between", "NotBetween"];
107
108
  const fullFieldPath = `${ruleSet.table}.${ruleSet.field}`;
@@ -115,7 +116,7 @@ class QueryService {
115
116
  }
116
117
  return sub[method](fullFieldPath, ruleSet.condition, ruleSet.value);
117
118
  }
118
- _applyRelatedQueryJoins(query, ruleSet) {
119
+ applyRelatedQueryJoins(query, ruleSet) {
119
120
  if (!ruleSet) {
120
121
  return;
121
122
  }
@@ -124,23 +125,23 @@ class QueryService {
124
125
  // If the item is not an array, it means that it is a standard condition
125
126
  if (Array.isArray(item) === false) {
126
127
  const condition = item;
127
- this._applyJoinIfNecessary(query, condition);
128
+ this.applyJoinIfNecessary(query, condition);
128
129
  }
129
130
  else {
130
- this._applyRelatedQueryJoins(query, item);
131
+ this.applyRelatedQueryJoins(query, item);
131
132
  }
132
133
  }
133
134
  }
134
135
  else {
135
- this._applyJoinIfNecessary(query, ruleSet);
136
+ this.applyJoinIfNecessary(query, ruleSet);
136
137
  }
137
138
  }
138
- _applyJoinIfNecessary(query, ruleSet) {
139
+ applyJoinIfNecessary(query, ruleSet) {
139
140
  if (ruleSet.table !== this.model.instance.table) {
140
- this._addJoinOnce(query, ruleSet);
141
+ this.addJoinOnce(query, ruleSet);
141
142
  }
142
143
  }
143
- _addJoinOnce(query, ruleSet) {
144
+ addJoinOnce(query, ruleSet) {
144
145
  const { model, relation } = ruleSet;
145
146
  if (!relation) {
146
147
  return;
@@ -154,21 +155,7 @@ class QueryService {
154
155
  query.leftJoin(tableName, primaryKey, foreignKey);
155
156
  this.createdJoins.push(relation.name);
156
157
  }
157
- _getSections(query) {
158
- if (typeof query !== "object") {
159
- throw new ApiError_1.default("You have to send an object to get sections.");
160
- }
161
- const sections = {
162
- q: query.q || null,
163
- page: query.page || 1,
164
- per_page: query.per_page || 10,
165
- sort: query.sory || null,
166
- fields: query.fields || null,
167
- with: query.with || null,
168
- };
169
- return sections;
170
- }
171
- _parseSections(sections) {
158
+ parseSections(sections) {
172
159
  if (sections.q) {
173
160
  const queryContent = sections.q.replace(/%20/g, "").replace(/ /g, "");
174
161
  // Users can send an unacceptable query string. We shouldn't allow them to
@@ -180,18 +167,19 @@ class QueryService {
180
167
  throw new ApiError_1.default(`Unacceptable query string: ${queryContent}`);
181
168
  }
182
169
  }
170
+ const withQueryResolver = new Resolvers_1.WithQueryResolver(this.model, this.models);
183
171
  const query = {
184
- page: this._parsePage(sections.page),
185
- per_page: this._parsePerPage(sections.per_page),
186
- fields: this._parseFields(sections.fields),
187
- sort: this._parseSortingOptions(sections.sort),
188
- q: this._parseCondition(sections.q),
189
- with: this._parseWith(this._parseWithSections(sections.with)),
172
+ page: this.parsePage(sections.page),
173
+ per_page: this.parsePerPage(sections.per_page),
174
+ fields: this.parseFields(sections.fields),
175
+ sort: this.parseSortingOptions(sections.sort),
176
+ q: this.parseCondition(sections.q),
177
+ with: withQueryResolver.resolve((sections === null || sections === void 0 ? void 0 : sections.with) || ""),
190
178
  };
191
- this._addRelationColumns(query.with);
179
+ this.addRelationColumns(query.with);
192
180
  return query;
193
181
  }
194
- _parsePage(content) {
182
+ parsePage(content) {
195
183
  const value = parseInt(content);
196
184
  if (isNaN(value)) {
197
185
  return 1;
@@ -201,14 +189,14 @@ class QueryService {
201
189
  }
202
190
  return value;
203
191
  }
204
- _parsePerPage(content) {
192
+ parsePerPage(content) {
205
193
  const value = parseInt(content);
206
194
  if (isNaN(value) || value <= 1 || value > 10000) {
207
195
  return 10;
208
196
  }
209
197
  return value;
210
198
  }
211
- _parseFields(content) {
199
+ parseFields(content) {
212
200
  if (!content) {
213
201
  return [];
214
202
  }
@@ -219,11 +207,11 @@ class QueryService {
219
207
  }
220
208
  const fields = strContent.split(",");
221
209
  fields.forEach((field) => {
222
- this._shouldBeAcceptableColumn(field);
210
+ this.shouldBeAcceptableColumn(field);
223
211
  });
224
212
  return fields;
225
213
  }
226
- _parseSortingOptions(content) {
214
+ parseSortingOptions(content) {
227
215
  // If there is not any sorting options, we don't have to return any value
228
216
  if (!content) {
229
217
  return [];
@@ -239,7 +227,7 @@ class QueryService {
239
227
  if (field.indexOf("+") === 0) {
240
228
  field = field.substr(1);
241
229
  }
242
- this._shouldBeAcceptableColumn(field);
230
+ this.shouldBeAcceptableColumn(field);
243
231
  result.push({
244
232
  name: field,
245
233
  type,
@@ -247,28 +235,28 @@ class QueryService {
247
235
  }
248
236
  return result;
249
237
  }
250
- _parseConditions(conditions) {
238
+ parseConditions(conditions) {
251
239
  if (!Array.isArray(conditions)) {
252
240
  throw new Error("An array should be sent to parseConditions() method.");
253
241
  }
254
242
  return conditions.map((condition) => {
255
- return this._parseCondition(condition);
243
+ return this.parseCondition(condition);
256
244
  });
257
245
  }
258
- _parseCondition(content) {
246
+ parseCondition(content) {
259
247
  if (Array.isArray(content)) {
260
- return this._parseConditions(content);
248
+ return this.parseConditions(content);
261
249
  }
262
250
  if (!content) {
263
251
  return [];
264
252
  }
265
253
  const wheres = [];
266
254
  for (const key in content) {
267
- wheres.push(this._parseConditionObject(content, key));
255
+ wheres.push(this.parseConditionObject(content, key));
268
256
  }
269
257
  return wheres;
270
258
  }
271
- _parseConditionObject(content, key) {
259
+ parseConditionObject(content, key) {
272
260
  const where = {
273
261
  prefix: null,
274
262
  model: this.model,
@@ -290,7 +278,7 @@ class QueryService {
290
278
  // If there is not any value, it means that we should check nullable values
291
279
  if (where.value === null) {
292
280
  // If the client wants to see not nullable values
293
- if (this._hasSpecialStructure(where.field, ".$not")) {
281
+ if (this.hasSpecialStructure(where.field, ".$not")) {
294
282
  where.field = where.field.replace(".$not", "");
295
283
  where.condition = Enums_1.ConditionTypes.NotNull;
296
284
  }
@@ -301,17 +289,17 @@ class QueryService {
301
289
  }
302
290
  else {
303
291
  // If there is value, we should check it
304
- this._applySpecialCondition(where, "$not", Enums_1.ConditionTypes["<>"]);
305
- this._applySpecialCondition(where, "$gt", Enums_1.ConditionTypes[">"]);
306
- this._applySpecialCondition(where, "$gte", Enums_1.ConditionTypes[">="]);
307
- this._applySpecialCondition(where, "$lt", Enums_1.ConditionTypes["<"]);
308
- this._applySpecialCondition(where, "$lte", Enums_1.ConditionTypes["<="]);
309
- this._applySpecialCondition(where, "$like", Enums_1.ConditionTypes.LIKE);
310
- this._applySpecialCondition(where, "$notLike", Enums_1.ConditionTypes["NOT LIKE"]);
311
- this._applySpecialCondition(where, "$in", Enums_1.ConditionTypes.In);
312
- this._applySpecialCondition(where, "$notIn", Enums_1.ConditionTypes.NotIn);
313
- this._applySpecialCondition(where, "$between", Enums_1.ConditionTypes.Between);
314
- this._applySpecialCondition(where, "$notBetween", Enums_1.ConditionTypes.NotBetween);
292
+ this.applySpecialCondition(where, "$not", Enums_1.ConditionTypes["<>"]);
293
+ this.applySpecialCondition(where, "$gt", Enums_1.ConditionTypes[">"]);
294
+ this.applySpecialCondition(where, "$gte", Enums_1.ConditionTypes[">="]);
295
+ this.applySpecialCondition(where, "$lt", Enums_1.ConditionTypes["<"]);
296
+ this.applySpecialCondition(where, "$lte", Enums_1.ConditionTypes["<="]);
297
+ this.applySpecialCondition(where, "$like", Enums_1.ConditionTypes.LIKE);
298
+ this.applySpecialCondition(where, "$notLike", Enums_1.ConditionTypes["NOT LIKE"]);
299
+ this.applySpecialCondition(where, "$in", Enums_1.ConditionTypes.In);
300
+ this.applySpecialCondition(where, "$notIn", Enums_1.ConditionTypes.NotIn);
301
+ this.applySpecialCondition(where, "$between", Enums_1.ConditionTypes.Between);
302
+ this.applySpecialCondition(where, "$notBetween", Enums_1.ConditionTypes.NotBetween);
315
303
  }
316
304
  if (where.condition === "In" || where.condition === "NotIn") {
317
305
  where.value = where.value.split(",");
@@ -338,94 +326,33 @@ class QueryService {
338
326
  where.relation = relation;
339
327
  where.field = field;
340
328
  }
341
- this._shouldBeAcceptableColumn(where.field);
329
+ this.shouldBeAcceptableColumn(where.field);
342
330
  this.usedConditionColumns.push(`${where.table}.${where.field}`);
343
331
  return where;
344
332
  }
345
- _parseWithSections(content) {
346
- if (!content) {
347
- return [];
348
- }
349
- const stringContent = content;
350
- return stringContent.split(",");
351
- }
352
- _parseWith(items) {
353
- const result = [];
354
- for (const item of items) {
355
- let relationship = item;
356
- let fields = [];
357
- let children = [];
358
- const columnIndex = relationship.indexOf("{");
359
- if (columnIndex > -1) {
360
- fields = this._splitWithRecursive(relationship.substr(columnIndex + 1, relationship.length - columnIndex - 2));
361
- relationship = relationship.substr(0, columnIndex);
362
- }
363
- // We are checking there is any children
364
- children = fields.filter((field) => field.indexOf("{") > -1 || field.indexOf(".") > -1);
365
- // Field list shouldn't have any related table
366
- fields = fields.filter((field) => field.indexOf("{") === -1 && field.indexOf(".") === -1);
367
- // We should validate fields are correct.
368
- fields.forEach((field) => {
369
- this._shouldBeAcceptableColumn(field);
370
- });
371
- // We should calculate recursivly all of childre
372
- children = this._parseWith(children);
373
- const relationModel = this.models.find((item) => item.name.toLowerCase() === relationship.toLowerCase());
374
- if (!relationModel) {
375
- throw new ApiError_1.default(`Undefined relationship: ${relationship}`);
376
- }
377
- result.push({
378
- relationship,
379
- relationModel,
380
- fields,
381
- children,
382
- });
383
- }
384
- return result;
385
- }
386
- _splitWithRecursive(content) {
387
- const result = [];
388
- let startAt = 0;
389
- let subcounter = 0;
390
- for (let position = 0; position < content.length; position++) {
391
- const current = content[position];
392
- if (current === "{") {
393
- subcounter++;
394
- }
395
- if (current === "}") {
396
- subcounter--;
397
- }
398
- if (current === "|" && subcounter === 0) {
399
- result.push(content.substr(startAt, position - startAt));
400
- startAt = position + 1;
401
- }
402
- }
403
- result.push(content.substr(startAt));
404
- return result;
405
- }
406
- _applySpecialCondition(where, structure, condition) {
333
+ applySpecialCondition(where, structure, condition) {
407
334
  structure = `.${structure}`;
408
- if (this._hasSpecialStructure(where.field, structure)) {
335
+ if (this.hasSpecialStructure(where.field, structure)) {
409
336
  where.field = where.field.replace(structure, "");
410
337
  where.condition = condition;
411
338
  }
412
339
  }
413
- _addRelationColumns(withs) {
340
+ addRelationColumns(withs) {
414
341
  withs.forEach((item) => {
415
- const relation = this.model.relations.find((i) => i.model.toLowerCase() === item.relationship.toLowerCase());
342
+ const relation = this.model.relations.find((i) => i.name === item.relationship);
416
343
  if (!relation) {
417
344
  throw new ApiError_1.default(`Undefined relation: ${item.relationship}`);
418
345
  }
419
346
  this.relationColumns.push(`${this.model.instance.table}.${relation.foreignKey}`);
420
347
  });
421
348
  }
422
- _getConditionMethodName(ruleSet) {
349
+ getConditionMethodName(ruleSet) {
423
350
  if (ruleSet.prefix === "or") {
424
351
  return "orWhere";
425
352
  }
426
353
  return "where";
427
354
  }
428
- _hasSpecialStructure(field, structure) {
355
+ hasSpecialStructure(field, structure) {
429
356
  if (field.indexOf(structure) === -1) {
430
357
  return false;
431
358
  }
@@ -434,7 +361,7 @@ class QueryService {
434
361
  }
435
362
  return false;
436
363
  }
437
- _shouldBeAcceptableColumn(field) {
364
+ shouldBeAcceptableColumn(field) {
438
365
  const regex = /^[0-9,a-z,A-Z_.]+$/;
439
366
  if (!field.match(regex)) {
440
367
  throw new ApiError_1.default(`Unacceptable field name: ${field}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axe-api",
3
- "version": "0.20.0-rc17",
3
+ "version": "0.20.0-rc19",
4
4
  "description": "AXE API is a simple tool which has been created based on Express and Knex.js to create Rest APIs quickly.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -41,9 +41,10 @@
41
41
  "@babel/core": "^7.16.10",
42
42
  "@babel/node": "^7.16.8",
43
43
  "@babel/preset-env": "^7.16.11",
44
+ "@babel/preset-typescript": "^7.18.6",
44
45
  "@babel/runtime": "^7.16.7",
45
46
  "@types/pluralize": "^0.0.29",
46
- "babel-jest": "^27.4.6",
47
+ "babel-jest": "^29.0.3",
47
48
  "babel-loader": "^8.2.3",
48
49
  "babel-plugin-module-resolver": "^4.1.0",
49
50
  "babel-preset-minify": "^0.5.1",
@@ -55,11 +56,11 @@
55
56
  "eslint-plugin-standard": "^5.0.0",
56
57
  "eslint-plugin-unicorn": "^33.0.1",
57
58
  "eslint-watch": "^7.0.0",
58
- "jest": "^27.4.7",
59
59
  "mysql": "^2.18.1",
60
60
  "nodemon": "^2.0.15",
61
61
  "pg": "^8.7.1",
62
62
  "set-value": ">=4.1.0",
63
- "sqlite3": "^5.0.2"
63
+ "sqlite3": "^5.0.2",
64
+ "ts-jest": "^29.0.1"
64
65
  }
65
66
  }