Skip to content

Commit

Permalink
✨ Version 2.3.0 Stable Release 1
Browse files Browse the repository at this point in the history
  • Loading branch information
MeetBhingradiya committed Oct 17, 2023
1 parent a083d13 commit 5bd187f
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 118 deletions.
204 changes: 110 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
# Express Router Plugin

Custom Express Router with Integrated Rate Limiting and Presets.
A custom Express Router that integrates `seamlessly` with rate limiting and middlewares. This plugin simplifies the process of creating `organized routes` in your Express.js applications. It also provides `built-in error handling` for route controllers and `integrated rate limiting` for enhanced security. The Express Router Plugin is `easy to use` and can be integrated into existing Express applications with minimal effort.

## Table of Contents
+ [Features](#features)
+ [Installation](#installation)
+ [Usage](#usage)
+ [Priorities Limit Configs](#priorities-limit-configs)
+ [Documentation](#documentation)
+ [New Documentation Soon!](https://meetbhingradiya.notion.site/ec5b42bc7d2749a0a5d7bb6d4a8cc609?v=f19bf64528ee47cfb87e3b49f819d51c&pvs=4)
+ [Contributing](#contributing)
+ [License](#license)

+ [Soon! (Notion Wiki)](https://meetbhingradiya.notion.site/ec5b42bc7d2749a0a5d7bb6d4a8cc609?v=f19bf64528ee47cfb87e3b49f819d51c&pvs=4)

## Features
+ Integrated Rate Limiting
+ Integrated Error Handler
+ Oranized Routes
+ SafeMode to Create Global RateLimit
+ Easy to use
+ **Integrated Rate Limiting:** Set rate limits for your routes effortlessly.
+ **Integrated Error Handler:** Built-in error handling for route controllers.
+ **Organized Routes:** Maintain clean and organized route structures.
+ **SafeMode:** Configure global rate limits for enhanced security.
+ **Easy to Use:** Simple integration into existing Express applications.

## Installation

Run the following command to install the package:
To install the Express Router Plugin, use one of the following package managers:

```bash
yarn add express-router-plugin
Expand All @@ -37,157 +44,165 @@ bun add express-router-plugin
## Usage

```ts
import Express from 'express';

// ? Import Router from express-router-plugin package
import Router from 'express-router-plugin';
// ? or
// import { Router } from 'express-router-plugin';
// ? or
// import { AppRouter } from 'express-router-plugin';
const Express = require('express');
const { Router } = require('express-router-plugin');

const app = Express();

/**
* ? Create a new instance of AppRouter
*/
const AppRouter = new Router();

// Initialize AppRouter configurations (optional)
AppRouter.Init({
// ? Apply Default RateLimit to all routes in the AppRouter only if you want default false

// Apply Default RateLimit that set by express-rate-limit package to all routes in the AppRouter only if you want default is false
ApplyDefaultRateLimit: false,

// ? Apply Inbuild Error Handler to all routes in the AppRouter only if you want default true
// Apply Inbuild Error Handler to all routes in the AppRouter only if you want default is true
inbuild_error_handler: true,

// ? SafeMode & Create Global RateLimit
// Default RateLimit that is directly passed to express-rate-limit package
GlobalRateLimit: {
// ? windowMs: 15 * 60 * 1000,
// ? max: 100,
// ? message: "Too many requests, please try again after 15 minutes"
// ? ...Rest of the options are same as `express-rate-limit` package
// windowMs: 15 * 60 * 1000,
// max: 100,
// message: "Too many requests, please try again after 15 minutes"
// ... other options from express-rate-limit
},

// ? SafeMode
// ? SafeMode is used to change `Priorities Limit Configs` Order
// ? SafeMode Order : `GlobalRateLimit` > `LimitOptions` > `LimitPreset` > `DefaultLimits` > `No RateLimit`
// This is change priority of RateLimit Configs so GlobalRateLimit is top priority and LimitOptions is bottom priority default LimitOptions is top priority and GlobalRateLimit is bottom priority
SafeMode: true,

// ? Global Request Timeout : Used to set timeout for all routes in the AppRouter
// ? Default : Not Set (No Timeout)
// ? This option is time validation supported so you can use more complex time like 1d, 1h, 1m, 1s, 1ms like JWT package
GlobalTimeout: "10s"


// Soon ! Not Added Yet
GlobalMiddlewares: [
// ... Global Middlewares
],
GlobalTimeout: 10000,
});

/**
* ? Create a new route not RateLimite
*/
// Create routes
AppRouter.CreateRoute({
// ? Endpoint of the route
endpoint: "/",

// ? Method of the route ! Currently only supports get, post, put, delete
method: "get",

// ? Middleware of the route
Middleware: [],

// ? Controller of the route
controller: (req, res) => {
res.send("Hello World");
}
// ? LimitOptions of the route
// LimitOptions: {},

// ? LimitPreset of the route
// LimitPreset: LimitPresets._1Min

// ? Request Timeout : Used to set timeout for this route
// ? Default : Not Set (No Timeout)
// ? This option is time validation supported so you can use more complex time like 1d, 1h, 1m, 1s, 1ms like JWT package
// Timeout: "10s"
});

/**
* ? Execute the AppRouter
*/
AppRouter.Execute(app); // ? or app.use("/<Your Endpoint>" , AppRouter.Execute());
// Execute AppRouter
AppRouter.Execute(app);

// ? Express Server Listen
// Express Server Listen
app.listen(3000, () => {
console.log("Server Started at http://localhost:3000");
})
});

module.exports = app;
```
## Priorities Limit Configs
> **`LimitOptions` > `LimitPreset` > `GlobalRateLimit` > `DefaultLimits` > `No RateLimit`**
## Documentation
1. **`LimitPreset`** - Rate limit presets created with `Create_Limit_Preset` function have the `highest` priority. If a route specifies a LimitPreset, it will be used as the rate limit configuration for that route.

2. **`LimitOptions`** - Rate limit options specified directly in the route using LimitOptions take the `second-highest` priority. These options are specific to the individual route and override any global rate limit settings.

3. **`GlobalRateLimit`**: Global rate limit configurations set during the initialization of AppRouter come next in priority. These configurations apply to all routes unless overridden by specific route settings.

4. **DefaultLimits:** If no specific rate limit configurations are provided for a route, and no global or route-specific limits are set, the route will inherit the default rate limits. These defaults are used when no other rate limit options are specified. Init Option Called `ApplyDefaultRateLimit` is used to apply default rate limit to all routes in the AppRouter.

>## Priorities Limit Configs
> + `LimitOptions` > `LimitPreset` > `GlobalRateLimit` > `DefaultLimits` > `No RateLimit`
5. **No Rate Limit:** If no rate limit options are provided at any level, the route operates without any rate limits. It has no defined restrictions on request rates.

### AppRouter.Init()
+ `ApplyDefaultRateLimit` - Apply Default RateLimit that set by `express-rate-limit` package to all routes in the AppRouter only if you want default false
+ `inbuild_error_handler` - Apply Inbuild Error Handler to all routes in the AppRouter only if you want default true
By following this order of priority, you can effectively tailor the rate limiting behavior for your routes in your Express.js application.

### AppRouter.CreateRoute()
+ `endpoint` - Endpoint of the route
+ `method` - Method of the route ! Currently only supports get, post, put, delete
+ `Middleware` - Add Middlewares to the route
+ `controller` - Controller of the route
+ `LimitOptions` - LimitOptions that is directly passed to `express-rate-limit` package
+ `LimitPreset` - used to use pre-made presets of RateLimit that is created from `Create_Limit_Preset` function
## Documentation

### **`AppRouter.Init()`**
+ `ApplyDefaultRateLimit` - (boolean, default: **false**): Apply a default rate limit to all routes in the AppRouter. If set to true, the default rate limit will be applied to all routes unless overridden by a specific route setting.
+ `inbuild_error_handler` - (boolean, default: **true**): Apply the built-in error handler to all routes in the AppRouter. If set to true, the built-in error handler will be applied to all routes unless overridden by a specific route setting.
+ `GlobalRateLimit` - (RateLimitOptions, default: **undefined**): Set a global rate limit for all routes in the AppRouter. If set, this rate limit will be applied to all routes unless overridden by a specific route setting.
+ `SafeMode` - (boolean, default: **true**): Set the priority of rate limit configurations. If set to **true**, the priority order will be: `GlobalRateLimit > DefaultLimits > LimitPreset > LimitOptions > No RateLimit`. [Learn More](#priorities-limit-configs)

Example:

```ts
import Express from 'express';
import Router from 'express-router-plugin';
const Express = require('express');
const { Router } = require('express-router-plugin');

const app = Express();
const AppRouter = new Router();

// ...Configs
// Initialize AppRouter configurations
AppRouter.Init({
ApplyDefaultRateLimit: false,
inbuild_error_handler: true,
GlobalRateLimit: {
windowMs: 15 * 60 * 1000,
max: 100,
message: "Too many requests, please try again after 15 minutes"
},
SafeMode: true
});

// ...Create Routes
```

### **`AppRouter.CreateRoute()`**
The CreateRoute function is used to create routes in the AppRouter. It takes a single parameter, which is an object containing the route configuration. The following properties are supported:

+ **`endpoint`** - (string, required): The endpoint at which the route should be created. This is the same as the first parameter of the Express app's `app.METHOD()` functions.
+ **`method`** - (string, required): The HTTP method for the route. This is the same as the second parameter of the Express app's `app.METHOD()` functions.
+ **`Middleware`** - (array of functions, default: []): Array of middlewares to be applied to the route.
+ **`controller`** - (function, required): The controller function for the route. This is the same as the fourth parameter of the Express app's `app.METHOD()` functions.
+ **`LimitOptions`** - (object, default: undefined): Limit options for rate limiting specific to this route. These options override any global rate limit settings if `Safemode` is set to true.
+ **`LimitPreset`** - (function, default: undefined): Pre-made rate limit preset function to be used for this route. These presets override any global rate limit settings if `Safemode` is set to true.

Example:

```ts
AppRouter.CreateRoute({
endpoint: "/",
method: "get",
Middleware: [],
controller: (req, res) => {
res.send("Hello World");
}
// LimitOptions: {},
// LimitPreset: LimitPresets._1Min
});

// ...More Routes
```

### **`AppRouter.Execute(app, endpoint)`**
The Execute function integrates the AppRouter with the Express app as middleware. It must be called after all routes have been created and configured. The function takes two parameters:
+ **`app`** - (Express app instance, required): The Express app to which the AppRouter should be integrated.
+ **`endpoint`** - (string, optional): The endpoint at which the AppRouter should be mounted. If no endpoint is provided, the AppRouter will be mounted at the root of the Express app.

### AppRouter.Execute()
+ `app` - Express App Instance
Example:

```ts
import Express from 'express';
import Router from 'express-router-plugin';
const Express = require('express');
const { Router } = require('express-router-plugin');

const app = Express();
const AppRouter = new Router();

// ...Routers and Configs

// ! Only one time use in the whole project other wise RateLimit conflicts occurs in the app
AppRouter.Execute(app);
// ... Initialize AppRouter and create routes

// ? OR
// Execute AppRouter
AppRouter.Execute(app); // or app.use(AppRouter.Execute());
// OR
AppRouter.Execute(app, "/api"); // or app.use("/api", AppRouter.Execute());

// ! Recommended to use this method to avoid RateLimit Conflicts
app.use("/<Your Endpoint>" , AppRouter.Execute());
app.listen(3000, () => {
console.log("Server Started at http://localhost:3000");
});

// ...Express Server Listen
module.exports = app;
```

### Create_Limit_Preset()
### **`Create_Limit_Preset()`**
+ We Used `express-rate-limit` : Version `7.1.0` `Last Updated 17-10-23`
+ This function is used to create presets of RateLimit that is exported from `express-rate-limit` package
+ please refer to [express-rate-limit](https://www.npmjs.com/package/express-rate-limit) for more details
+ please refer to `express-rate-limit` package [Learn more](https://www.npmjs.com/package/express-rate-limit)

```ts
// ? Limit Presets
Expand Down Expand Up @@ -216,7 +231,6 @@ const LimitPresets = {
AppRouter.CreateRoute({
endpoint: "/",
method: "get",
Middleware: [],
controller: (req, res) => {
res.send("Hello World");
}
Expand All @@ -226,7 +240,9 @@ AppRouter.CreateRoute({

## Contributing

Contributions are welcome! Please feel free to submit a pull request or open an issue if you find any problems or have suggestions for improvements.
Contributions are welcome! If you encounter issues or have suggestions, please submit a pull request or open an issue.

## License
This project is licensed under the `MIT` License - see the [LICENSE](./License) file for details.

2023 © [TEAMSM](https://teamsm.vercel.app/)
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "express-router-plugin",
"version": "2.2.0",
"version": "2.3.0",
"description": "Custom Express Router with Integrated Rate Limiting and Middlewares",
"main": "./build/index.js",
"scripts": {
Expand All @@ -9,19 +9,24 @@
},
"keywords": [
"express",
"express-router",
"express-router-plugin",
"router",
"custom-router",
"router-plugin",
"plugin",
"rate-limiting",
"middleware",
"middlewares",

"TeamSM",
"MeetBhingradiya",
"@TeamSM",
"@TeamSM/MeetBhingradiya"
],
"author": "Meet Bhingradiya",
"license": "MIT",
"dependencies": {
"connect-timeout": "^1.9.0",
"express": "^4.18.2",
"express-rate-limit": "^7.1.0"
},
Expand Down
22 changes: 2 additions & 20 deletions src/Processors/AppRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Config_Type, CreateRoute_Type, RateLimit_Options_Optimised, Middleware_
import { useController } from ".";
import { Router as _Route, Express } from "express";
import RateLimit, { RateLimitRequestHandler } from "express-rate-limit";
import Timeout from "connect-timeout";

class AppRouter {
private Router: _Route;
Expand All @@ -12,8 +11,7 @@ class AppRouter {
inbuild_error_handler: true,
ApplyDefaultRateLimit: false,
GlobalRateLimit: undefined,
SafeMode: false,
GlobalTimeout: undefined
SafeMode: false
}

constructor() {
Expand Down Expand Up @@ -56,8 +54,7 @@ class AppRouter {
Middleware = [],
controller,
LimitOptions = {},
LimitPreset,
TimeOut
LimitPreset
}: CreateRoute_Type): void {
const Apply_RateLimit_Instance = () => {
if (LimitPreset) {
Expand All @@ -84,22 +81,7 @@ class AppRouter {
}
}

const TimeOut_Instance = () => {
if(TimeOut) {
this.Router.use(endpoint, Timeout(TimeOut));

if (!this.Config.SafeMode) {
return;
}
}

if (this.Config.GlobalTimeout) {
this.Router.use(Timeout(this.Config.GlobalTimeout));
}
}

Apply_RateLimit_Instance();
TimeOut_Instance();
const Middlewares = this.applyMiddleware(Middleware);
const Controller = this.Config.inbuild_error_handler ? useController(controller) : controller;

Expand Down
Loading

0 comments on commit 5bd187f

Please sign in to comment.