Skip to content

Commit

Permalink
Merge pull request #181 from AnkanSaha/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
AnkanSaha committed Mar 8, 2024
2 parents 76d825b + 6b7a8ce commit 46950c9
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules
lib
dist
Cache
a.js
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ CODE_OF_CONDUCT.md
CONTRIBUTING.md
LEARN.md
SECURITY.md
.circleci
.circleci
a.js
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,34 @@ app.use("/api", Middleware.JWTValidator("FieldName", Token), MainRouter); // use
// You can pass as many as you want methods in the first parameter of the function
## Count the Number of Requests in NodeJS
```javascript
const { Middleware } = require("outers"); // import the package

app.use(
"/api",
Middleware.RequestCounter(true, true, true, true, true),
MainRouter,
); // count the number of requests in NodeJS with the Middleware function
```
- Note : You can pass true/false in all parameters of the function, by default it is set to true, if you set it to true then it will count the number of requests in the console
- Note : The First Parameter is SaveIP which is used to save the IP Address in the Request Object, by default it is set to true, if you set it to true then it will save the IP Address in the Request Object
- Note : The Second Parameter is SaveUserAgent which is used to save the User Agent in the Request Object, by default it is set to true, if you set it to true then it will save the User Agent in the Request Object
- Note : The Third Parameter is SaveRequestTime which is used to save the Request Time in the Request Object, by default it is set to true, if you set it to true then it will save the Request Time in the Request Object
- Note : The Fourth Parameter is SaveContentType which is used to save the Content Type in the Request Object, by default it is set to true, if you set it to true then it will save the Content Type in the Request Object
- Note : The Fifth Parameter is SaveMethod which is used to save the Method in the Request Object, by default it is set to true, if you set it to true then it will save the Method in the Request Object
## License
MIT
```

```
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "outers",
"version": "8.2.15",
"version": "8.3.0",
"description": "outers - a all in one package for your day to day use",
"main": "./lib/Config/outer.js",
"types": "./lib/Config/outer.d.ts",
Expand Down
31 changes: 31 additions & 0 deletions source/Cluster/class/CreateClusterByClass.method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class CreateClusterByClass {
#AfterListenFunctions: any[]; // Any Functions to run after listen
#FunctionMiddlewares: any[]; // Any Middlewares to apply
#GlobalResponseObject: ResponseObject; // Any ResponseObject
#EnableTrustProxy: boolean; // Enable Trust Proxy

// Constructor
/**
Expand Down Expand Up @@ -60,6 +61,7 @@ export default class CreateClusterByClass {
TotalAfterFunctions: this.#AfterListenFunctions.length,
ActiveMiddlewares: this.#FunctionMiddlewares,
};
this.#EnableTrustProxy = true; // Enable Trust Proxy
}

// Start Server Method
Expand Down Expand Up @@ -137,6 +139,13 @@ export default class CreateClusterByClass {
yellow(`Worker ${worker.process.pid} is listening`);
});
} else {
// Enable trust proxy for Express Server
this.#EnableTrustProxy === true
? this.#ExpressServer.set("trust proxy", true)
: yellow(
"Trust Proxy is not enabled, if you are working behind a proxy, please enable it to get the real IP Address",
);

// Apply Function Middlewares to Express Server Instance like CORS, Body Parser, etc.
if (
this.#FunctionMiddlewares.length > 0 ||
Expand Down Expand Up @@ -279,4 +288,26 @@ export default class CreateClusterByClass {

this.#FunctionMiddlewares.push(FunctionToRun); // Add Function to Function Middlewares
}

// Enable Trust Proxy Method
/**
* Controls the Trust Proxy setting.
* @param {boolean} Status - The value indicating whether to enable or disable Trust Proxy.
* @throws {Error} If Trust Proxy is already enabled.
* @throws {Error} If the provided value is not a boolean.
*/
public ControlTrustProxy(Status: boolean): void {
// Check if Trust Proxy is already enabled or not
if (this.#EnableTrustProxy === true) {
throw new Error("Trust Proxy is already enabled"); // Error Message for Server Start
}

// Check inserted value is boolean or not
if (typeof Status !== "boolean") {
throw new Error("TPlease provide a boolean value to enable Trust Proxy"); // Error Message for Server Start
}

// Enable Trust Proxy
this.#EnableTrustProxy = Status; // Enable Trust Proxy
}
}
9 changes: 9 additions & 0 deletions source/Cluster/function/CreateClusterByFunction.method.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ResponseObject } from "../../Config/Interfaces/Cluster/CreateClusterByF
* @param ExpressServer - The main Express server instance.
* @param PORT - The port number to listen on.
* @param NumberOfWorkers - The number of worker copies to create.
* @param EnableTrustProxy - Whether to enable trust proxy or not.
* @param BeforeListenFunctions - Any functions to run before listening.
* @param AfterListenFunctions - Any functions to run after listening.
* @param FunctionMiddlewares - Any middlewares to apply to the Express server instance.
Expand All @@ -26,6 +27,7 @@ export default async function Config(
ExpressServer: Express = express(), // Main Express Server Instance
PORT = 3000, // Port Number to Listen
NumberOfWorkers: number = cpus().length, // Number of Copies of Workers
EnableTrustProxy: boolean = true, // Enable Trust Proxy
BeforeListenFunctions: any[] = [], // Any Functions to run before listen
AfterListenFunctions: any[] = [], // Any Functions to run after listen
FunctionMiddlewares: any[] = [], // Any Middlewares to apply
Expand Down Expand Up @@ -98,6 +100,13 @@ export default async function Config(
yellow(`Worker ${worker.process.pid} is listening`);
});
} else {
// Enable trust proxy for Express Server
EnableTrustProxy
? ExpressServer.set("trust proxy", () => true)
: yellow(
"Trust Proxy is not enabled, if you are working behind a proxy, please enable it to get the real IP Address",
);

// Apply Function Middlewares to Express Server Instance like CORS, Body Parser, etc.
if (FunctionMiddlewares.length > 0 || FunctionMiddlewares !== undefined) {
FunctionMiddlewares.forEach((FunctionMiddleware) => {
Expand Down
3 changes: 3 additions & 0 deletions source/Config/Constant/Middleware.Constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,6 @@ export const IPAllowedMethods = ["PUT", "POST", "PATCH", "DELETE"]; // Allowed M

// Constants for Allowed HTTP Methods in Request Controller Middleware
export const AllowedMethods = [...IPAllowedMethods, "OPTIONS"]; // Allowed Methods

// Constants for Request Counter Storage
export const TodayDate = new Date().toLocaleDateString(); // Get Today's Date
2 changes: 2 additions & 0 deletions source/Config/outer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import IP_Controller from "../Middlewares/IP Controller/Base.middleware"; // Imp
import UserAccessController from "../Middlewares/User Agent Controller/Base.middleware"; // Import User Access Controller Module
import RequestController from "../Middlewares/Request Controller/Base.middleware"; // Import Request Controller Module
import JWTValidator from "../Middlewares/JWT Validator/Base.middleware"; // Import JWT Validator Middleware
import RequestCounter from "../Middlewares/User Counter/Base.middleware"; // Import Request Counter Middleware

// Import Functions Related Modules
import IPChecker from "../Functions/IP Type Checker.function"; // Import IP Type Checker Module
Expand Down Expand Up @@ -108,6 +109,7 @@ export const Middleware = Object.freeze({
User_AgentController: UserAccessController, // Export User Access Controller Module as Middleware
MethodsController: RequestController, // Export Request Controller Module as Middleware
JWTValidator, // Export JWT Validator Middleware
RequestCounter, // Export Request Counter Middleware
}); // Export IP Injector Module as Middleware

// Export All Class based with Freeze
Expand Down
89 changes: 89 additions & 0 deletions source/Middlewares/User Counter/Base.middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Request, Response, NextFunction } from "express"; // Importing express types
import Storage from "../../Storage Management/ShortStorage.storage"; // Importing ShortStorage
import { TodayDate } from "../../Config/Constant/Middleware.Constant"; // Importing Today's Date
import { StatusCode } from "../../StatusCode/Code"; // Importing Status Code
import { Serve } from "../../Config/outer"; // Importing Serve

// Create new ShortStorage instance
export const StorageInstance = new Storage(
"Request-Counter-details-for-nodejs",
999999, // 999999 MB = 1TB
"Request-Counter-details-for-nodejs",
);

// Main middleware function
export default function (
SaveIP: boolean = true,
SaveUserAgent: boolean = true,
SaveRequestTime: boolean = true,
SaveContentType: boolean = true,
SaveMethod: boolean = true,
) {
return async (Request: Request, Response: Response, Next: NextFunction) => {
const GetPreviousData = await StorageInstance.Get(TodayDate); // Get previous data

// Check if previous data is available or not
if (GetPreviousData.status === StatusCode.NOT_FOUND) {
const SaveStatus = await StorageInstance.Save(TodayDate, {
TotalRequest: 0,
TotalDetails: [
{
RequestDate: TodayDate,
RequestTime: SaveRequestTime ? new Date().getTime() : undefined,
RequestIP: SaveIP ? Request.ip : undefined,
RequestUserAgent: SaveUserAgent
? Request.headers["user-agent"]
: undefined,
RequestContentType: SaveContentType
? Request.headers["content-type"]
: undefined,
RequestMethod: SaveMethod ? Request.method : undefined,
},
],
});

// Check if data is saved or not
SaveStatus.status === StatusCode.OK
? Next()
: Serve.JSON({
response: Response,
status: false,
message: "Unable to process your request, please try again later",
Title: "Error",
statusCode: StatusCode.INTERNAL_SERVER_ERROR,
data: undefined,
});
} else {
const UpdateStatus = await StorageInstance.Update(TodayDate, {
TotalRequest: GetPreviousData.Data[0].Data.TotalRequest + 1,
TotalDetails: [
...GetPreviousData.Data[0].Data.TotalDetails,
{
RequestDate: TodayDate,
RequestTime: SaveRequestTime ? new Date().getTime() : undefined,
RequestIP: SaveIP ? Request.ip : undefined,
RequestUserAgent: SaveUserAgent
? Request.headers["user-agent"]
: undefined,
RequestContentType: SaveContentType
? Request.headers["content-type"]
: undefined,
RequestMethod: SaveMethod ? Request.method : undefined,
},
],
});

// Check if data is updated or not
UpdateStatus.status === StatusCode.OK
? Next()
: Serve.JSON({
response: Response,
status: false,
message: "Unable to process your request, please try again later",
Title: "Error",
statusCode: StatusCode.INTERNAL_SERVER_ERROR,
data: undefined,
});
}
};
}

0 comments on commit 46950c9

Please sign in to comment.