axe-api 1.0.0-rc9 → 1.0.1

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 (138) hide show
  1. package/build/index.d.ts +1 -0
  2. package/build/index.js +1 -0
  3. package/build/src/Builders/IndexBuilder.d.ts +7 -0
  4. package/build/src/Builders/IndexBuilder.js +35 -0
  5. package/build/src/Builders/ModelTreeBuilder.js +2 -1
  6. package/build/src/Builders/RouterBuilder.js +22 -11
  7. package/build/src/Builders/SwaggerBuilder.d.ts +2 -0
  8. package/build/src/Builders/SwaggerBuilder.js +609 -0
  9. package/build/src/Enums.d.ts +6 -1
  10. package/build/src/Enums.js +7 -1
  11. package/build/src/Handlers/DocsHandler.js +41 -0
  12. package/build/src/Handlers/ErrorHandler.d.ts +6 -0
  13. package/build/src/Handlers/ErrorHandler.js +12 -0
  14. package/build/src/Handlers/Helpers.d.ts +16 -4
  15. package/build/src/Handlers/Helpers.js +202 -5
  16. package/build/src/Handlers/RequestHandler.d.ts +4 -1
  17. package/build/src/Handlers/RequestHandler.js +36 -40
  18. package/build/src/Handlers/{DocsHTMLHandler.js → SwaggerHandler.js} +8 -7
  19. package/build/src/Interfaces.d.ts +103 -35
  20. package/build/src/Middlewares/RateLimit/AdaptorFactory.d.ts +3 -3
  21. package/build/src/Middlewares/RateLimit/MemoryAdaptor.d.ts +2 -2
  22. package/build/src/Middlewares/RateLimit/RedisAdaptor.d.ts +12 -4
  23. package/build/src/Middlewares/RateLimit/RedisAdaptor.js +24 -0
  24. package/build/src/Middlewares/RateLimit/index.d.ts +22 -3
  25. package/build/src/Middlewares/RateLimit/index.js +23 -3
  26. package/build/src/Model.d.ts +256 -10
  27. package/build/src/Model.js +322 -30
  28. package/build/src/Phases/All/FetchPhase.d.ts +2 -2
  29. package/build/src/Phases/All/PreparePhase.d.ts +2 -2
  30. package/build/src/Phases/All/index.d.ts +1 -1
  31. package/build/src/Phases/CacheTagCleanPhase.d.ts +3 -0
  32. package/build/src/{Handlers/MetadataHandler.js → Phases/CacheTagCleanPhase.js} +6 -10
  33. package/build/src/Phases/Delete/ActionPhase.d.ts +2 -2
  34. package/build/src/Phases/Delete/ActionPhase.js +21 -2
  35. package/build/src/Phases/Delete/PreparePhase.d.ts +2 -2
  36. package/build/src/Phases/Delete/QueryPhase.d.ts +2 -2
  37. package/build/src/Phases/Delete/ResponsePhase.d.ts +2 -2
  38. package/build/src/Phases/Delete/ResponsePhase.js +2 -1
  39. package/build/src/Phases/Delete/index.d.ts +4 -4
  40. package/build/src/Phases/ForceDelete/ActionPhase.d.ts +2 -2
  41. package/build/src/Phases/ForceDelete/ActionPhase.js +7 -0
  42. package/build/src/Phases/ForceDelete/PreparePhase.d.ts +2 -2
  43. package/build/src/Phases/ForceDelete/QueryPhase.d.ts +2 -2
  44. package/build/src/Phases/ForceDelete/index.d.ts +3 -3
  45. package/build/src/Phases/GetCachePhase.d.ts +3 -0
  46. package/build/src/Phases/GetCachePhase.js +39 -0
  47. package/build/src/Phases/List/RelationalPhase.d.ts +2 -2
  48. package/build/src/Phases/List/ResultPhase.d.ts +2 -2
  49. package/build/src/Phases/List/ResultPhase.js +9 -1
  50. package/build/src/Phases/List/SerializePhase.d.ts +2 -2
  51. package/build/src/Phases/List/index.d.ts +3 -3
  52. package/build/src/Phases/Paginate/FetchPhase.d.ts +2 -2
  53. package/build/src/Phases/Paginate/PreparePhase.d.ts +2 -2
  54. package/build/src/Phases/Paginate/index.d.ts +2 -2
  55. package/build/src/Phases/Patch/PrepareActionPhase.d.ts +2 -2
  56. package/build/src/Phases/Patch/PrepareActionPhase.js +13 -10
  57. package/build/src/Phases/Patch/index.d.ts +1 -1
  58. package/build/src/Phases/Search/FetchPhase.d.ts +3 -0
  59. package/build/src/Phases/Search/FetchPhase.js +66 -0
  60. package/build/src/Phases/Search/PreparePhase.d.ts +3 -0
  61. package/build/src/Phases/Search/PreparePhase.js +19 -0
  62. package/build/src/Phases/Search/index.d.ts +5 -0
  63. package/build/src/Phases/Search/index.js +11 -0
  64. package/build/src/Phases/Show/FetchPhase.d.ts +2 -2
  65. package/build/src/Phases/Show/FetchPhase.js +11 -1
  66. package/build/src/Phases/Show/PreparePhase.d.ts +2 -2
  67. package/build/src/Phases/Show/PreparePhase.js +5 -13
  68. package/build/src/Phases/Show/index.d.ts +2 -2
  69. package/build/src/Phases/Single/GetPhase.d.ts +2 -2
  70. package/build/src/Phases/Single/PrepareGetPhase.d.ts +2 -2
  71. package/build/src/Phases/Single/RelationalPhase.d.ts +2 -2
  72. package/build/src/Phases/Single/ResultPhase.d.ts +2 -2
  73. package/build/src/Phases/Single/ResultPhase.js +9 -1
  74. package/build/src/Phases/Single/SerializePhase.d.ts +2 -2
  75. package/build/src/Phases/Single/index.d.ts +5 -5
  76. package/build/src/Phases/Store/ActionPhase.d.ts +2 -2
  77. package/build/src/Phases/Store/ActionPhase.js +18 -7
  78. package/build/src/Phases/Store/PreparePhase.d.ts +2 -2
  79. package/build/src/Phases/Store/PreparePhase.js +14 -9
  80. package/build/src/Phases/Store/ResultPhase.d.ts +3 -0
  81. package/build/src/Phases/Store/ResultPhase.js +23 -0
  82. package/build/src/Phases/Store/index.d.ts +3 -2
  83. package/build/src/Phases/Store/index.js +2 -0
  84. package/build/src/Phases/URLSearchParamPhase.d.ts +3 -0
  85. package/build/src/Phases/URLSearchParamPhase.js +37 -0
  86. package/build/src/Phases/Update/ActionPhase.d.ts +2 -2
  87. package/build/src/Phases/Update/ActionPhase.js +14 -3
  88. package/build/src/Phases/Update/PrepareActionPhase.d.ts +2 -2
  89. package/build/src/Phases/Update/PrepareActionPhase.js +13 -10
  90. package/build/src/Phases/Update/index.d.ts +2 -2
  91. package/build/src/Resolvers/ModelResolver.d.ts +1 -0
  92. package/build/src/Resolvers/ModelResolver.js +21 -2
  93. package/build/src/Resolvers/TransactionResolver.js +3 -15
  94. package/build/src/Resolvers/VersionConfigResolver.js +6 -1
  95. package/build/src/Resolvers/VersionResolver.js +1 -0
  96. package/build/src/Server.d.ts +5 -0
  97. package/build/src/Server.js +44 -11
  98. package/build/src/Services/APIService.d.ts +3 -3
  99. package/build/src/Services/APIService.js +3 -16
  100. package/build/src/Services/App.d.ts +94 -8
  101. package/build/src/Services/App.js +94 -29
  102. package/build/src/Services/AxeRequest.d.ts +51 -2
  103. package/build/src/Services/AxeRequest.js +51 -4
  104. package/build/src/Services/AxeResponse.d.ts +28 -1
  105. package/build/src/Services/AxeResponse.js +28 -0
  106. package/build/src/Services/ConverterService.d.ts +5 -3
  107. package/build/src/Services/DocumentationService.d.ts +5 -2
  108. package/build/src/Services/DocumentationService.js +13 -1
  109. package/build/src/Services/ElasticService.d.ts +14 -0
  110. package/build/src/Services/ElasticService.js +74 -0
  111. package/build/src/Services/IoCService.d.ts +29 -2
  112. package/build/src/Services/IoCService.js +33 -6
  113. package/build/src/Services/LimitService.d.ts +18 -0
  114. package/build/src/Services/LimitService.js +18 -0
  115. package/build/src/Services/ModelService.d.ts +9 -5
  116. package/build/src/Services/ModelService.js +11 -0
  117. package/build/src/Services/QueryService.d.ts +3 -3
  118. package/build/src/Services/QueryService.js +6 -0
  119. package/build/src/Services/SchemaValidatorService.d.ts +1 -0
  120. package/build/src/Services/SchemaValidatorService.js +4 -0
  121. package/build/src/Services/URLService.d.ts +6 -14
  122. package/build/src/Services/URLService.js +10 -8
  123. package/build/src/Steps/Event.d.ts +11 -0
  124. package/build/src/Steps/Event.js +17 -0
  125. package/build/src/Steps/Hook.d.ts +11 -0
  126. package/build/src/Steps/Hook.js +17 -0
  127. package/build/src/Steps/Phase.d.ts +11 -0
  128. package/build/src/Steps/Phase.js +18 -0
  129. package/build/src/Types.d.ts +12 -10
  130. package/build/src/constants.d.ts +8 -9
  131. package/build/src/constants.js +217 -152
  132. package/package.json +51 -37
  133. package/build/dev-kit.d.ts +0 -1
  134. package/build/dev-kit.js +0 -16
  135. package/build/src/Middlewares/RateLimit/IAdaptor.d.ts +0 -6
  136. package/build/src/Middlewares/RateLimit/IAdaptor.js +0 -2
  137. /package/build/src/Handlers/{DocsHTMLHandler.d.ts → DocsHandler.d.ts} +0 -0
  138. /package/build/src/Handlers/{MetadataHandler.d.ts → SwaggerHandler.d.ts} +0 -0
