diff --git a/commitlint.config.js b/commitlint.config.js index 0bb50357b..fe545a8ff 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -30,6 +30,7 @@ module.exports = { 'deps', 'docs', 'release', + 'express', 'socket.io', 'fastify', 'ws', diff --git a/packages/platform-express/README.md b/packages/platform-express/README.md new file mode 100644 index 000000000..73317b8ae --- /dev/null +++ b/packages/platform-express/README.md @@ -0,0 +1,22 @@ +# `@ogma/platform-express` + +The `ExpressInterceptorService` parser for the `OgmaInterceptor`. This plugin class parses Express request and response object to be able to successfully log the data about the request. For more information, check out [the @ogma/nestjs-module](packages/nestjs-module/README.md) documentation. + +## Installation + +Nothing special, standard `npm i @ogma/platform-express` or `yarn add @ogma/platform-express` + +## Usage + +This plugin is to be used in the `OgmaInterceptorOptions` portion of the `OgmaModule` during `forRoot` or `forRootAsync` registration. It can be used like so: + +```ts +@Module( + OgmaModule.forRoot({ + interceptor: { + http: ExpressInterceptorService + } + }) +) +export class AppModule {} +``` diff --git a/packages/platform-express/package.json b/packages/platform-express/package.json new file mode 100644 index 000000000..fb0959bd8 --- /dev/null +++ b/packages/platform-express/package.json @@ -0,0 +1,45 @@ +{ + "name": "@ogma/platform-express", + "version": "0.1.0", + "description": "A plugin for the OgmaInterceptor to properly handle HTTP requests from Express", + "keywords": [ + "express", + "logging", + "ogma", + "nestjs", + "interceptor", + "http" + ], + "author": "Jay McDoniel ", + "homepage": "https://github.com/jmcdo29/nestjs-ogma#readme", + "license": "MIT", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jmcdo29/nestjs-ogma.git" + }, + "scripts": { + "build": "tsc -b tsconfig.build.json", + "test": "jest", + "test:cov": "jest --coverage" + }, + "bugs": { + "url": "https://github.com/jmcdo29/nestjs-ogma/issues" + }, + "peerDependencies": { + "@ogma/nestjs-module": "^0.1.0", + "@types/express": "^4.17.3" + }, + "devDependencies": { + "@nestjs/platform-express": "^7.0.6", + "@ogma/nestjs-module": "^0.1.0", + "@types/express": "^4.17.3" + } +} diff --git a/packages/platform-express/src/express-interceptor.service.ts b/packages/platform-express/src/express-interceptor.service.ts new file mode 100644 index 000000000..f7e4d1ce4 --- /dev/null +++ b/packages/platform-express/src/express-interceptor.service.ts @@ -0,0 +1,68 @@ +import { ExecutionContext, HttpException, Injectable } from '@nestjs/common'; +import { HTTP_CODE_METADATA } from '@nestjs/common/constants'; +import { AbstractInterceptorService } from '@ogma/nestjs-module'; +import { Request, Response } from 'express'; + +@Injectable() +export class ExpressInterceptorService extends AbstractInterceptorService { + getCallerIp(context: ExecutionContext): string[] | string { + const req = this.getRequest(context); + return req.ips.length ? req.ips : req.ip; + } + + getCallPoint(context: ExecutionContext): string { + const req = this.getRequest(context); + const url = req.url; + return url || ''; + } + + getStatus( + context: ExecutionContext, + inColor: boolean, + error?: Error & HttpException, + ): string { + let status; + const res = this.getResponse(context); + status = res.statusCode; + const reflectStatus = this.reflector.get( + HTTP_CODE_METADATA, + context.getHandler(), + ); + status = reflectStatus ?? status; + if (error) { + status = this.determineStatusCodeFromError(error); + } + return inColor ? this.wrapInColor(status) : status.toString(); + } + + getMethod(context: ExecutionContext): string { + const req = this.getRequest(context); + const method = req.method; + return method ?? 'GET'; + } + + getProtocol(context: ExecutionContext): string { + const req = this.getRequest(context); + return `HTTP/${this.getHttpMajor(req)}.${this.getHttpMinor(req)}`; + } + + private getRequest(context: ExecutionContext): Request { + return context.switchToHttp().getRequest(); + } + + private getResponse(context: ExecutionContext): Response { + return context.switchToHttp().getResponse(); + } + + private getHttpMajor(req: Request): number { + return req.httpVersionMajor; + } + + private getHttpMinor(req: Request): number { + return req.httpVersionMinor; + } + + private determineStatusCodeFromError(error: HttpException & Error): number { + return (error.getStatus && error.getStatus()) || 500; + } +} diff --git a/packages/platform-express/src/index.ts b/packages/platform-express/src/index.ts new file mode 100644 index 000000000..b98ee449a --- /dev/null +++ b/packages/platform-express/src/index.ts @@ -0,0 +1 @@ +export * from './express-interceptor.service'; diff --git a/packages/platform-express/tsconfig.build.json b/packages/platform-express/tsconfig.build.json new file mode 100644 index 000000000..48efbcf68 --- /dev/null +++ b/packages/platform-express/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["test", "./src/**/*spec.ts"] +} diff --git a/packages/platform-express/tsconfig.json b/packages/platform-express/tsconfig.json new file mode 100644 index 000000000..af41db5f7 --- /dev/null +++ b/packages/platform-express/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "include": ["./src"], + "references": [ + { + "path": "../logger" + } + ] +}