axe-api 1.0.0-rc4 → 1.0.0-rc6

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.
@@ -14,40 +14,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const Services_1 = require("../Services");
16
16
  const URLService_1 = __importDefault(require("../Services/URLService"));
17
- const AxeRequest_1 = __importDefault(require("../Services/AxeRequest"));
18
- const AxeResponse_1 = __importDefault(require("../Services/AxeResponse"));
17
+ const ConverterService_1 = require("../Services/ConverterService");
19
18
  const api = Services_1.APIService.getInstance();
20
19
  const return404 = (response) => {
21
20
  response.statusCode = 404;
22
21
  response.write(JSON.stringify({ error: "Resource not found" }));
23
22
  response.end();
24
23
  };
25
- exports.default = (request, response) => __awaiter(void 0, void 0, void 0, function* () {
26
- Services_1.LogService.debug(`${request.method} ${request.url}`);
27
- const axeRequest = new AxeRequest_1.default(request);
28
- const match = URLService_1.default.match(axeRequest);
29
- const axeResponse = new AxeResponse_1.default(response, axeRequest.currentLanguage);
30
- if (!match) {
31
- Services_1.LogService.warn(`The URL is not matched! ${request.method} ${request.url}`);
32
- return return404(response);
33
- }
34
- if (match.customHandler) {
35
- match.customHandler(axeRequest, axeResponse);
36
- return;
37
- }
38
- // We should set the params
39
- axeRequest.params = match.params;
40
- const database = (yield Services_1.IoCService.use("Database"));
41
- // Prepare the database by the transaction option
42
- let trx = null;
43
- if (match.hasTransaction) {
44
- Services_1.LogService.warn("\tDB transaction created");
45
- trx = yield database.transaction();
46
- }
47
- const pack = Object.assign(Object.assign({}, match.data), { params: match.params, api, req: axeRequest, res: axeResponse, database: match.hasTransaction && trx ? trx : database });
48
- response.setHeader("Content-Type", "application/json");
49
- response.setHeader("x-powered-by", "Axe API");
50
- for (const phase of match.phases) {
24
+ const callPhases = (phases, pack, match, trx, axeResponse) => __awaiter(void 0, void 0, void 0, function* () {
25
+ for (const phase of phases) {
51
26
  // If there is an non-async phase, it should be an Event function
52
27
  if (phase.isAsync === false) {
53
28
  Services_1.LogService.debug(`\t${phase.name}()`);
@@ -100,3 +75,25 @@ exports.default = (request, response) => __awaiter(void 0, void 0, void 0, funct
100
75
  break;
101
76
  }
102
77
  });
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
+ });
@@ -4,7 +4,7 @@ import { Knex } from "knex";
4
4
  import { Column } from "knex-schema-inspector/lib/types/column";
5
5
  import { HandlerTypes, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes, QueryFeature, QueryFeatureType } from "./Enums";
6
6
  import Model from "./Model";
7
- import { AdaptorTypes, PhaseFunction, SerializationFunction } from "./Types";
7
+ import { AdaptorTypes, HandlerFunction, HookFunctions, MiddlewareFunction, StepTypes, PhaseFunction, SerializationFunction } from "./Types";
8
8
  import { ModelListService, QueryService } from "./Services";
9
9
  import AxeRequest from "./Services/AxeRequest";
10
10
  import AxeResponse from "./Services/AxeResponse";
@@ -111,7 +111,7 @@ export interface IGeneralHooks {
111
111
  }
112
112
  export interface IHandlerBaseMiddleware {
113
113
  handler: HandlerTypes[];
114
- middleware: PhaseFunction;
114
+ middleware: StepTypes;
115
115
  }
116
116
  export interface IMethodBaseConfig {
117
117
  [HttpMethods.POST]?: string[];
@@ -128,8 +128,8 @@ export interface IModelService {
128
128
  relations: IRelation[];
129
129
  columns: IColumn[];
130
130
  columnNames: string[];
131
- hooks: Record<HookFunctionTypes, PhaseFunction>;
132
- events: Record<HookFunctionTypes, PhaseFunction>;
131
+ hooks: HookFunctions;
132
+ events: HookFunctions;
133
133
  isRecursive: boolean;
134
134
  children: IModelService[];
135
135
  queryLimits: IQueryLimitConfig[];
@@ -229,4 +229,12 @@ export interface IPhaseDefinition {
229
229
  isAsync: boolean;
230
230
  callback: PhaseFunction;
231
231
  }
232
+ export interface AxeRequestResponsePair {
233
+ axeRequest: AxeRequest;
234
+ axeResponse: AxeResponse;
235
+ }
236
+ export interface MiddlewareResolution {
237
+ middlewares: MiddlewareFunction[];
238
+ handler: HandlerFunction;
239
+ }
232
240
  export {};
@@ -1,13 +1,13 @@
1
- import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBaseMiddleware, IHandlerBasedTransactionConfig, IQueryLimitConfig } from "./Interfaces";
1
+ import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBasedTransactionConfig, IQueryLimitConfig } from "./Interfaces";
2
2
  import { HandlerTypes, HttpMethods } from "./Enums";
3
- import { FieldList, ModelValidation, PhaseFunction } from "./Types";
3
+ import { FieldList, ModelMiddlewareDefinition, StepTypes, ModelValidation } from "./Types";
4
4
  declare class Model {
5
5
  get primaryKey(): string;
6
6
  get table(): string;
7
7
  get fillable(): FieldList | IMethodBaseConfig;
8
8
  get validations(): IMethodBaseValidations | ModelValidation;
9
9
  get handlers(): HandlerTypes[];
10
- get middlewares(): PhaseFunction[] | IHandlerBaseMiddleware[] | IHandlerBaseMiddleware;
10
+ get middlewares(): ModelMiddlewareDefinition;
11
11
  get hiddens(): FieldList;
12
12
  get createdAtColumn(): string | null;
13
13
  get updatedAtColumn(): string | null;
@@ -17,7 +17,7 @@ declare class Model {
17
17
  get limits(): Array<IQueryLimitConfig[]>;
18
18
  getFillableFields(methodType: HttpMethods): string[];
19
19
  getValidationRules(methodType: HttpMethods): ModelValidation | null;
20
- getMiddlewares(handlerType: HandlerTypes): PhaseFunction[];
20
+ getMiddlewares(handlerType: HandlerTypes): StepTypes[];
21
21
  hasMany(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
22
22
  hasOne(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
23
23
  belongsTo(relatedModel: string, primaryKey: string, foreignKey: string): IRelation;
@@ -1,14 +1,14 @@
1
1
  import connect from "connect";
2
- import { HandlerFunction } from "../Types";
2
+ import { DynamicFunctionType } from "../Types";
3
3
  declare class App {
4
4
  private connect;
5
5
  constructor();
6
6
  get instance(): connect.Server;
7
7
  use(middleware: connect.NextHandleFunction): void;
8
- get(url: string, handler: HandlerFunction): void;
9
- post(url: string, handler: HandlerFunction): void;
10
- put(url: string, handler: HandlerFunction): void;
11
- patch(url: string, handler: HandlerFunction): void;
12
- delete(url: string, handler: HandlerFunction): void;
8
+ get(url: string, ...args: DynamicFunctionType): void;
9
+ post(url: string, ...args: DynamicFunctionType): void;
10
+ put(url: string, ...args: DynamicFunctionType): void;
11
+ patch(url: string, ...args: DynamicFunctionType): void;
12
+ delete(url: string, ...args: DynamicFunctionType): void;
13
13
  }
14
14
  export default App;
@@ -32,6 +32,7 @@ const URLService_1 = __importDefault(require("./URLService"));
32
32
  const LogService_1 = __importDefault(require("./LogService"));
33
33
  const RateLimit_1 = __importStar(require("../Middlewares/RateLimit"));
34
34
  const APIService_1 = __importDefault(require("./APIService"));
35
+ const ConverterService_1 = require("./ConverterService");
35
36
  class App {
36
37
  constructor() {
37
38
  var _a;
@@ -55,20 +56,25 @@ class App {
55
56
  this.connect.use(middleware);
56
57
  LogService_1.default.debug(`New middleware: ${middleware.name || "anonymous"}()`);
57
58
  }
58
- get(url, handler) {
59
- URLService_1.default.addHandler("GET", url, handler);
59
+ get(url, ...args) {
60
+ const { handler, middlewares } = (0, ConverterService_1.resolveMiddlewares)(args);
61
+ URLService_1.default.addHandler("GET", url, handler, middlewares);
60
62
  }
61
- post(url, handler) {
62
- URLService_1.default.addHandler("POST", url, handler);
63
+ post(url, ...args) {
64
+ const { handler, middlewares } = (0, ConverterService_1.resolveMiddlewares)(args);
65
+ URLService_1.default.addHandler("POST", url, handler, middlewares);
63
66
  }
64
- put(url, handler) {
65
- URLService_1.default.addHandler("PUT", url, handler);
67
+ put(url, ...args) {
68
+ const { handler, middlewares } = (0, ConverterService_1.resolveMiddlewares)(args);
69
+ URLService_1.default.addHandler("PUT", url, handler, middlewares);
66
70
  }
67
- patch(url, handler) {
68
- URLService_1.default.addHandler("PATCH", url, handler);
71
+ patch(url, ...args) {
72
+ const { handler, middlewares } = (0, ConverterService_1.resolveMiddlewares)(args);
73
+ URLService_1.default.addHandler("PATCH", url, handler, middlewares);
69
74
  }
70
- delete(url, handler) {
71
- URLService_1.default.addHandler("DELETE", url, handler);
75
+ delete(url, ...args) {
76
+ const { handler, middlewares } = (0, ConverterService_1.resolveMiddlewares)(args);
77
+ URLService_1.default.addHandler("DELETE", url, handler, middlewares);
72
78
  }
73
79
  }
74
80
  exports.default = App;
@@ -0,0 +1,9 @@
1
+ import { IncomingMessage, ServerResponse } from "http";
2
+ import { AxeRequestResponsePair, MiddlewareResolution } from "../Interfaces";
3
+ import { DynamicFunctionType, PhaseFunction, StepTypes } from "src/Types";
4
+ export declare const toAxeRequestResponsePair: (request: IncomingMessage, response: ServerResponse) => AxeRequestResponsePair;
5
+ export declare const resolveMiddlewares: (args: DynamicFunctionType) => MiddlewareResolution;
6
+ export declare const isMiddlewareFunction: (callback: any) => boolean;
7
+ export declare const isHandlerFunction: (callback: any) => boolean;
8
+ export declare const isPhaseFunction: (callback: any) => boolean;
9
+ export declare const toPhaseFunction: (callback: StepTypes) => PhaseFunction;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.toPhaseFunction = exports.isPhaseFunction = exports.isHandlerFunction = exports.isMiddlewareFunction = exports.resolveMiddlewares = exports.toAxeRequestResponsePair = void 0;
7
+ const util_1 = require("util");
8
+ const AxeRequest_1 = __importDefault(require("./AxeRequest"));
9
+ const AxeResponse_1 = __importDefault(require("./AxeResponse"));
10
+ const toAxeRequestResponsePair = (request, response) => {
11
+ const axeRequest = new AxeRequest_1.default(request);
12
+ const axeResponse = new AxeResponse_1.default(response, axeRequest.currentLanguage);
13
+ return {
14
+ axeRequest,
15
+ axeResponse,
16
+ };
17
+ };
18
+ exports.toAxeRequestResponsePair = toAxeRequestResponsePair;
19
+ const resolveMiddlewares = (args) => {
20
+ const middlewares = args.slice(0, -1);
21
+ const handler = args.at(-1);
22
+ return {
23
+ middlewares,
24
+ handler,
25
+ };
26
+ };
27
+ exports.resolveMiddlewares = resolveMiddlewares;
28
+ const isMiddlewareFunction = (callback) => {
29
+ return callback.length === 3;
30
+ };
31
+ exports.isMiddlewareFunction = isMiddlewareFunction;
32
+ const isHandlerFunction = (callback) => {
33
+ return callback.length === 2;
34
+ };
35
+ exports.isHandlerFunction = isHandlerFunction;
36
+ const isPhaseFunction = (callback) => {
37
+ return callback.length === 1;
38
+ };
39
+ exports.isPhaseFunction = isPhaseFunction;
40
+ const toPhaseFunction = (callback) => {
41
+ if ((0, exports.isMiddlewareFunction)(callback)) {
42
+ return (0, util_1.promisify)((context, next) => callback(context.req.original, context.res.original, next));
43
+ }
44
+ if ((0, exports.isHandlerFunction)(callback)) {
45
+ return (context) => callback(context.req, context.res);
46
+ }
47
+ return callback;
48
+ };
49
+ exports.toPhaseFunction = toPhaseFunction;
@@ -1,15 +1,15 @@
1
1
  import { HookFunctionTypes, Extensions } from "../Enums";
2
2
  import { IColumn, IModelService, IQueryLimitConfig, IRelation } from "../Interfaces";
3
3
  import Model from "./../Model";
4
- import { PhaseFunction, SerializationFunction } from "../Types";
4
+ import { HookFunctions, PhaseFunction, SerializationFunction } from "../Types";
5
5
  declare class ModelService implements IModelService {
6
6
  name: string;
7
7
  instance: Model;
8
8
  relations: IRelation[];
9
9
  columns: IColumn[];
10
10
  columnNames: string[];
11
- hooks: Record<HookFunctionTypes, PhaseFunction>;
12
- events: Record<HookFunctionTypes, PhaseFunction>;
11
+ hooks: HookFunctions;
12
+ events: HookFunctions;
13
13
  children: IModelService[];
14
14
  isRecursive: boolean;
15
15
  queryLimits: IQueryLimitConfig[];
@@ -1,4 +1,4 @@
1
- import { HandlerFunction, PhaseFunction } from "src/Types";
1
+ import { HandlerFunction, MiddlewareFunction, StepTypes } from "../Types";
2
2
  import { IPhaseDefinition, IRouteData } from "../Interfaces";
3
3
  import AxeRequest from "./AxeRequest";
4
4
  interface Pair {
@@ -12,8 +12,8 @@ interface Pair {
12
12
  }
13
13
  declare class URLService {
14
14
  private static urls;
15
- static add(method: string, pattern: string, data: IRouteData, middlewares: PhaseFunction[]): Promise<void>;
16
- static addHandler(method: string, pattern: string, customHandler: HandlerFunction): Promise<void>;
15
+ static add(method: string, pattern: string, data: IRouteData, middlewares: StepTypes[]): Promise<void>;
16
+ static addHandler(method: string, pattern: string, customHandler: HandlerFunction, middlewares: MiddlewareFunction[]): Promise<void>;
17
17
  static match(request: AxeRequest): {
18
18
  params: any;
19
19
  method: string;
@@ -12,10 +12,12 @@ 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
+ const util_1 = require("util");
15
16
  const constants_1 = require("../constants");
16
17
  const Resolvers_1 = require("../Resolvers");
17
18
  const Enums_1 = require("../Enums");
18
19
  const LogService_1 = __importDefault(require("./LogService"));
20
+ const ConverterService_1 = require("./ConverterService");
19
21
  const check = (url, pattern) => {
20
22
  // Escape special characters in the pattern and replace parameter placeholders with regular expression groups
21
23
  const regexPattern = new RegExp("^" + pattern.replace(/:[a-zA-Z0-9_]+/g, "([a-zA-Z0-9_-]+)") + "$");
@@ -63,17 +65,26 @@ class URLService {
63
65
  });
64
66
  });
65
67
  }
66
- static addHandler(method, pattern, customHandler) {
68
+ static addHandler(method, pattern, customHandler, middlewares) {
67
69
  return __awaiter(this, void 0, void 0, function* () {
68
70
  LogService_1.default.info(`${method} ${pattern}`);
69
- const phases = this.getDefaultPhases([]);
71
+ const phases = middlewares.map((middleware) => {
72
+ return {
73
+ isAsync: false,
74
+ name: `middleware:test`,
75
+ callback: (pack) => __awaiter(this, void 0, void 0, function* () {
76
+ const caller = (0, util_1.promisify)((pack, next) => middleware(pack.req.original, pack.res.original, next));
77
+ yield caller(pack);
78
+ }),
79
+ };
80
+ });
70
81
  const hasTransaction = false;
71
82
  phases.push({
72
83
  isAsync: false,
73
84
  name: "customHandler",
74
- callback: (pack) => {
85
+ callback: (pack) => __awaiter(this, void 0, void 0, function* () {
75
86
  customHandler(pack.req, pack.res);
76
- },
87
+ }),
77
88
  });
78
89
  this.urls.push({
79
90
  method,
@@ -107,14 +118,15 @@ class URLService {
107
118
  return this.urls;
108
119
  }
109
120
  static getDefaultPhases(middlewares) {
110
- // Creating the phase array
121
+ // We should convert to all StepTypes functions to PhaseFunctions
122
+ const callbacks = middlewares.map(ConverterService_1.toPhaseFunction);
111
123
  const phases = [
112
124
  // Internal middlewares
113
- ...middlewares.map((middleware) => {
125
+ ...callbacks.map((callback) => {
114
126
  return {
115
127
  isAsync: true,
116
- name: `middleware:${middleware.name || "anonymous"}`,
117
- callback: middleware,
128
+ name: `middleware:${callback.name || "anonymous"}`,
129
+ callback,
118
130
  };
119
131
  }),
120
132
  ];
@@ -1,10 +1,20 @@
1
- import { IRequestPack } from "./Interfaces";
1
+ /// <reference types="node" />
2
+ /// <reference types="express" />
3
+ import { IncomingMessage, ServerResponse } from "http";
4
+ import { IHandlerBaseMiddleware, IRequestPack } from "./Interfaces";
2
5
  import AxeRequest from "./Services/AxeRequest";
3
6
  import AxeResponse from "./Services/AxeResponse";
4
- export type SerializationFunction = (item: any, request: AxeRequest) => any;
7
+ import { HookFunctionTypes } from "./Enums";
5
8
  export type ModelValidation = Record<string, string>;
6
9
  export type FieldList = string[];
7
- export type PhaseFunction = (pack: IRequestPack) => void | Promise<void>;
8
- export type NextFunction = () => void;
9
- export type HandlerFunction = (request: AxeRequest, response: AxeResponse) => Promise<void> | void;
10
+ export type DefaultResponse = Promise<void> | void | undefined;
10
11
  export type AdaptorTypes = "redis" | "memory";
12
+ export type MiddlewareFunction = (req: IncomingMessage, res: ServerResponse, next: NextFunction) => DefaultResponse;
13
+ export type HandlerFunction = (request: AxeRequest, response: AxeResponse) => DefaultResponse;
14
+ export type PhaseFunction = (pack: IRequestPack) => DefaultResponse;
15
+ export type SerializationFunction = (item: any, request: AxeRequest) => any;
16
+ export type HookFunctions = Record<HookFunctionTypes, PhaseFunction>;
17
+ export type NextFunction = (error: any) => void;
18
+ export type DynamicFunctionType = (MiddlewareFunction | HandlerFunction)[];
19
+ export type StepTypes = MiddlewareFunction | HandlerFunction | PhaseFunction;
20
+ export type ModelMiddlewareDefinition = Array<StepTypes | IHandlerBaseMiddleware>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axe-api",
3
- "version": "1.0.0-rc4",
3
+ "version": "1.0.0-rc6",
4
4
  "description": "AXE API is a simple tool to create Rest APIs quickly.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",