axe-api 1.5.0-rc-1 → 1.5.0-rc-2

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.
package/build/index.d.ts CHANGED
@@ -4,8 +4,8 @@ import ApiError from "./src/Exceptions/ApiError";
4
4
  import RedisAdaptor from "./src/Middlewares/RateLimit/RedisAdaptor";
5
5
  import { DEFAULT_HANDLERS, DEFAULT_VERSION_CONFIG } from "./src/constants";
6
6
  import { IoCService, allow, deny, App, AxeRequest, AxeResponse } from "./src/Services";
7
- import { rateLimit, createRateLimitMiddleware } from "./src/Middlewares/RateLimit";
7
+ import { rateLimit, createRateLimitter } from "./src/Middlewares/RateLimit";
8
8
  export * from "./src/Enums";
9
9
  export * from "./src/Interfaces";
10
10
  export * from "./src/Types";
11
- export { App, AxeRequest, AxeResponse, Server, Model, ApiError, RedisAdaptor, DEFAULT_HANDLERS, DEFAULT_VERSION_CONFIG, IoCService, allow, deny, rateLimit, createRateLimitMiddleware, };
11
+ export { App, AxeRequest, AxeResponse, Server, Model, ApiError, RedisAdaptor, DEFAULT_HANDLERS, DEFAULT_VERSION_CONFIG, IoCService, allow, deny, rateLimit, createRateLimitter, };
package/build/index.js CHANGED
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.createRateLimitMiddleware = exports.rateLimit = exports.deny = exports.allow = exports.IoCService = exports.DEFAULT_VERSION_CONFIG = exports.DEFAULT_HANDLERS = exports.RedisAdaptor = exports.ApiError = exports.Model = exports.Server = exports.AxeResponse = exports.AxeRequest = exports.App = void 0;
20
+ exports.createRateLimitter = exports.rateLimit = exports.deny = exports.allow = exports.IoCService = exports.DEFAULT_VERSION_CONFIG = exports.DEFAULT_HANDLERS = exports.RedisAdaptor = exports.ApiError = exports.Model = exports.Server = exports.AxeResponse = exports.AxeRequest = exports.App = void 0;
21
21
  const Server_1 = __importDefault(require("./src/Server"));
22
22
  exports.Server = Server_1.default;
23
23
  const Model_1 = __importDefault(require("./src/Model"));
