axe-api 0.22.0 → 0.30.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 (73) hide show
  1. package/build/dev-kit.d.ts +1 -0
  2. package/build/dev-kit.js +16 -0
  3. package/build/index.d.ts +3 -3
  4. package/build/index.js +4 -1
  5. package/build/src/Builders/ModelTreeBuilder.d.ts +3 -0
  6. package/build/src/Builders/ModelTreeBuilder.js +21 -17
  7. package/build/src/Builders/RouterBuilder.d.ts +3 -0
  8. package/build/src/Builders/RouterBuilder.js +28 -27
  9. package/build/src/Enums.d.ts +98 -0
  10. package/build/src/Enums.js +103 -1
  11. package/build/src/Exceptions/ApiError.d.ts +1 -1
  12. package/build/src/Exceptions/ApiError.js +2 -2
  13. package/build/src/Exceptions/AxeError.d.ts +8 -0
  14. package/build/src/Exceptions/AxeError.js +11 -0
  15. package/build/src/Handlers/AllHandler.js +4 -5
  16. package/build/src/Handlers/DocsHandler.d.ts +3 -0
  17. package/build/src/Handlers/DocsHandler.js +22 -0
  18. package/build/src/Handlers/HandlerFactory.d.ts +1 -1
  19. package/build/src/Handlers/HandlerFactory.js +1 -1
  20. package/build/src/Handlers/Helpers.d.ts +5 -3
  21. package/build/src/Handlers/Helpers.js +29 -13
  22. package/build/src/Handlers/PaginateHandler.js +4 -5
  23. package/build/src/Handlers/PatchHandler.js +2 -2
  24. package/build/src/Handlers/RoutesHandler.d.ts +3 -0
  25. package/build/src/Handlers/RoutesHandler.js +16 -0
  26. package/build/src/Handlers/ShowHandler.js +4 -5
  27. package/build/src/Handlers/StoreHandler.js +2 -2
  28. package/build/src/Handlers/UpdateHandler.js +2 -2
  29. package/build/src/Helpers.d.ts +4 -0
  30. package/build/src/Helpers.js +78 -0
  31. package/build/src/Interfaces.d.ts +54 -14
  32. package/build/src/Middlewares/acceptLanguageMiddleware.js +3 -5
  33. package/build/src/Model.d.ts +2 -2
  34. package/build/src/Model.js +3 -4
  35. package/build/src/Resolvers/FileResolver.js +2 -2
  36. package/build/src/Resolvers/GeneralHookResolver.d.ts +4 -2
  37. package/build/src/Resolvers/GeneralHookResolver.js +5 -8
  38. package/build/src/Resolvers/ModelResolver.d.ts +7 -0
  39. package/build/src/Resolvers/ModelResolver.js +99 -19
  40. package/build/src/Resolvers/TransactionResolver.d.ts +4 -2
  41. package/build/src/Resolvers/TransactionResolver.js +5 -4
  42. package/build/src/Resolvers/VersionConfigResolver.d.ts +7 -0
  43. package/build/src/Resolvers/VersionConfigResolver.js +58 -0
  44. package/build/src/Resolvers/VersionResolver.d.ts +7 -0
  45. package/build/src/Resolvers/VersionResolver.js +65 -0
  46. package/build/src/Resolvers/index.d.ts +3 -2
  47. package/build/src/Resolvers/index.js +5 -3
  48. package/build/src/Server.d.ts +3 -2
  49. package/build/src/Server.js +73 -46
  50. package/build/src/Services/APIService.d.ts +16 -0
  51. package/build/src/Services/APIService.js +82 -0
  52. package/build/src/Services/DocumentationService.d.ts +3 -1
  53. package/build/src/Services/DocumentationService.js +6 -0
  54. package/build/src/Services/LimitService.d.ts +5 -0
  55. package/build/src/Services/LimitService.js +116 -0
  56. package/build/src/Services/LogService.d.ts +4 -1
  57. package/build/src/Services/LogService.js +6 -0
  58. package/build/src/Services/ModelService.d.ts +6 -1
  59. package/build/src/Services/ModelService.js +8 -0
  60. package/build/src/Services/QueryService.d.ts +3 -2
  61. package/build/src/Services/QueryService.js +32 -7
  62. package/build/src/Services/SchemaValidatorService.d.ts +7 -0
  63. package/build/src/Services/SchemaValidatorService.js +62 -8
  64. package/build/src/Services/index.d.ts +3 -1
  65. package/build/src/Services/index.js +6 -1
  66. package/build/src/Types.d.ts +2 -0
  67. package/build/src/Types.js +2 -0
  68. package/build/src/constants.d.ts +5 -1
  69. package/build/src/constants.js +43 -2
  70. package/package.json +26 -24
  71. package/CHANGELOG.md +0 -212
  72. package/build/src/Resolvers/FolderResolver.d.ts +0 -5
  73. package/build/src/Resolvers/FolderResolver.js +0 -19