@@ -1,8 +1,8 @@
1
1
  declare const _default: {
2
- RelationalPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
3
- ResultPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
4
- SerializePhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
5
- PrepareGetPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
6
- GetPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
2
+ RelationalPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
3
+ ResultPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
4
+ SerializePhase: (context: import("../../Interfaces").IContext) => Promise<void>;
5
+ PrepareGetPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
6
+ GetPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
7
7
  };
8
8
  export default _default;
@@ -1,3 +1,3 @@
1
- import { IRequestPack } from "../../Interfaces";
2
- declare const _default: (context: IRequestPack) => Promise<void>;
1
+ import { IContext } from "../../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
3
  export default _default;
@@ -9,21 +9,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ const Enums_1 = require("../../Enums");
13
+ const Services_1 = require("../../Services");
14
+ const Helpers_1 = require("../../Handlers/Helpers");
12
15
  exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
16
+ const { model, res } = context;
13
17
  const [returningResult] = yield context
14
- .database(context.model.instance.table)
18
+ .database(model.instance.table)
15
19
  .insert(context.formData)
16
- .returning(context.model.instance.primaryKey);
20
+ .returning(model.instance.primaryKey);
17
21
  let insertedPrimaryKeyValue = typeof returningResult === "number"
18
22
  ? returningResult
