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
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = (err, req, res, next) => {
4
+ // Sett the HTTP status code
5
+ res.statusCode = 500;
6
+ // Set the default HTTP message
7
+ res.write(JSON.stringify({
8
+ error: "Internal server error",
9
+ }));
10
+ res.end();
11
+ next();
12
+ };
@@ -1,17 +1,29 @@
1
- import { IModelService, IRelation, IQuery, IVersion, IWith, IRequestPack } from "../Interfaces";
1
+ import { IModelService, IRelation, IQuery, IVersion, IWith, IContext, ICacheConfiguration } from "../Interfaces";
2
2
  import { Knex } from "knex";
3
3
  import { HandlerTypes, HookFunctionTypes, TimestampColumns } from "../Enums";
4
4
  import { ModelListService } from "../Services";
5
5
  import { SerializationFunction } from "../Types";
6
- import AxeRequest from "src/Services/AxeRequest";
6
+ import AxeRequest from "../Services/AxeRequest";
7
7
  export declare const bindTimestampValues: (formData: Record<string, any>, model: IModelService, columnTypes?: TimestampColumns[]) => void;
8
8
  export declare const getMergedFormData: (req: AxeRequest, fillables: string[]) => Record<string, any>;
9
- export declare const callHooks: (model: IModelService, type: HookFunctionTypes, params: IRequestPack) => Promise<void>;
10
- export declare const getParentColumn: (relation: IRelation | null) => string | null;
9
+ export declare const callHooks: (model: IModelService, type: HookFunctionTypes, params: IContext) => Promise<void>;
10
+ export declare const getParentColumn: (model: IModelService, relation: IRelation | null) => string | null;
11
11
  export declare const checkPrimaryKeyValueType: (model: IModelService, value: any) => void;
12
12
  export declare const addForeignKeyQuery: (request: AxeRequest, query: Knex.QueryBuilder, relation: IRelation | null, parentModel: IModelService | null) => void;
13
+ export declare const getParentIndexQuery: (request: AxeRequest, relation: IRelation | null, parentModel: IModelService | null) => any;
13
14
  export declare const serializeData: (version: IVersion, itemArray: any, modelSerializer: SerializationFunction | null, handler: HandlerTypes, request: AxeRequest) => Promise<any[]>;
14
15
  export declare const filterHiddenFields: (itemArray: any[], hiddens: string[] | null) => void;
15
16
  export declare const addSoftDeleteQuery: (model: IModelService, conditions: IQuery | null, query: Knex.QueryBuilder) => void;
16
17
  export declare const getRelatedData: (version: IVersion, data: any[], withArray: IWith[], model: IModelService, modelList: ModelListService, database: Knex | Knex.Transaction, handler: HandlerTypes, request: AxeRequest) => Promise<void>;
17
18
  export declare const isBoolean: (value: any) => boolean;
19
+ export declare const getModelCacheConfiguration: (model: IModelService, apiConfig: ICacheConfiguration, versionConfig: ICacheConfiguration | null, handler: string) => ICacheConfiguration;
20
+ export declare const defaultCacheKeyFunction: (req: AxeRequest) => string;
21
+ export declare const toCacheTagKey: (model: IModelService, primaryKeyValue: string, config?: ICacheConfiguration | null) => string;
22
+ export declare const toCacheKey: (context: IContext) => string;
23
+ export declare const putCache: (context: IContext, data: any) => Promise<void>;
24
+ export declare const deleteCacheTagMembers: (key: string) => Promise<void>;
25
+ export declare const cleanRelatedCachedObjectByModel: (model: IModelService, config?: ICacheConfiguration | null) => Promise<void>;
26
+ export declare const clearCacheTags: (tag: string) => Promise<void>;
27
+ export declare const toCachePrefix: (value: string | undefined | null) => string;
28
+ export declare const getForeignKeyValueErrors: (context: IContext) => Promise<(string | null)[]>;
29
+ export declare const getSearchData: (model: IModelService, item: any) => Record<string, any>;
@@ -12,7 +12,8 @@ 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.isBoolean = exports.getRelatedData = exports.addSoftDeleteQuery = exports.filterHiddenFields = exports.serializeData = exports.addForeignKeyQuery = exports.checkPrimaryKeyValueType = exports.getParentColumn = exports.callHooks = exports.getMergedFormData = exports.bindTimestampValues = void 0;
15
+ exports.getSearchData = exports.getForeignKeyValueErrors = exports.toCachePrefix = exports.clearCacheTags = exports.cleanRelatedCachedObjectByModel = exports.deleteCacheTagMembers = exports.putCache = exports.toCacheKey = exports.toCacheTagKey = exports.defaultCacheKeyFunction = exports.getModelCacheConfiguration = exports.isBoolean = exports.getRelatedData = exports.addSoftDeleteQuery = exports.filterHiddenFields = exports.serializeData = exports.getParentIndexQuery = exports.addForeignKeyQuery = exports.checkPrimaryKeyValueType = exports.getParentColumn = exports.callHooks = exports.getMergedFormData = exports.bindTimestampValues = void 0;
16
+ const crypto_1 = __importDefault(require("crypto"));
16
17
  const change_case_1 = require("change-case");