@@ -1,15 +1,17 @@
1
1
  import { Request } from "express";
2
- import { IModelService, IRelation, IHookParameter, IQuery } from "../Interfaces";
2
+ import { IModelService, IRelation, IHookParameter, IQuery, IVersion } from "../Interfaces";
3
3
  import { Knex } from "knex";
4
4
  import { IWith } from "../Interfaces";
5
5
  import { HandlerTypes, HookFunctionTypes, TimestampColumns } from "../Enums";
6
6
  import { ModelListService } from "../Services";
7
+ import { SerializationFunction } from "../Types";
7
8
  export declare const bindTimestampValues: (formData: Record<string, any>, columnTypes: TimestampColumns[] | undefined, model: IModelService) => void;
8
9
  export declare const getMergedFormData: (req: Request, fillables: string[]) => Record<string, any>;
9
10
  export declare const callHooks: (model: IModelService, type: HookFunctionTypes, params: IHookParameter) => Promise<void>;
10
11
  export declare const getParentColumn: (relation: IRelation | null) => string | null;
11
12
  export declare const addForeignKeyQuery: (request: Request, query: Knex.QueryBuilder, relation: IRelation | null, parentModel: IModelService | null) => void;
12
- export declare const serializeData: (itemArray: any[] | any, modelSerializer: (data: any, request: Request) => void, handler: HandlerTypes, request: Request) => Promise<any[]>;
13
+ export declare const serializeData: (version: IVersion, itemArray: any[] | any, modelSerializer: SerializationFunction | null, handler: HandlerTypes, request: Request) => Promise<any[]>;
13
14
  export declare const filterHiddenFields: (itemArray: any[], hiddens: string[] | null) => void;
14
15
  export declare const addSoftDeleteQuery: (model: IModelService, conditions: IQuery | null, query: Knex.QueryBuilder) => void;
15
- export declare const getRelatedData: (data: any[], withArray: IWith[], model: IModelService, modelList: ModelListService, database: Knex | Knex.Transaction, handler: HandlerTypes, request: Request) => Promise<void>;
16
+ export declare const getRelatedData: (version: IVersion, data: any[], withArray: IWith[], model: IModelService, modelList: ModelListService, database: Knex | Knex.Transaction, handler: HandlerTypes, request: Request) => Promise<void>;
17
+ export declare const isBoolean: (value: any) => boolean;
@@ -12,11 +12,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.getRelatedData = exports.addSoftDeleteQuery = exports.filterHiddenFields = exports.serializeData = exports.addForeignKeyQuery = exports.getParentColumn = exports.callHooks = exports.getMergedFormData = exports.bindTimestampValues = void 0;
15
+ exports.isBoolean = exports.getRelatedData = exports.addSoftDeleteQuery = exports.filterHiddenFields = exports.serializeData = exports.addForeignKeyQuery = exports.getParentColumn = exports.callHooks = exports.getMergedFormData = exports.bindTimestampValues = void 0;
16
16
  const change_case_1 = require("change-case");
17
17
  const Enums_1 = require("../Enums");
18
18
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
19
19
  const Services_1 = require("../Services");