19
- : returningResult[context.model.instance.primaryKey];
23
+ : returningResult[model.instance.primaryKey];
20
24
  // If the user use a special primary key value, we should use that value
21
25
  if (insertedPrimaryKeyValue === 0) {
22
- insertedPrimaryKeyValue =
23
- context.formData[context.model.instance.primaryKey];
26
+ insertedPrimaryKeyValue = context.formData[model.instance.primaryKey];
24
27
  }
25
28
  context.item = yield context
26
- .database(context.model.instance.table)
27
- .where(context.model.instance.primaryKey, insertedPrimaryKeyValue)
29
+ .database(model.instance.table)
30
+ .where(model.instance.primaryKey, insertedPrimaryKeyValue)
28
31
  .first();
32
+ // Add index values
33
+ if (model.instance.search) {
34
+ const elastic = yield Services_1.IoCService.use("Elastic");
35
+ const body = (0, Helpers_1.getSearchData)(model, context.item);
36
+ yield elastic.insert(model.name, context.item[model.instance.primaryKey], body);
37
+ }
38
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
39
+ res.status(Enums_1.StatusCodes.CREATED);
29
40
  });
@@ -1,3 +1,3 @@
1
- import { IRequestPack } from "../../Interfaces";
2
- declare const _default: (context: IRequestPack) => Promise<void>;
1
+ import { IContext } from "../../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
3
  export default _default;
@@ -16,30 +16,35 @@ const validatorjs_1 = __importDefault(require("validatorjs"));
16
16
  const Helpers_1 = require("../../Handlers/Helpers");
17
17
  const Enums_1 = require("../../Enums");
18
18
  exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