17
18
  const Enums_1 = require("../Enums");
18
19
  const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
@@ -50,18 +51,18 @@ const callHooks = (model, type, params) => __awaiter(void 0, void 0, void 0, fun
50
51
  // we don't await for the events. If the developer uses the transaction and
51
52
  // try to commit something, it would be lost cause the transaction could be
52
53
  // already completed.
53
- const database = (yield Services_1.IoCService.use("Database"));
54
+ const database = yield Services_1.IoCService.use("Database");
54
55
  params.database = database;
55
56
  // Calling the events
56
57
  model.events[type](params);
57
58
  }
58
59
  });
59
60
  exports.callHooks = callHooks;
60
- const getParentColumn = (relation) => {
61
+ const getParentColumn = (model, relation) => {
61
62
  if (!relation) {
62
63
  return null;
63
64
  }
64
- return (0, change_case_1.camelCase)(relation.foreignKey);
65
+ return (0, change_case_1.camelCase)(`${model.name}-${relation.primaryKey}`);
65
66
  };
66
67
  exports.getParentColumn = getParentColumn;
67
68
  const checkPrimaryKeyValueType = (model, value) => {
@@ -75,13 +76,24 @@ const checkPrimaryKeyValueType = (model, value) => {
75
76
  exports.checkPrimaryKeyValueType = checkPrimaryKeyValueType;
76
77
  const addForeignKeyQuery = (request, query, relation, parentModel) => {
77
78
  if (relation && parentModel) {
78
- const parentColumn = (0, exports.getParentColumn)(relation);
79
+ const parentColumn = (0, exports.getParentColumn)(parentModel, relation);
79
80
  if (parentColumn) {
80
81
  query.where(relation.foreignKey, request.params[parentColumn]);
81
82
  }
82
83
  }
83
84
  };
84
85
  exports.addForeignKeyQuery = addForeignKeyQuery;
86
+ const getParentIndexQuery = (request, relation, parentModel) => {
87
+ const result = {};
88
+ if (relation && parentModel) {
89
+ const parentColumn = (0, exports.getParentColumn)(parentModel, relation);
90
+ if (parentColumn) {
91
+ result[relation.foreignKey] = request.params[parentColumn];
92
+ }
93
+ }
94
+ return result;
95
+ };
96
+ exports.getParentIndexQuery = getParentIndexQuery;
85
97
  const getPrimaryOrForeignKeyByRelation = (relation, dataField) => {
86
98
  if (dataField === "primaryKey") {
87
99
  return relation.primaryKey;
@@ -221,6 +233,10 @@ const getRelatedData = (version, data, withArray, model, modelList, database, ha
221
233
  }
222
234
  // Fetching related records by foreignKey and primary key values.
223
235
  let relatedRecords = yield foreignModelQuery.whereIn(searchFieldKey, parentPrimaryKeyValues);
236
+ // Adding related data source to the request tags to set cache tag values
237
+ const { primaryKey } = foreignModel.instance;
238
+ const cacheConfig = foreignModel.getCacheConfiguration(handler);
239
+ request.original.tags.push(...relatedRecords.map((i) => (0, exports.toCacheTagKey)(foreignModel, i[primaryKey], cacheConfig)));
224
240
  // We should serialize related data if there is any serialization function
225
241
  relatedRecords = yield (0, exports.serializeData)(version, relatedRecords, foreignModel.serialize, handler, request);
226
242
  // We should hide hidden fields if there is any
@@ -251,3 +267,184 @@ const isBoolean = (value) => {
251
267
  return false;
252
268
  };
253
269
  exports.isBoolean = isBoolean;
270
+ const getModelCacheConfiguration = (model, apiConfig, versionConfig, handler) => {
271
+ let base = Object.assign(Object.assign({}, constants_1.DEFAULT_CACHE_CONFIGURATION), apiConfig);
272
+ if (model.instance.cache) {
273
+ const data = model.instance.cache;
274
+ if (Array.isArray(data)) {
275
+ const handlerBasedConfigs = data;
276
+ for (const item of handlerBasedConfigs) {
277
+ const isFound = item.handlers.map((i) => i).includes(handler);
278
+ if (isFound) {
279
+ base = Object.assign(Object.assign({}, base), item.cache);
280
+ return base;
281
+ }
282
+ }
283
+ }
284
+ else {
285
+ base = Object.assign(Object.assign({}, base), data);
286
+ return base;
287
+ }
288
+ }
289
+ if (versionConfig) {
290
+ base = Object.assign(Object.assign({}, base), versionConfig);
291
+ }
292
+ return base;
293
+ };
294
+ exports.getModelCacheConfiguration = getModelCacheConfiguration;
295
+ const defaultCacheKeyFunction = (req) => {
296
+ return JSON.stringify({
297
+ url: req.url,
298
+ method: req.method,
299
+ headers: {
300
+ Accept: req.header("Accept"),
301
+ "Accept-Encoding": req.header("Accept-Encoding"),
302
+ "Accept-Language": req.header("Accept-Language"),
303
+ Authorization: req.header("Authorization"),
304
+ Host: req.header("Host"),
305
+ Origin: req.header("Origin"),
306
+ Referer: req.header("Referer"),
307
+ "User-Agent": req.header("User-Agent"),
308
+ },
309
+ });
310
+ };
311
+ exports.defaultCacheKeyFunction = defaultCacheKeyFunction;
312
+ const toCacheTagKey = (model, primaryKeyValue, config) => {
313
+ const prefix = (0, exports.toCachePrefix)(config === null || config === void 0 ? void 0 : config.cachePrefix);
314
+ const tagPrefix = (config === null || config === void 0 ? void 0 : config.tagPrefix) ? config === null || config === void 0 ? void 0 : config.tagPrefix : "";
315
+ const modelName = model.name.toLowerCase();
316
+ return `${prefix}:${tagPrefix}:${modelName}:${primaryKeyValue}`;
317
+ };
318
+ exports.toCacheTagKey = toCacheTagKey;
319
+ const toCacheKey = (context) => {
320
+ const { model, handlerType } = context;
321
+ const config = model.getCacheConfiguration(handlerType);
322
+ const keyData = (config === null || config === void 0 ? void 0 : config.cacheKey)
323
+ ? config.cacheKey(context.req)
324
+ : (0, exports.defaultCacheKeyFunction)(context.req);
325
+ const key = crypto_1.default.createHash("sha256").update(keyData).digest("hex");
326
+ const prefix = (0, exports.toCachePrefix)(config === null || config === void 0 ? void 0 : config.cachePrefix);
327
+ const modelName = model.name.toLowerCase();
328
+ return `${prefix}:${modelName}:${key}`;
329
+ };
330
+ exports.toCacheKey = toCacheKey;
331
+ const putCache = (context, data) => __awaiter(void 0, void 0, void 0, function* () {
332
+ // Getting the correct configuration
333
+ const { model, handlerType } = context;
334
+ const config = model.getCacheConfiguration(handlerType);
335
+ // Check if the cache enable for this handler
336
+ if (!(config === null || config === void 0 ? void 0 : config.enable)) {
337
+ return;
338
+ }
339
+ // Getting the redis service
340
+ const redis = yield Services_1.IoCService.use("Redis");
341
+ // Generating the cache key
342
+ const key = (0, exports.toCacheKey)(context);
343
+ // Setting the tags if the cache configuration of the model has been set as
344
+ // tag-based cache invalidation strategy. Which means, the key cached value
345
+ // can be deleted if the tagged items updated/delete
346
+ if (config.invalidation === Enums_1.CacheStrategies.TagBased) {
347
+ redis.tags(context.req.original.tags, key);
348
+ }
349
+ // Putting the cache data
350
+ redis.set(key, JSON.stringify(data), config.ttl || 1000);
351
+ if (config.responseHeader) {
352
+ context.res.header(config.responseHeader, "Missed");
353
+ }
354
+ // Logging
355
+ Services_1.LogService.debug(`\t🔄 redis.cache(${key},${config.ttl})`);
356
+ });
357
+ exports.putCache = putCache;
358
+ const deleteCacheTagMembers = (key) => __awaiter(void 0, void 0, void 0, function* () {
359
+ const redis = yield Services_1.IoCService.use("Redis");
360
+ const members = yield redis.getTagMemebers(key);
361
+ yield redis.delete(members);
362
+ });
363
+ exports.deleteCacheTagMembers = deleteCacheTagMembers;
364
+ const cleanRelatedCachedObjectByModel = (model, config) => __awaiter(void 0, void 0, void 0, function* () {
365
+ const redis = yield Services_1.IoCService.use("Redis");
366
+ const prefix = (0, exports.toCachePrefix)(config === null || config === void 0 ? void 0 : config.cachePrefix);
367
+ const tagPrefix = (config === null || config === void 0 ? void 0 : config.tagPrefix) ? config === null || config === void 0 ? void 0 : config.tagPrefix : "";
368
+ const modelName = model.name.toLowerCase();
369
+ const searchKey = `${prefix}:${tagPrefix}:${modelName}:*`;
370
+ // Logging
371
+ Services_1.LogService.debug(`\t🔄 redis.cleaByTag(${searchKey})`);
372
+ const { keys } = yield redis.searchTags(searchKey);
373
+ const tasks = keys.map((key) => (0, exports.deleteCacheTagMembers)(key));
374
+ Promise.all(tasks);
375
+ });
376
+ exports.cleanRelatedCachedObjectByModel = cleanRelatedCachedObjectByModel;
377
+ const clearCacheTags = (tag) => __awaiter(void 0, void 0, void 0, function* () {
378
+ const redis = yield Services_1.IoCService.use("Redis");
379
+ const members = yield redis.getTagMemebers(tag);
380
+ if (members.length > 0) {
381
+ yield redis.delete(members);
382
+ }
383
+ });
384
+ exports.clearCacheTags = clearCacheTags;
385
+ const toCachePrefix = (value) => {
386
+ return value ? value : "";
387
+ };
388
+ exports.toCachePrefix = toCachePrefix;
389
+ const validateForeignValues = (database, version, relation, value) => __awaiter(void 0, void 0, void 0, function* () {
390
+ if (!value) {
391
+ return true;
392
+ }
393
+ const foreignModel = version.modelList
394
+ .get()
395
+ .find((model) => model.name === relation.model);
396
+ if (!foreignModel) {
397
+ throw new Error(`The model not found: ${relation.model}`);
398
+ }
399
+ const found = yield database(foreignModel.instance.table)
400
+ .where(foreignModel.instance.primaryKey, value)
401
+ .first();
402
+ return !!found;
403
+ });
404
+ const getForeignKeyValueErrors = (context) => __awaiter(void 0, void 0, void 0, function* () {
405
+ const { model, database, version } = context;
406
+ // Getting all foreign rules.
407
+ const foreignRelations = model.relations.filter((relation) => relation.type === Enums_1.Relationships.HAS_ONE);
408
+ const tasks = [];
409
+ for (const relation of foreignRelations) {
410
+ const value = context.formData[relation.foreignKey];
411
+ tasks.push({
412
+ data: {
413
+ value,
414
+ relation,
415
+ },
416
+ promise: validateForeignValues(database, version, relation, value),
417
+ });
418
+ }
419
+ const results = yield Promise.all(tasks.map((promise) => promise.promise));
420
+ return results
421
+ .map((result, index) => {
422
+ if (result) {
423
+ return null;
424
+ }
425
+ const data = tasks[index].data;
426
+ return `Invalid value: ${data.relation.foreignKey} = ${data.value}`;
427
+ })
428
+ .filter((error) => error);
429
+ });
430
+ exports.getForeignKeyValueErrors = getForeignKeyValueErrors;
431
+ const getSearchData = (model, item) => {
432
+ const result = {};
433
+ if (model.instance.search) {
434
+ for (const field of model.instance.search) {
435
+ result[field] = item[field];
436
+ }
437
+ }
438
+ // If there is a deleted at column, we should put it to the index data
439
+ if (model.instance.deletedAtColumn) {
440
+ result[model.instance.deletedAtColumn] =
441
+ item[model.instance.deletedAtColumn];
442
+ }
443
+ // We should add the parent relations if there is any
444
+ const relations = model.relations.filter((relation) => relation.type === Enums_1.Relationships.HAS_ONE);
445
+ for (const relation of relations) {
446
+ result[relation.foreignKey] = item[relation.foreignKey];
447
+ }
448
+ return result;
449
+ };
450
+ exports.getSearchData = getSearchData;
@@ -1,3 +1,6 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="express" />
1
3
  import { IncomingMessage, ServerResponse } from "http";
2
- declare const _default: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
4
+ import { NextFunction } from "connect";
5
+ declare const _default: (request: IncomingMessage, response: ServerResponse, next: NextFunction) => Promise<void>;
3
6
  export default _default;
@@ -15,30 +15,49 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const Services_1 = require("../Services");
16
16
  const URLService_1 = __importDefault(require("../Services/URLService"));
17
17
  const ConverterService_1 = require("../Services/ConverterService");
18
- const api = Services_1.APIService.getInstance();
19
18
  const return404 = (response) => {
20
19
  response.statusCode = 404;
21
20
  response.write(JSON.stringify({ error: "Resource not found" }));
22
21
  response.end();
23
22
  };
24
- const callPhases = (phases, pack, match, trx, axeResponse) => __awaiter(void 0, void 0, void 0, function* () {
25
- for (const phase of phases) {
23
+ exports.default = (request, response, next) => __awaiter(void 0, void 0, void 0, function* () {
24
+ const api = Services_1.APIService.getInstance();
25
+ Services_1.LogService.debug(`📥 ${request.method} ${request.url}`);
26
+ const { axeRequest, axeResponse } = (0, ConverterService_1.toAxeRequestResponsePair)(request, response);
27
+ const match = URLService_1.default.match(axeRequest);
28
+ if (!match) {
29
+ Services_1.LogService.warn(`The URL is not matched! ${request.method} ${request.url}`);
30
+ return return404(response);
31
+ }
32
+ // We should set the params
33
+ axeRequest.params = match.params;
34
+ const database = yield Services_1.IoCService.use("Database");
35
+ // Prepare the database by the transaction option
36
+ let trx = null;
37
+ if (match.hasTransaction) {
38
+ Services_1.LogService.info("\t🛢 DBTransaction:created()");
39
+ trx = yield database.transaction();
40
+ }
41
+ const context = Object.assign(Object.assign({}, match.data), { params: match.params, api, req: axeRequest, res: axeResponse, isTransactionOpen: match.hasTransaction, database: match.hasTransaction && trx ? trx : database });
42
+ response.setHeader("Content-Type", "application/json");
43
+ response.setHeader("x-powered-by", "Axe API");
44
+ for (const phase of match.phases) {
26
45
  // If there is an non-async phase, it should be an Event function
27
46
  if (phase.isAsync === false) {
28
- Services_1.LogService.debug(`\t${phase.name}()`);
29
- yield phase.callback(pack);
47
+ Services_1.LogService.debug(`\t🔄 ${phase.name}()`);
48
+ phase.callback(context);
30
49
  continue;
31
50
  }
32
51
  // Middleware and hook calls
33
52
  try {
34
- Services_1.LogService.debug(`\t${phase.name}()`);
35
- yield phase.callback(pack);
53
+ Services_1.LogService.debug(`\t🔄 ${phase.name}()`);
54
+ yield phase.callback(context);
36
55
  }
37
56
  catch (error) {
38
- Services_1.LogService.error(`\t${error.message} ${phase.callback}`);
57
+ Services_1.LogService.error(error);
39
58
  // Rollback transaction
40
59
  if (match.hasTransaction && trx) {
41
- Services_1.LogService.warn("\tDB transaction rollback");
60
+ Services_1.LogService.info("\t🛢 DBTransaction:rollback()");
42
61
  trx.rollback();
43
62
  }
44
63
  if (error.type === "ApiError") {
@@ -47,53 +66,30 @@ const callPhases = (phases, pack, match, trx, axeResponse) => __awaiter(void 0,
47
66
  .status(apiError.status)
48
67
  .json({ error: apiError.message });
49
68
  }
50
- // TODO: We need an error handler.
51
- axeResponse.status(500).json({ error: error.toString() });
69
+ next(error);
52
70
  break;
53
71
  }
54
72
  // If the response is not created, we should go to the next phase
55
- if (pack.res.isResponded() === false) {
73
+ if (context.res.isResponded() === false) {
56
74
  continue;
57
75
  }
58
76
  // If the response is an error, and we have an active transaction,
59
77
  // we should rollback it before the HTTP request end.
60
- if (pack.res.statusCode() >= 400 && pack.res.statusCode() < 599) {
78
+ if (context.res.statusCode() >= 400 && context.res.statusCode() < 599) {
61
79
  if (match.hasTransaction && trx) {
62
- Services_1.LogService.warn("\tDB transaction rollback");
80
+ Services_1.LogService.info("\t🛢 DBTransaction:rollback()");
63
81
  trx.rollback();
64
82
  }
65
- Services_1.LogService.debug(`\tResponse ${pack.res.statusCode()}`);
83
+ Services_1.LogService.debug(`\tResponse ${context.res.statusCode()}`);
66
84
  break;
67
85
  }
68
- // If there is a valid transaction, we should commit it
86
+ // We should commit the transaction if there is any
69
87
  if (match.hasTransaction && trx) {
70
- Services_1.LogService.warn("\tDB transaction commit");
88
+ Services_1.LogService.info("\t🛢 DBTransaction:commit()");
71
89
  trx.commit();
72
90
  }
73
- Services_1.LogService.debug(`\tResponse ${pack.res.statusCode()}`);
91
+ Services_1.LogService.debug(`\t🟢 Response ${context.res.statusCode()}`);
74
92
  // We should brake the for-loop
75
93
  break;
76
94
  }
77
95
  });
78
- exports.default = (request, response) => __awaiter(void 0, void 0, void 0, function* () {
79
- Services_1.LogService.debug(`${request.method} ${request.url}`);
80
- const { axeRequest, axeResponse } = (0, ConverterService_1.toAxeRequestResponsePair)(request, response);
81
- const match = URLService_1.default.match(axeRequest);
82
- if (!match) {
83
- Services_1.LogService.warn(`The URL is not matched! ${request.method} ${request.url}`);
84
- return return404(response);
85
- }
86
- // We should set the params
87
- axeRequest.params = match.params;
88
- const database = (yield Services_1.IoCService.use("Database"));
89
- // Prepare the database by the transaction option
90
- let trx = null;
91
- if (match.hasTransaction) {
92
- Services_1.LogService.warn("\tDB transaction created");
93
- trx = yield database.transaction();
94
- }
95
- const pack = Object.assign(Object.assign({}, match.data), { params: match.params, api, req: axeRequest, res: axeResponse, database: match.hasTransaction && trx ? trx : database });
96
- response.setHeader("Content-Type", "application/json");
97
- response.setHeader("x-powered-by", "Axe API");
98
- yield callPhases(match.phases, pack, match, trx, axeResponse);
99
- });
@@ -8,17 +8,18 @@ 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
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const CLOUD_FRONT_DOMAIN = "https://dw7lgbuj348m4.cloudfront.net/v1";
15
+ const SwaggerBuilder_1 = __importDefault(require("../Builders/SwaggerBuilder"));
16
+ const Services_1 = require("../Services");
13
17
  exports.default = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
14
18
  try {
15
- const result = yield fetch(`${CLOUD_FRONT_DOMAIN}/index.html`);
16
- const content = (yield result.text())
17
- .replaceAll(`src="`, `src="${CLOUD_FRONT_DOMAIN}`)
18
- .replaceAll(`href="`, `href="${CLOUD_FRONT_DOMAIN}`);
19
- res.send(content);
19
+ res.json(yield (0, SwaggerBuilder_1.default)());
20
20
  }
21
21
  catch (error) {
22
- res.send("404");
22
+ Services_1.LogService.error(error);
23
+ res.status(500).json({ error: error.message });
23
24
  }
24
25
  });