20
+ const LimitService_1 = require("../Services/LimitService");
21
+ const constants_1 = require("../constants");
20
22
  const bindTimestampValues = (formData, columnTypes = [], model) => {
21
23
  if (columnTypes.includes(Enums_1.TimestampColumns.CREATED_AT) &&
22
24
  model.instance.createdAtColumn) {
@@ -30,7 +32,7 @@ const bindTimestampValues = (formData, columnTypes = [], model) => {
30
32
  exports.bindTimestampValues = bindTimestampValues;
31
33
  const getMergedFormData = (req, fillables) => {
32
34
  const formData = {};
33
- Object.keys(req.body).forEach((key) => {
35
+ Object.keys((req === null || req === void 0 ? void 0 : req.body) || {}).forEach((key) => {
34
36
  if (fillables.includes(key)) {
35
37
  formData[key] = req.body[key];
36
38
  }
@@ -92,14 +94,13 @@ const serialize = (data, callback, request) => {
92
94
  }
93
95
  return callback(data, request);
94
96
  };
95
- const globalSerializer = (itemArray, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
96
- const Application = yield Services_1.IoCService.useByType("Config");
97
- if (!Application.serializers) {
97
+ const globalSerializer = (version, itemArray, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
98
+ if (!version.config.serializers) {
98
99
  return itemArray;
99
100
  }
100
101
  const callbacks = [];
101
102
  // Push all runable serializer into callbacks.
102
- Application.serializers.map((configSerializer) => {
103
+ version.config.serializers.map((configSerializer) => {
103
104
  // Serialize data for all requests types.
104
105
  if (typeof configSerializer === "function") {
105
106
  callbacks.push(configSerializer);
@@ -116,9 +117,9 @@ const globalSerializer = (itemArray, handler, request) => __awaiter(void 0, void
116
117
  });
117
118
  return itemArray;
118
119
  });
119
- const serializeData = (itemArray, modelSerializer, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
120
+ const serializeData = (version, itemArray, modelSerializer, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
120
121
  itemArray = serialize(itemArray, modelSerializer, request);
121
- itemArray = yield globalSerializer(itemArray, handler, request);
122
+ itemArray = yield globalSerializer(version, itemArray, handler, request);
122
123
  return itemArray;
123
124
  });
124
125
  exports.serializeData = serializeData;
@@ -139,14 +140,16 @@ const filterHiddenFields = (itemArray, hiddens) => {
139
140
  };
140
141
  exports.filterHiddenFields = filterHiddenFields;
141
142
  const addSoftDeleteQuery = (model, conditions, query) => {
142
- // TODO: Trashed feature will be implemented later
143
- // (conditions === null || conditions?.trashed === false)
143
+ if (conditions !== null && (conditions === null || conditions === void 0 ? void 0 : conditions.trashed) === true) {
144
+ (0, LimitService_1.valideteQueryFeature)(model, Enums_1.QueryFeature.Trashed);
145
+ return;
146
+ }
144
147
  if (model.instance.deletedAtColumn) {
145
148
  query.whereNull(model.instance.deletedAtColumn);
146
149
  }
147
150
  };
148
151
  exports.addSoftDeleteQuery = addSoftDeleteQuery;
149
- const getRelatedData = (data, withArray, model, modelList, database, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
152
+ const getRelatedData = (version, data, withArray, model, modelList, database, handler, request) => __awaiter(void 0, void 0, void 0, function* () {
150
153
  if (withArray.length === 0) {
151
154
  return;
152
155
  }
@@ -163,6 +166,8 @@ const getRelatedData = (data, withArray, model, modelList, database, handler, re
163
166
  if (!foreignModel) {
164
167
  continue;
165
168
  }
169
+ // Validating the query limit
170
+ (0, LimitService_1.valideteQueryFeature)(model, constants_1.RelationQueryFeatureMap[definedRelation.type], `${model.instance.table}.${definedRelation.name}`, `${model.instance.table}.${definedRelation.name}`);
166
171
  let dataField = "primaryKey";
167
172
  let searchField = "foreignKey";
168
173
  if (definedRelation.type !== Enums_1.Relationships.HAS_MANY) {
@@ -208,12 +213,12 @@ const getRelatedData = (data, withArray, model, modelList, database, handler, re
208
213
  // Fetching related records by foreignKey and primary key values.
209
214
  let relatedRecords = yield foreignModelQuery.whereIn(searchFieldKey, parentPrimaryKeyValues);
210
215
  // We should serialize related data if there is any serialization function
211
- relatedRecords = yield (0, exports.serializeData)(relatedRecords, foreignModel.instance.serialize, handler, request);
216
+ relatedRecords = yield (0, exports.serializeData)(version, relatedRecords, foreignModel.serialize, handler, request);
212
217
  // We should hide hidden fields if there is any
213
218
  (0, exports.filterHiddenFields)(relatedRecords, foreignModel.instance.hiddens);
214
219
  // We should try to get child data if there is any on the query
215
220
  if (clientQuery.children.length > 0) {
216
- yield (0, exports.getRelatedData)(relatedRecords, clientQuery.children, foreignModel, modelList, database, handler, request);
221
+ yield (0, exports.getRelatedData)(version, relatedRecords, clientQuery.children, foreignModel, modelList, database, handler, request);
217
222
  }
218
223
  // Binding relation data to the parent rows.
219
224
  data.forEach((row) => {
@@ -226,3 +231,14 @@ const getRelatedData = (data, withArray, model, modelList, database, handler, re
226
231
  }
227
232
  });
228
233
  exports.getRelatedData = getRelatedData;
234
+ const isBoolean = (value) => {
235
+ if (value === undefined || value === null) {
236
+ return false;
237
+ }
238
+ value = (value || "").trim().toLocaleLowerCase();
239
+ if (value === "true" || value === "1" || value === "on" || value === "yes") {
240
+ return true;
241
+ }
242
+ return false;
243
+ };
244
+ exports.isBoolean = isBoolean;
@@ -13,9 +13,8 @@ const Helpers_1 = require("./Helpers");
13
13
  const Enums_1 = require("../Enums");
14
14
  const Services_1 = require("../Services");
15
15
  exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
16
- const modelList = yield Services_1.IoCService.useByType("ModelListService");
17
- const { model, req, database, relation, parentModel } = pack;
18
- const queryParser = new Services_1.QueryService(model, modelList.get());
16
+ const { version, model, req, database, relation, parentModel } = pack;
17
+ const queryParser = new Services_1.QueryService(model, version.modelList.get(), version.config);
19
18
  // We should parse URL query string to use as condition in Lucid query
20
19
  const conditions = queryParser.get(req.query);
21
20
  // Creating a new database query
@@ -38,12 +37,12 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
38
37
  isLengthAware: true,
39
38
  });
40
39
  // We should try to get related data if there is any
41
- yield (0, Helpers_1.getRelatedData)(result.data, conditions.with, model, modelList, database, Enums_1.HandlerTypes.PAGINATE, req);
40
+ yield (0, Helpers_1.getRelatedData)(version, result.data, conditions.with, model, version.modelList, database, Enums_1.HandlerTypes.PAGINATE, req);
42
41
  yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterPaginate, Object.assign(Object.assign({}, pack), { conditions,
43
42
  result,
44
43
  query }));
45
44
  // Serializing the data by the model's serialize method
46
- result.data = yield (0, Helpers_1.serializeData)(result.data, model.instance.serialize, Enums_1.HandlerTypes.PAGINATE, req);
45
+ result.data = yield (0, Helpers_1.serializeData)(version, result.data, model.serialize, Enums_1.HandlerTypes.PAGINATE, req);
47
46
  // Filtering hidden fields from the response data.
48
47
  (0, Helpers_1.filterHiddenFields)(result.data, model.instance.hiddens);
49
48
  return pack.res.json(result);
@@ -17,7 +17,7 @@ const Helpers_1 = require("./Helpers");
17
17
  const Enums_1 = require("../Enums");
18
18
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
19
19
  exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
20
- const { model, req, res, database, relation, parentModel } = pack;
20
+ const { version, model, req, res, database, relation, parentModel } = pack;
21
21
  const query = database.from(model.instance.table);
22
22
  // If there is a relation, we should bind it
23
23
  (0, Helpers_1.addForeignKeyQuery)(req, query, relation, parentModel);
@@ -60,7 +60,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
60
60
  formData,
61
61
  query }));
62
62
  // Serializing the data by the model's serialize method
63
- item = yield (0, Helpers_1.serializeData)(item, model.instance.serialize, Enums_1.HandlerTypes.PATCH, req);
63
+ item = yield (0, Helpers_1.serializeData)(version, item, model.serialize, Enums_1.HandlerTypes.PATCH, req);
64
64
  // Filtering hidden fields from the response data.
65
65
  (0, Helpers_1.filterHiddenFields)([item], model.instance.hiddens);
66
66
  return res.json(item);
@@ -0,0 +1,3 @@
1
+ import { Request, Response } from "express";
2
+ declare const _default: (req: Request, res: Response) => Promise<void>;
3
+ export default _default;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const Services_1 = require("../Services");
13
+ exports.default = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const docs = Services_1.DocumentationService.getInstance();
15
+ res.json(docs.get().map((route) => `${route.method} ${route.url}`));
16
+ });
@@ -17,9 +17,8 @@ const Enums_1 = require("../Enums");
17
17
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
18
18
  const Services_1 = require("../Services");
19
19
  exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
20
- const modelList = yield Services_1.IoCService.useByType("ModelListService");
21
- const { model, req, res, database, relation, parentModel } = pack;
22
- const queryParser = new Services_1.QueryService(model, modelList.get());
20
+ const { version, model, req, res, database, relation, parentModel } = pack;
21
+ const queryParser = new Services_1.QueryService(model, version.modelList.get(), version.config);
23
22
  // We should parse URL query string to use as condition in Lucid query
24
23
  const conditions = queryParser.get(req.query);
25
24
  // Fetching item
@@ -41,12 +40,12 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
41
40
  throw new ApiError_1.default(`The item is not found on ${model.name}.`);
42
41
  }
43
42
  // We should try to get related data if there is any
44
- yield (0, Helpers_1.getRelatedData)([item], conditions.with, model, modelList, database, Enums_1.HandlerTypes.ALL, req);
43
+ yield (0, Helpers_1.getRelatedData)(version, [item], conditions.with, model, version.modelList, database, Enums_1.HandlerTypes.ALL, req);
45
44
  yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterShow, Object.assign(Object.assign({}, pack), { query,
46
45
  conditions,
47
46
  item }));
48
47
  // Serializing the data by the model's serialize method
49
- item = yield (0, Helpers_1.serializeData)(item, model.instance.serialize, Enums_1.HandlerTypes.SHOW, req);
48
+ item = yield (0, Helpers_1.serializeData)(version, item, model.serialize, Enums_1.HandlerTypes.SHOW, req);
50
49
  // Filtering hidden fields from the response data.
51
50
  (0, Helpers_1.filterHiddenFields)([item], model.instance.hiddens);
52
51
  return res.json(item);
@@ -16,7 +16,7 @@ const validatorjs_1 = __importDefault(require("validatorjs"));
16
16
  const Helpers_1 = require("./Helpers");
17
17
  const Enums_1 = require("../Enums");
18
18
  exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
19
- const { model, req, res, database, relation, parentModel } = pack;
19
+ const { version, model, req, res, database, relation, parentModel } = pack;
20
20
  const requestMethod = req.method;
21
21
  const fillables = model.instance.getFillableFields(requestMethod);
22
22
  const formData = (0, Helpers_1.getMergedFormData)(req, fillables);
@@ -55,7 +55,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
55
55
  yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterInsert, Object.assign(Object.assign({}, pack), { formData,
56
56
  item }));
57
57
  // Serializing the data by the model's serialize method
58
- item = yield (0, Helpers_1.serializeData)(item, model.instance.serialize, Enums_1.HandlerTypes.INSERT, req);
58
+ item = yield (0, Helpers_1.serializeData)(version, item, model.serialize, Enums_1.HandlerTypes.INSERT, req);
59
59
  // Filtering hidden fields from the response data.
60
60
  (0, Helpers_1.filterHiddenFields)([item], model.instance.hiddens);
61
61
  return res.json(item);
@@ -17,7 +17,7 @@ const Helpers_1 = require("./Helpers");
17
17
  const Enums_1 = require("../Enums");
18
18
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
19
19
  exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
20
- const { model, req, res, database, relation, parentModel } = pack;
20
+ const { version, model, req, res, database, relation, parentModel } = pack;
21
21
  const query = database.from(model.instance.table);
22
22
  // If there is a relation, we should bind it
23
23
  (0, Helpers_1.addForeignKeyQuery)(req, query, relation, parentModel);
@@ -60,7 +60,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
60
60
  formData,
61
61
  query }));
62
62
  // Serializing the data by the model's serialize method
63
- item = yield (0, Helpers_1.serializeData)(item, model.instance.serialize, Enums_1.HandlerTypes.UPDATE, req);
63
+ item = yield (0, Helpers_1.serializeData)(version, item, model.serialize, Enums_1.HandlerTypes.UPDATE, req);
64
64
  // Filtering hidden fields from the response data.
65
65
  (0, Helpers_1.filterHiddenFields)([item], model.instance.hiddens);
66
66
  return res.json(item);
@@ -0,0 +1,4 @@
1
+ import { Request } from "express";
2
+ import { IVersion } from "./Interfaces";
3
+ export declare const getVersionByRequest: (req: Request) => Promise<IVersion>;
4
+ export declare const consoleAxeError: (error: any) => void;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.consoleAxeError = exports.getVersionByRequest = void 0;
16
+ const chalk_1 = __importDefault(require("chalk"));
17
+ const change_case_1 = require("change-case");
18
+ const Services_1 = require("./Services");
19
+ const getVersionByRequest = (req) => __awaiter(void 0, void 0, void 0, function* () {
20
+ // Application configuration is need for the default setting.
21
+ const api = Services_1.APIService.getInstance();
22
+ const matchedVersion = api.versions.find((version) => {
23
+ const path = `/${api.config.prefix}/${version.name}`;
24
+ return req.path.indexOf(path) === 0;
25
+ });
26
+ if (!matchedVersion) {
27
+ throw new Error(`Version is not matched: ${req.path}`);
28
+ }
29
+ return matchedVersion;
30
+ });
31
+ exports.getVersionByRequest = getVersionByRequest;
32
+ const consoleAxeError = (error) => {
33
+ const putWithSpace = (text, max) => {
34
+ const diff = max - text.length + 3;
35
+ for (let index = 0; index <= diff; index++) {
36
+ text = `${text} `;
37
+ }
38
+ text = ` ${text}`;
39
+ if (text.length > 77) {
40
+ let lines = [];
41
+ text = text.trim();
42
+ for (let step = 0; step < text.length / 70; step++) {
43
+ lines.push(text.substring(0, 70));
44
+ text = text.substring(70);
45
+ }
46
+ lines.push(text);
47
+ lines = lines.map((line) => putWithSpace(line, max));
48
+ return lines.flat();
49
+ }
50
+ return [text];
51
+ };
52
+ const getMaxLength = (code, message) => {
53
+ let maxLength = message.length;
54
+ if (code.length > message.length) {
55
+ maxLength = code.length;
56
+ }
57
+ if (maxLength > 70) {
58
+ maxLength = 70;
59
+ }
60
+ return maxLength;
61
+ };
62
+ const maxLength = getMaxLength(error.code, error.message);
63
+ const messages = [
64
+ "\n",
65
+ ...putWithSpace(" ", maxLength),
66
+ ...putWithSpace(`[${error.code}]`, maxLength),
67
+ ...putWithSpace(" ", maxLength),
68
+ ...putWithSpace(error.message, maxLength),
69
+ ...putWithSpace(" ", maxLength),
70
+ ];
71
+ console.log(chalk_1.default.bgRed.white(messages.join("\n")));
72
+ console.log(chalk_1.default.cyan([
73
+ "\n",
74
+ "You can find more in the documentation;",
75
+ `https://axe-api.com/errors.html#${(0, change_case_1.paramCase)(error.code)}`,
76
+ ].join("\n")));
77
+ };
78
+ exports.consoleAxeError = consoleAxeError;
@@ -1,8 +1,10 @@
1
1
  import { Knex } from "knex";
2
2
  import { Express, Request, Response, NextFunction } from "express";
3
3
  import { Column } from "knex-schema-inspector/lib/types/column";
4
- import { HandlerTypes, LogLevels, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes } from "./Enums";
4
+ import { HandlerTypes, LogLevels, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes, QueryFeature, QueryFeatureType } from "./Enums";
5
5
  import Model from "./Model";
6
+ import { SerializationFunction } from "./Types";
7
+ import { ModelListService } from "./Services";
6
8
  export interface IColumn extends Column {
7
9
  table_name: string;
8
10
  }
@@ -16,15 +18,33 @@ interface IHandlerBasedSerializer {
16
18
  handler: HandlerTypes[];
17
19
  serializer: ((data: any, request: Request) => void)[];
18
20
  }
21
+ export interface IQueryLimitConfig {
22
+ feature: QueryFeature;
23
+ type: QueryFeatureType;
24
+ key: string | null;
25
+ }
26
+ export interface IQueryDefaultConfig {
27
+ perPage?: number;
28
+ minPerPage?: number;
29
+ maxPerPage?: number;
30
+ }
31
+ export interface IQueryConfig {
32
+ limits: Array<IQueryLimitConfig[]>;
33
+ defaults?: IQueryDefaultConfig;
34
+ }
35
+ export interface IVersionConfig {
36
+ transaction: boolean | IHandlerBasedTransactionConfig | IHandlerBasedTransactionConfig[];
37
+ serializers: ((data: any, request: Request) => void)[] | IHandlerBasedSerializer[];
38
+ supportedLanguages: string[];
39
+ defaultLanguage: string;
40
+ query: IQueryConfig;
41
+ }
19
42
  export interface IApplicationConfig extends IConfig {
20
43
  env: string;
21
44
  port: number;
22
45
  logLevel: LogLevels;
23
46
  prefix: string;
24
- transaction: boolean | IHandlerBasedTransactionConfig | IHandlerBasedTransactionConfig[];
25
- serializers: ((data: any, request: Request) => void)[] | IHandlerBasedSerializer[];
26
- supportedLanguages: string[];
27
- defaultLanguage: string;
47
+ database: IDatabaseConfig;
28
48
  }
29
49
  export interface ILanguage {
30
50
  title: string;
@@ -35,14 +55,28 @@ export interface IAcceptedLanguage {
35
55
  language: ILanguage;
36
56
  quality: number;
37
57
  }
38
- export declare type IDatabaseConfig = Knex.Config;
39
- export interface IFolders {
40
- App: string;
41
- Config: string;
42
- Events: string;
43
- Hooks: string;
44
- Middlewares: string;
45
- Models: string;
58
+ export type IDatabaseConfig = Knex.Config;
59
+ export interface IVersionFolder {
60
+ root: string;
61
+ config: string;
62
+ events: string;
63
+ hooks: string;
64
+ middlewares: string;
65
+ models: string;
66
+ serialization: string;
67
+ }
68
+ export interface IVersion {
69
+ name: string;
70
+ config: IVersionConfig;
71
+ folders: IVersionFolder;
72
+ modelList: ModelListService;
73
+ modelTree: IModelService[];
74
+ }
75
+ export interface IAPI {
76
+ rootFolder: string;
77
+ appFolder: string;
78
+ versions: IVersion[];
79
+ config: IApplicationConfig;
46
80
  }
47
81
  export interface IGeneralHooks {
48
82
  onBeforeInit: (app: Express) => void | null;
@@ -85,8 +119,12 @@ export interface IModelService {
85
119
  events: Record<HookFunctionTypes, (params: IHookParameter) => void>;
86
120
  isRecursive: boolean;
87
121
  children: IModelService[];
122
+ queryLimits: IQueryLimitConfig[];
123
+ serialize: SerializationFunction | null;
88
124
  setColumns(columns: IColumn[]): void;
89
125
  setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: (params: IHookParameter) => void): void;
126
+ setQueryLimits(limits: IQueryLimitConfig[]): void;
127
+ setSerialization(callback: SerializationFunction): void;
90
128
  }
91
129
  export interface IRelation {
92
130
  type: Relationships;
@@ -96,6 +134,8 @@ export interface IRelation {
96
134
  foreignKey: string;
97
135
  }
98
136
  export interface IRequestPack {
137
+ api: IAPI;
138
+ version: IVersion;
99
139
  req: Request;
100
140
  res: Response;
101
141
  handlerType: HandlerTypes;
@@ -150,7 +190,7 @@ export interface IWhere {
150
190
  value: any;
151
191
  relation: IRelation | null;
152
192
  }
153
- export declare type NestedWhere = Array<NestedWhere | IWhere>;
193
+ export type NestedWhere = Array<NestedWhere | IWhere>;
154
194
  export interface IDependency {
155
195
  type: DependencyTypes;
156
196
  callback: any;
@@ -9,15 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const Services_1 = require("../Services");
13
12
  const Resolvers_1 = require("../Resolvers");
13
+ const Helpers_1 = require("../Helpers");
14
14
  exports.default = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  // Application configuration is need for the default setting.
16
- const configs = yield Services_1.IoCService.use("Config");
17
- const application = configs.Application;
18
- const { supportedLanguages, defaultLanguage } = application;
16
+ const version = yield (0, Helpers_1.getVersionByRequest)(req);
19
17
  // Setting the current language by the supported, default and the client prefences
20
- req.currentLanguage = Resolvers_1.AcceptLanguageResolver.resolve(req.get("accept-language") || "", supportedLanguages || ["en"], defaultLanguage || "en");
18
+ req.currentLanguage = Resolvers_1.AcceptLanguageResolver.resolve(req.get("accept-language") || "", version.config.supportedLanguages || ["en"], version.config.defaultLanguage || "en");
21
19
  // Adding the `Content-Language` header to the response object
22
20
  res.setHeader("Content-Language", req.currentLanguage.title);
23
21
  next();
@@ -1,5 +1,5 @@
1
1
  import { Request, Response, NextFunction } from "express";
2
- import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBaseMiddleware, IHandlerBasedTransactionConfig } from "./Interfaces";
2
+ import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBaseMiddleware, IHandlerBasedTransactionConfig, IQueryLimitConfig } from "./Interfaces";
3
3
  import { HandlerTypes, HttpMethods } from "./Enums";
4
4
  declare class Model {
5
5
  get primaryKey(): string;
@@ -14,13 +14,13 @@ declare class Model {
14
14
  get deletedAtColumn(): string | null;
15
15
  get transaction(): boolean | IHandlerBasedTransactionConfig | IHandlerBasedTransactionConfig[] | null;
16
16
  get ignore(): boolean;
17
+ get limits(): Array<IQueryLimitConfig[]>;
17
18
  getFillableFields(methodType: HttpMethods): string[];
18
19
  getValidationRules(methodType: HttpMethods): Record<string, string> | null;
19
20
  getMiddlewares(handlerType: HandlerTypes): ((req: Request, res: Response, next: NextFunction) => void)[];
20
21
  hasMany(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
21
22
  hasOne(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
22
23
  belongsTo(relatedModel: string, primaryKey: string, foreignKey: string): IRelation;
23
- serialize(data: any, request: Request): any;
24
24
  private hasStringValue;
25
25
  }
26
26
  export default Model;
@@ -44,6 +44,9 @@ class Model {
44
44
  get ignore() {
45
45
  return false;
46
46
  }
47
+ get limits() {
48
+ return [];
49
+ }
47
50
  getFillableFields(methodType) {
48
51
  if (this.fillable === null) {
49
52
  return [];
@@ -130,10 +133,6 @@ class Model {
130
133
  belongsTo(relatedModel, primaryKey, foreignKey) {
131
134
  return this.hasOne(relatedModel, foreignKey, primaryKey);
132
135
  }
133
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
134
- serialize(data, request) {
135
- return data;
136
- }
137
136
  hasStringValue() {
138
137
  const tester = this.validations;
139
138
  let status = false;
@@ -50,7 +50,7 @@ class FileResolver {
50
50
  .map((item) => item.name);
51
51
  for (const file of files) {
52
52
  const configFile = path_1.default.join(directory, file);
53
- const { default: content } = yield Promise.resolve().then(() => __importStar(require(configFile)));
53
+ const { default: content } = yield Promise.resolve(`${configFile}`).then(s => __importStar(require(s)));
54
54
  const key = file.replace(".ts", "").replace(".js", "");
55
55
  if (content === null || content === void 0 ? void 0 : content.prototype) {
56
56
  results[key] = new content();
@@ -74,7 +74,7 @@ class FileResolver {
74
74
  .map((item) => item.name);
75
75
  for (const file of files) {
76
76
  const configFile = path_1.default.join(directory, file);
77
- const content = yield Promise.resolve().then(() => __importStar(require(configFile)));
77
+ const content = yield Promise.resolve(`${configFile}`).then(s => __importStar(require(s)));
78
78
  const key = file.replace(".ts", "").replace(".js", "");
79
79
  results[key] = content;
80
80
  }
@@ -1,5 +1,7 @@
1
- import { IGeneralHooks } from "../Interfaces";
1
+ import { IGeneralHooks, IVersion } from "../Interfaces";
2
2
  declare class GeneralHookResolver {
3
- static resolve(): Promise<IGeneralHooks>;
3
+ private version;
4
+ constructor(version: IVersion);
5
+ resolve(): Promise<IGeneralHooks>;
4
6
  }
5
7
  export default GeneralHookResolver;
@@ -8,19 +8,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const path_1 = __importDefault(require("path"));
16
- const Services_1 = require("../Services");
17
12
  const _1 = require(".");
18
13
  class GeneralHookResolver {
19
- static resolve() {
14
+ constructor(version) {
15
+ this.version = version;
16
+ }
17
+ resolve() {
20
18
  return __awaiter(this, void 0, void 0, function* () {
21
- const folders = (yield Services_1.IoCService.use("Folders"));
22
19
  const fileResolver = new _1.FileResolver();
23
- const content = yield fileResolver.resolveContent(path_1.default.join(folders.App, "app"));
20
+ const content = yield fileResolver.resolveContent(this.version.folders.root);
24
21
  if (content && content.init) {
25
22
  const { onBeforeInit = null, onAfterInit = null } = content.init;
26
23
  return { onBeforeInit, onAfterInit };
@@ -1,9 +1,16 @@
1
+ import { IVersion } from "../Interfaces";
1
2
  declare class ModelResolver {
3
+ private version;
4
+ constructor(version: IVersion);
2
5
  resolve(): Promise<void>;
3
6
  private setModelRelations;
4
7
  private getModelList;
5
8
  private setDatabaseColumns;
6
9
  private setModelHooks;
10
+ private getDirectories;
11
+ private checkOldStyleHookFiles;
12
+ private setModelSerializations;
13
+ private setModelQueryLimits;
7
14
  private getInstanceMethods;
8
15
  }
9
16
  export default ModelResolver;