19
- const requestMethod = context.req
20
- .method;
21
- const fillables = context.model.instance.getFillableFields(requestMethod);
22
- context.formData = (0, Helpers_1.getMergedFormData)(context.req, fillables);
23
- const validationRules = context.model.instance.getValidationRules(requestMethod);
19
+ const { req, res, model } = context;
20
+ const requestMethod = req.method;
21
+ const fillables = model.instance.getFillableFields(requestMethod);
22
+ context.formData = (0, Helpers_1.getMergedFormData)(req, fillables);
23
+ const validationRules = model.instance.getValidationRules(requestMethod);
24
24
  if (validationRules) {
25
25
  // The validation language should be set
26
- validatorjs_1.default.useLang(context.req.currentLanguage.language);
26
+ validatorjs_1.default.useLang(req.currentLanguage.language);
27
27
  // Validate the data
28
28
  const validation = new validatorjs_1.default(context.formData, validationRules);
29
29
  if (validation.fails()) {
30
- context.res.status(400).json(validation.errors);
30
+ res.status(Enums_1.StatusCodes.BAD_REQUEST).json(validation.errors);
31
31
  return;
32
32
  }
33
33
  }
34
34
  if (context.relation && context.parentModel) {
35
- const parentColumn = (0, Helpers_1.getParentColumn)(context.relation);
35
+ const parentColumn = (0, Helpers_1.getParentColumn)(context.parentModel, context.relation);
36
36
  if (parentColumn) {
37
37
  context.formData[context.relation.foreignKey] =
38
38
  context.params[parentColumn];
39
39
  }
40
40
  }
41
+ // Checking the foreign key values if there is any
42
+ const errors = yield (0, Helpers_1.getForeignKeyValueErrors)(context);
43
+ if (errors.length > 0) {
44
+ return res.status(Enums_1.StatusCodes.BAD_REQUEST).json({ errors });
45
+ }
41
46
  // We should bind the timestamp values
42
- (0, Helpers_1.bindTimestampValues)(context.formData, context.model, [
47
+ (0, Helpers_1.bindTimestampValues)(context.formData, model, [
43
48
  Enums_1.TimestampColumns.CREATED_AT,
44
49
  Enums_1.TimestampColumns.UPDATED_AT,
45
50
  ]);
@@ -0,0 +1,3 @@
1
+ import { IContext } from "../../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
+ export default _default;
@@ -0,0 +1,23 @@
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 Helpers_1 = require("../../Handlers/Helpers");
13
+ const Enums_1 = require("../../Enums");
14
+ exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
15
+ const { item, res, model, handlerType } = context;
16
+ // Deleting all cached result for the model
17
+ const config = model.getCacheConfiguration(handlerType);
18
+ if ((config === null || config === void 0 ? void 0 : config.enable) && (config === null || config === void 0 ? void 0 : config.invalidation) === Enums_1.CacheStrategies.TagBased) {
19
+ (0, Helpers_1.cleanRelatedCachedObjectByModel)(model, config);
20
+ }
21
+ // Preparing the json response
22
+ res.json(item);
23
+ });
@@ -1,5 +1,6 @@
1
1
  declare const _default: {
2
- PreparePhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
3
- ActionPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
2
+ PreparePhase: (context: import("../../Interfaces").IContext) => Promise<void>;
3
+ ActionPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
4
+ ResultPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
4
5
  };
5
6
  export default _default;
@@ -5,7 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const PreparePhase_1 = __importDefault(require("./PreparePhase"));
7
7
  const ActionPhase_1 = __importDefault(require("./ActionPhase"));
8
+ const ResultPhase_1 = __importDefault(require("./ResultPhase"));
8
9
  exports.default = {
9
10
  PreparePhase: PreparePhase_1.default,
10
11
  ActionPhase: ActionPhase_1.default,
12
+ ResultPhase: ResultPhase_1.default,
11
13
  };
@@ -0,0 +1,3 @@
1
+ import { IContext } from "../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
+ export default _default;
@@ -0,0 +1,37 @@
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
+ const URLService_1 = __importDefault(require("../Services/URLService"));
16
+ const Enums_1 = require("../Enums");
17
+ const queryByPrimaryKey = (content, queryModel, value) => __awaiter(void 0, void 0, void 0, function* () {
18
+ const { database } = content;
19
+ return database
20
+ .from(queryModel.instance.table)
21
+ .where(queryModel.instance.primaryKey, value)
22
+ .first();
23
+ });
24
+ exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
25
+ const { req, res } = context;
26
+ const match = URLService_1.default.match(req);
27
+ if (match) {
28
+ const promises = match.parentPairs.map((pair) => queryByPrimaryKey(context, pair.model, match.params[pair.paramName]));
29
+ const results = yield Promise.all(promises);
30
+ const isMissing = results.some((item) => !item);
31
+ if (isMissing) {
32
+ res
33
+ .status(Enums_1.StatusCodes.NOT_FOUND)
34
+ .json({ error: "The resource is not found" });
35
+ }
36
+ }
37
+ });
@@ -1,3 +1,3 @@
1
- import { IRequestPack } from "../../Interfaces";
2
- declare const _default: (context: IRequestPack) => Promise<void>;
1
+ import { IContext } from "../../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
3
  export default _default;