@@ -38,7 +38,7 @@ Object.defineProperty(exports, "AxeRequest", { enumerable: true, get: function (
38
38
  Object.defineProperty(exports, "AxeResponse", { enumerable: true, get: function () { return Services_1.AxeResponse; } });
39
39
  const RateLimit_1 = require("./src/Middlewares/RateLimit");
40
40
  Object.defineProperty(exports, "rateLimit", { enumerable: true, get: function () { return RateLimit_1.rateLimit; } });
41
- Object.defineProperty(exports, "createRateLimitMiddleware", { enumerable: true, get: function () { return RateLimit_1.createRateLimitMiddleware; } });
41
+ Object.defineProperty(exports, "createRateLimitter", { enumerable: true, get: function () { return RateLimit_1.createRateLimitter; } });
42
42
  __exportStar(require("./src/Enums"), exports);
43
43
  __exportStar(require("./src/Interfaces"), exports);
44
44
  __exportStar(require("./src/Types"), exports);
@@ -53,11 +53,9 @@ exports.default = (request, response, next) => __awaiter(void 0, void 0, void 0,
53
53
  }
54
54
  const validator = yield Services_1.IoCService.use("Validator");
55
55
  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, validator });
56
- if (!response.isResponded) {
57
- response.setHeader("Content-Type", "application/json");
58
- if (api.config.disableXPoweredByHeader === false) {
59
- response.setHeader("x-powered-by", "Axe API");
60
- }
56
+ response.setHeader("Content-Type", "application/json");
57
+ if (api.config.disableXPoweredByHeader === false) {
58
+ response.setHeader("x-powered-by", "Axe API");
61
59
  }
62
60
  for (const phase of match.phases) {
63
61
  // If there is an non-async phase, it should be an Event function
@@ -44,6 +44,11 @@ export interface IQueryConfig {
44
44
  limits: Array<IQueryLimitConfig[]>;
45
45
  defaults?: IQueryDefaultConfig;
46
46
  }
47
+ export interface IRateLimitMiddleware {
48
+ name: string;
49
+ clientKey: string;
50
+ setResponseHeaders?: boolean;
51
+ }
47
52
  export interface IRateLimitOptions {
48
53
  maxRequests: number;
49
54
  windowInSeconds: number;
@@ -1,7 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "http";
2
- import { AxeConfig, IRateLimitOptions, IContext } from "../../Interfaces";
2
+ import { AxeConfig, IRateLimitOptions, IContext, IRateLimitMiddleware } from "../../Interfaces";
3
3
  export declare const setupRateLimitAdaptors: (config: AxeConfig) => Promise<void>;
4
- export declare const createRateLimitMiddleware: (req: IncomingMessage, res: ServerResponse, next: () => void, key: string, options: IRateLimitOptions) => Promise<void>;
5
4
  /**
6
5
  * Add a rate limit with the `IRateLimitOptions`
7
6
  *
@@ -20,5 +19,17 @@ export declare const createRateLimitMiddleware: (req: IncomingMessage, res: Serv
20
19
  * }
21
20
  */
22
21
  export declare const rateLimit: (options?: IRateLimitOptions) => (context: IContext) => Promise<void>;
22
+ /**
23
+ * Create a rate-limitter middleware (a connect middleware) with a middleware
24
+ * configurations
25
+ *
26
+ * @param middleware IRateLimitMiddleware
27
+ * @param options IRateLimitOptions
28
+ * @param req IncomingMessage
29
+ * @param res ServerResponse
30
+ * @param next NextFunction
31
+ * @returns
32
+ */
33
+ export declare const createRateLimitter: (middleware: IRateLimitMiddleware, options: IRateLimitOptions, req: IncomingMessage, res: ServerResponse, next: any) => Promise<any>;
23
34
  declare const _default: (req: IncomingMessage, res: ServerResponse, next: any) => Promise<any>;
24
35
  export default _default;
@@ -12,7 +12,7 @@ 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.rateLimit = exports.createRateLimitMiddleware = exports.setupRateLimitAdaptors = void 0;
15
+ exports.createRateLimitter = exports.rateLimit = exports.setupRateLimitAdaptors = void 0;
16
16
  const AdaptorFactory_1 = __importDefault(require("./AdaptorFactory"));
17
17
  const Services_1 = require("../../Services");
18
18
  const nanoid_1 = require("nanoid");
@@ -70,25 +70,6 @@ const setupRateLimitAdaptors = (config) => __awaiter(void 0, void 0, void 0, fun
70
70
  adaptor = yield (0, AdaptorFactory_1.default)(((_a = config.rateLimit) === null || _a === void 0 ? void 0 : _a.adaptor) || "memory");
71
71
  });
72
72
  exports.setupRateLimitAdaptors = setupRateLimitAdaptors;
73
- const createRateLimitMiddleware = (req, res, next, key, options) => __awaiter(void 0, void 0, void 0, function* () {
74
- // Checking the rate limit
75
- const isAllowed = yield checkRateLimit(key, options);
76
- // Setting the headers
77
- res.setHeader("X-RateLimit-Limit", isAllowed.limit);
78
- res.setHeader("X-RateLimit-Remaining", isAllowed.remaining);
79
- // Sending an error message if there is an error
80
- if (isAllowed.success === false) {
81
- Services_1.LogService.warn(`Rate limit exceeded: ${req.url}`);
82
- res.statusCode = Enums_1.StatusCodes.TOO_MANY_REQUESTS;
83
- res.write(JSON.stringify({
84
- error: "Rate limit exceeded.",
85
- }));
86
- res.isResponded = true;
87
- res.end();
88
- }
89
- next();
90
- });
91
- exports.createRateLimitMiddleware = createRateLimitMiddleware;
92
73
  /**
93
74
  * Add a rate limit with the `IRateLimitOptions`
94
75
  *
@@ -109,21 +90,60 @@ exports.createRateLimitMiddleware = createRateLimitMiddleware;
109
90
  const rateLimit = (options) => {
110
91
  // For each model middleware, we should use a different ID for the cache key
111
92
  const id = (0, nanoid_1.nanoid)();
112
- // API configuration fetching
113
- const api = Services_1.APIService.getInstance();
114
- // Developers are able to set different rate limit options
115
- // in model files. That's why we should create a new option object.
116
- const selectedOptions = Object.assign(Object.assign({}, api.config.rateLimit), options);
117
93
  return (context) => __awaiter(void 0, void 0, void 0, function* () {
94
+ // API configuration fetching
95
+ const api = Services_1.APIService.getInstance();
118
96
  // Creating a clientkey by the client key configurations
119
97
  const clientKey = getClientKeyByConfigurations(context.req.original, api.config.rateLimit);
120
- const key = `${clientKey}:${id}`;
121
- return new Promise((resolve) => {
122
- (0, exports.createRateLimitMiddleware)(context.req.original, context.res.original, resolve, key, selectedOptions);
123
- });
98
+ // Developers are able to set different rate limit options
99
+ // in model files. That's why we should create a new option object.
100
+ const selectedOptions = Object.assign(Object.assign({}, api.config.rateLimit), options);
101
+ // Checking the rate limit
102
+ const isAllowed = yield checkRateLimit(`${clientKey}:${id}`, selectedOptions);
103
+ // Setting the headers
104
+ context.res.original.setHeader("X-RateLimit-Limit", isAllowed.limit);
105
+ context.res.original.setHeader("X-RateLimit-Remaining", isAllowed.remaining);
106
+ // Sending an error message if there is an error
107
+ if (isAllowed.success === false) {
108
+ Services_1.LogService.warn(`Rate limit exceeded: ${context.req.url}`);
109
+ context.res
110
+ .status(Enums_1.StatusCodes.TOO_MANY_REQUESTS)
111
+ .json({ error: "Rate limit exceeded." });
112
+ }
124
113
  });
125
114
  };
126
115
  exports.rateLimit = rateLimit;
116
+ /**
117
+ * Create a rate-limitter middleware (a connect middleware) with a middleware
118
+ * configurations
119
+ *
120
+ * @param middleware IRateLimitMiddleware
121
+ * @param options IRateLimitOptions
122
+ * @param req IncomingMessage
123
+ * @param res ServerResponse
124
+ * @param next NextFunction
125
+ * @returns
126
+ */
127
+ const createRateLimitter = (middleware, options, req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
128
+ // Checking the rate limits.
129
+ const isAllowed = yield checkRateLimit(middleware.clientKey, options);
130
+ // Setting the HTTP Response headers.
131
+ if (middleware.setResponseHeaders) {
132
+ res.setHeader(`X-${middleware.name}-Limit`, isAllowed.limit);
133
+ res.setHeader(`X-${middleware.name}-Remaining`, isAllowed.remaining);
134
+ }
135
+ // If it is allowed, the next function would be called.
136
+ if (isAllowed.success) {
137
+ return next();
138
+ }
139
+ // Sending an error message.
140
+ Services_1.LogService.warn(`Rate limit exceeded: ${req.url}`);
141
+ res.writeHead(429, { "Content-Type": "application/json" });
142
+ res.end(JSON.stringify({
143
+ error: "Rate limit exceeded.",
144
+ }));
145
+ });
146
+ exports.createRateLimitter = createRateLimitter;
127
147
  exports.default = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
128
148
  const api = Services_1.APIService.getInstance();
129
149
  // Generating the client key
@@ -62,7 +62,7 @@ class AxeResponse {
62
62
  return this.response.statusCode;
63
63
  }
64
64
  header(key, value) {
65
- this.original.setHeader(key, value);
65
+ this.response.setHeader(key, value);
66
66
  }
67
67
  }
68
68
  exports.default = AxeResponse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axe-api",
3
- "version": "1.5.0-rc-1",
3
+ "version": "1.5.0-rc-2",
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",