@@ -9,14 +9,25 @@ 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
+ const Helpers_1 = require("../../Handlers/Helpers");
12
14
  exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
15
+ const { model } = context;
13
16
  if (context.query) {
17
+ // Updating the data
14
18
  yield context.query
15
- .where(context.model.instance.primaryKey, context.item[context.model.instance.primaryKey])
19
+ .where(model.instance.primaryKey, context.item[model.instance.primaryKey])
16
20
  .update(context.formData);
21
+ // Fetchinf the latest version of the item
17
22
  context.item = yield context
18
- .database(context.model.instance.table)
19
- .where(context.model.instance.primaryKey, context.item[context.model.instance.primaryKey])
23
+ .database(model.instance.table)
24
+ .where(model.instance.primaryKey, context.item[model.instance.primaryKey])
20
25
  .first();
26
+ // Updat the index values
27
+ if (model.instance.search) {
28
+ const elastic = yield Services_1.IoCService.use("Elastic");
29
+ const body = (0, Helpers_1.getSearchData)(model, context.item);
30
+ yield elastic.update(model.name, context.item[model.instance.primaryKey], body);
31
+ }
21
32
  }
22
33
  });
@@ -1,3 +1,3 @@
1
- import { IRequestPack } from "../../Interfaces";
2
- declare const _default: (context: IRequestPack) => Promise<void>;
1
+ import { IContext } from "../../Interfaces";
2
+ declare const _default: (context: IContext) => Promise<void>;
3
3
  export default _default;
@@ -16,22 +16,25 @@ const validatorjs_1 = __importDefault(require("validatorjs"));
16
16
  const Enums_1 = require("../../Enums");
17
17
  const Helpers_1 = require("../../Handlers/Helpers");
18
18
  exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
19
- const requestMethod = context.req
20
- .method;
21
- const fillables = context.model.instance.getFillableFields(requestMethod);
22
- context.formData = (0, Helpers_1.getMergedFormData)(context.req, fillables);
23
- const validationRules = context.model.instance.getValidationRules(requestMethod);
19
+ const { req, res, model } = context;
20
+ const requestMethod = req.method;
21
+ const fillables = model.instance.getFillableFields(requestMethod);
22
+ context.formData = (0, Helpers_1.getMergedFormData)(req, fillables);
23
+ const validationRules = model.instance.getValidationRules(requestMethod);
24
24
  if (validationRules) {
25
25
  // The validation language should be set
26
- validatorjs_1.default.useLang(context.req.currentLanguage.language);
26
+ validatorjs_1.default.useLang(req.currentLanguage.language);
27
27
  // Validate the data
28
28
  const validation = new validatorjs_1.default(context.formData, validationRules);
29
29
  if (validation.fails()) {
30
- return context.res.status(400).json(validation.errors);
30
+ return res.status(Enums_1.StatusCodes.BAD_REQUEST).json(validation.errors);
31
31
  }
32
32
  }
33
+ // Checking the foreign key values if there is any
34
+ const errors = yield (0, Helpers_1.getForeignKeyValueErrors)(context);
35
+ if (errors.length > 0) {
36
+ return res.status(Enums_1.StatusCodes.BAD_REQUEST).json({ errors });
37
+ }
33
38
  // We should bind the timestamp values
34
- (0, Helpers_1.bindTimestampValues)(context.formData, context.model, [
35
- Enums_1.TimestampColumns.UPDATED_AT,
36
- ]);
39
+ (0, Helpers_1.bindTimestampValues)(context.formData, model, [Enums_1.TimestampColumns.UPDATED_AT]);
37
40
  });
@@ -1,5 +1,5 @@
1
1
  declare const _default: {
2
- ActionPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
3
- PrepareActionPhase: (context: import("../../Interfaces").IRequestPack) => Promise<void>;
2
+ ActionPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
3
+ PrepareActionPhase: (context: import("../../Interfaces").IContext) => Promise<void>;
4
4
  };
5
5
  export default _default;
@@ -3,6 +3,7 @@ declare class ModelResolver {
3
3
  private version;
4
4
  constructor(version: IVersion);
5
5
  resolve(): Promise<void>;
6
+ private setCacheOptions;
6
7
  private setModelRelations;
7
8
  private getModelList;
8
9
  private setDatabaseColumns;
@@ -20,6 +20,7 @@ const Enums_1 = require("../Enums");
20
20
  const Services_1 = require("../Services");
21
21
  const constants_1 = require("../constants");
22
22
  const AxeError_1 = __importDefault(require("../Exceptions/AxeError"));
23
+ const Helpers_1 = require("../Handlers/Helpers");
23
24
  class ModelResolver {
24
25
  constructor(version) {
25
26
  this.version = version;
@@ -41,9 +42,27 @@ class ModelResolver {
41
42
  yield this.setModelQueryLimits(modelList);
42
43
  Services_1.LogService.debug(`[${this.version.name}] Model query limits have been loaded`);
43
44
  this.version.modelList = modelList;
45
+ yield this.setCacheOptions(modelList);
44
46
  Services_1.LogService.debug(`[${this.version.name}] All models have been resolved.`);
45
47
  });
46
48
  }
49
+ setCacheOptions(modelList) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const api = Services_1.APIService.getInstance();
52
+ // For each model should be analyzed
53
+ for (const model of modelList.get()) {
54
+ // For each cachable handler, developers are able to set a different
55
+ // configuration. That's why we should check for each of them.
56
+ for (const handler of constants_1.ALL_HANDLERS) {
57
+ // API configuration, version configuration and the handler type are in
58
+ // order. The following function gets the correct configuration
59
+ const configuration = (0, Helpers_1.getModelCacheConfiguration)(model, api.config.cache, this.version.config.cache, handler);
60
+ // We need to set this to use late in action
61
+ model.setCacheConfiguration(handler, configuration);
62
+ }
63
+ }
64
+ });
65
+ }
47
66
  setModelRelations(modelList) {
48
67
  return __awaiter(this, void 0, void 0, function* () {
49
68
  for (const model of modelList.get()) {
@@ -73,8 +92,8 @@ class ModelResolver {
73
92
  }
74
93
  setDatabaseColumns(modelList) {
75
94
  return __awaiter(this, void 0, void 0, function* () {
76
- const database = (yield Services_1.IoCService.use("Database"));
77
- const schemaInspector = (yield Services_1.IoCService.use("SchemaInspector"));
95
+ const database = yield Services_1.IoCService.use("Database");
96
+ const schemaInspector = yield Services_1.IoCService.use("SchemaInspector");
78
97
  const inspector = schemaInspector(database);
79
98
  const columns = [];
80
99
  for (const table of yield inspector.tables()) {
@@ -28,21 +28,9 @@ class TransactionResolver {
28
28
  });
29
29
  }
30
30
  static getTransactionConfiguration(configItem, handlerType) {
31
- // An item definitions might have handler array such as;
32
- //
33
- // handler: [HandlerTypes.ALL, HandlerTypes.INSERT]
34
- if (Array.isArray(configItem.handler)) {
35
- // If this is an array, we should find the matched handler type
36
- const found = configItem.handler.find((item) => item === handlerType);
37
- // If there is, this is the our transaction choice
38
- if (found) {
39
- return configItem.transaction;
40
- }
41
- }
42
- else if (configItem.handler === handlerType) {
43
- // If the "configItem.handler" is not an array, should be matched
44
- // with the handlerType. If it matches, it means that this is our
45
- // transaction configuration
31
+ const found = configItem.handlers.find((item) => item === handlerType);
32
+ // If there is, this is the our transaction choice
33
+ if (found) {
46
34
  return configItem.transaction;
47
35
  }
48
36
  return null;
@@ -39,6 +39,7 @@ const path_1 = __importDefault(require("path"));
39
39
  const fs_1 = __importDefault(require("fs"));
40
40
  const AxeError_1 = __importDefault(require("../Exceptions/AxeError"));
41
41
  const Enums_1 = require("../Enums");
42
+ const constants_1 = require("../constants");
42
43
  class VersionConfigResolver {
43
44
  constructor(version) {
44
45
  this.version = version;
@@ -50,8 +51,12 @@ class VersionConfigResolver {
50
51
  !fs_1.default.existsSync(`${versionConfigFile}.js`)) {
51
52
  throw new AxeError_1.default(Enums_1.AxeErrorCode.VERSION_CONFIG_NOT_FOUND, `The version file not found: ${versionConfigFile}.ts`);
52
53
  }
54
+ // Loading the configuration file
53
55
  const { default: content } = yield Promise.resolve(`${versionConfigFile}`).then(s => __importStar(require(s)));
54
- this.version.config = content;
56
+ // Merging the configurations with the default version configurations
57
+ const apiConfiguration = Object.assign(Object.assign({}, constants_1.DEFAULT_VERSION_CONFIG), content);
58
+ // Setting the config values
59
+ this.version.config = apiConfiguration;
55
60
  });
56
61
  }
57
62
  }
@@ -23,6 +23,7 @@ const RESERVED_VERSION_FOLDERS = [
23
23
  "Hooks",
24
24
  "Models",
25
25
  "Serialization",
26
+ "Swagger",
26
27
  ];
27
28
  class VersionResolver {
28
29
  resolve() {
@@ -1,4 +1,9 @@
1
1
  declare class Server {
2
+ /**
3
+ * Start the application with the rootFolder.
4
+ *
5
+ * @param rootFolder
6
+ */
2
7
  start(rootFolder: string): Promise<void>;
3
8
  private bindDependencies;
4
9
  private analyzeVersions;
@@ -43,13 +43,23 @@ const knex_schema_inspector_1 = __importDefault(require("knex-schema-inspector")
43
43
  const knex_paginate_1 = require("knex-paginate");
44
44
  const Builders_1 = require("./Builders");
45
45
  const Services_1 = require("./Services");
46
- const MetadataHandler_1 = __importDefault(require("./Handlers/MetadataHandler"));
47
- const DocsHTMLHandler_1 = __importDefault(require("./Handlers/DocsHTMLHandler"));
46
+ const SwaggerHandler_1 = __importDefault(require("./Handlers/SwaggerHandler"));
47
+ const DocsHandler_1 = __importDefault(require("./Handlers/DocsHandler"));
48
48
  const RoutesHandler_1 = __importDefault(require("./Handlers/RoutesHandler"));
49
49
  const http_1 = __importDefault(require("http"));
50
50
  const RequestHandler_1 = __importDefault(require("./Handlers/RequestHandler"));
51
51
  const App_1 = __importDefault(require("./Services/App"));
52
+ const constants_1 = require("./constants");
53
+ const RedisAdaptor_1 = __importDefault(require("./Middlewares/RateLimit/RedisAdaptor"));
54
+ const RateLimit_1 = __importDefault(require("./Middlewares/RateLimit"));
55
+ const ElasticService_1 = __importDefault(require("./Services/ElasticService"));
56
+ const IndexBuilder_1 = __importDefault(require("./Builders/IndexBuilder"));
52
57
  class Server {
58
+ /**
59
+ * Start the application with the rootFolder.
60
+ *
61
+ * @param rootFolder
62
+ */
53
63
  start(rootFolder) {
54
64
  return __awaiter(this, void 0, void 0, function* () {
55
65
  dotenv_1.default.config();
@@ -77,11 +87,19 @@ class Server {
77
87
  Services_1.IoCService.singleton("App", () => new App_1.default());
78
88
  Services_1.IoCService.singleton("Database", () => __awaiter(this, void 0, void 0, function* () {
79
89
  const database = (0, knex_1.default)(api.config.database);
80
- Services_1.LogService.debug("Created a knex connection instance");
90
+ const { client } = api.config.database;
91
+ const { database: db, filename } = api.config.database.connection;
92
+ Services_1.LogService.debug(`Created a knex connection instance: [${client}:${db || filename}]`);
81
93
  (0, knex_paginate_1.attachPaginate)();
82
94
  Services_1.LogService.debug("Added pagination support to the knex");
83
95
  return database;
84
96
  }));
97
+ Services_1.IoCService.singleton("Redis", () => {
98
+ return new RedisAdaptor_1.default(api.config.redis, "");
99
+ });
100
+ Services_1.IoCService.singleton("Elastic", () => {
101
+ return new ElasticService_1.default(api.config.search, api.config.elasticSearch);
102
+ });
85
103
  });
86
104
  }
87
105
  analyzeVersions() {
@@ -93,6 +111,7 @@ class Server {
93
111
  yield new Resolvers_1.ModelResolver(version).resolve();
94
112
  yield new Services_1.SchemaValidatorService(version).validate();
95
113
  yield new Builders_1.ModelTreeBuilder(version).build();
114
+ yield new IndexBuilder_1.default(version).build();
96
115
  yield new Builders_1.RouterBuilder(version).build();
97
116
  }
98
117
  });
@@ -100,28 +119,42 @@ class Server {
100
119
  loadGeneralConfiguration() {
101
120
  return __awaiter(this, void 0, void 0, function* () {
102
121
  const api = Services_1.APIService.getInstance();
122
+ // Getting configuration file path
103
123
  const generalConfigFile = path_1.default.join(api.appFolder, "config");
124
+ // Loading the configurations
104
125
  const { default: content } = yield Promise.resolve(`${generalConfigFile}`).then(s => __importStar(require(s)));
105
- api.setConfig(content);
126
+ // Merge the configuration with the default configurations
127
+ const apiConfiguration = Object.assign(Object.assign({}, constants_1.DEFAULT_APP_CONFIG), content);
128
+ // Setting the configurations
129
+ api.setConfig(apiConfiguration);
130
+ // Setting the logger instance
106
131
  Services_1.LogService.setInstance(api.config.pino);
107
132
  Services_1.LogService.debug("Configurations are loaded");
108
133
  });
109
134
  }
110
135
  listen() {
136
+ var _a;
111
137
  return __awaiter(this, void 0, void 0, function* () {
112
- const app = yield Services_1.IoCService.useByType("App");
138
+ const app = yield Services_1.IoCService.use("App");
139
+ const api = Services_1.APIService.getInstance();
140
+ // Adding the default handler for auto-created routes
113
141
  app.use(RequestHandler_1.default);
142
+ // Setting the error handler
143
+ app.use(api.config.errorHandler);
114
144
  const server = http_1.default.createServer(app.instance);
115
- const api = Services_1.APIService.getInstance();
116
145
  server.on("error", function (e) {
117
- // Handle your error here
118
- console.log("GENERAL", e);
146
+ Services_1.LogService.error(e.message);
119
147
  });
120
- if (api.config.env === "development") {
121
- app.get("/metadata", MetadataHandler_1.default);
122
- app.get("/docs", DocsHTMLHandler_1.default);
148
+ if (api.config.docs) {
149
+ app.get("/swagger", SwaggerHandler_1.default);
150
+ app.get("/docs", DocsHandler_1.default);
123
151
  app.get("/routes", RoutesHandler_1.default);
124
152
  }
153
+ // Rate limitting should be added after init() functions.
154
+ if ((_a = api.config.rateLimit) === null || _a === void 0 ? void 0 : _a.enabled) {
155
+ Services_1.LogService.debug("New middleware: rateLimit()");
156
+ app.use(RateLimit_1.default);
157
+ }
125
158
  server.listen(api.config.port);
126
159
  Services_1.LogService.info(`Axe API listens requests on http://localhost:${api.config.port}`);
127
160
  });
@@ -1,4 +1,4 @@
1
- import { IApplicationConfig, IVersion } from "../Interfaces";
1
+ import { AxeConfig, IVersion } from "../Interfaces";
2
2
  declare class APIService {
3
3
  private folders;
4
4
  private static instance;
@@ -8,8 +8,8 @@ declare class APIService {
8
8
  get rootFolder(): string;
9
9
  get appFolder(): string;
10
10
  get versions(): IVersion[];
11
- get config(): IApplicationConfig;
12
- setConfig(config: IApplicationConfig): void;
11
+ get config(): AxeConfig;
12
+ setConfig(config: AxeConfig): void;
13
13
  addVersion(name: string): void;
14
14
  getVersion(name: string): IVersion;
15
15
  }
@@ -5,28 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const path_1 = __importDefault(require("path"));
7
7
  const ModelListService_1 = __importDefault(require("./ModelListService"));
8
+ const constants_1 = require("../constants");
8
9
  class APIService {
9
10
  constructor(rootFolder) {
10
11
  this.folders = {
11
12
  rootFolder: rootFolder,
12
13
  appFolder: path_1.default.join(rootFolder, "app"),
13
14
  versions: [],
14
- config: {
15
- env: "production",
16
- port: 3000,
17
- prefix: "/api",
18
- database: {},
19
- pino: {},
20
- rateLimit: {
21
- enabled: false,
22
- maxRequests: 200,
23
- windowInSeconds: 5,
24
- trustProxyIP: false,
25
- adaptor: {
26
- type: "memory",
27
- },
28
- },
29
- },
15
+ config: constants_1.DEFAULT_APP_CONFIG,
30
16
  };
31
17
  }
32
18
  static getInstance() {
@@ -66,6 +52,7 @@ class APIService {
66
52
  limits: [],
67
53
  },
68
54
  formidable: {},
55
+ cache: null,
69
56
  },
70
57
  folders: {
71
58
  root,