@syswatch/nestjs 1.0.0
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/dist/index.d.mts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +41 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ModuleMetadata, Type, DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { SysWatchConfig, SysWatch } from '@syswatch/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
type SysWatchModuleOptions = SysWatchConfig;
|
|
6
|
+
interface SysWatchOptionsFactory {
|
|
7
|
+
createSysWatchOptions(): Promise<SysWatchModuleOptions> | SysWatchModuleOptions;
|
|
8
|
+
}
|
|
9
|
+
interface SysWatchModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
10
|
+
useExisting?: Type<SysWatchOptionsFactory>;
|
|
11
|
+
useClass?: Type<SysWatchOptionsFactory>;
|
|
12
|
+
useFactory?: (...args: any[]) => Promise<SysWatchModuleOptions> | SysWatchModuleOptions;
|
|
13
|
+
inject?: any[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const SYSWATCH_OPTIONS = "SYSWATCH_OPTIONS";
|
|
17
|
+
|
|
18
|
+
declare class SysWatchService extends SysWatch {
|
|
19
|
+
constructor(options: SysWatchModuleOptions);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class SysWatchModule {
|
|
23
|
+
static forRoot(options: SysWatchModuleOptions): DynamicModule;
|
|
24
|
+
static forRootAsync(options: SysWatchModuleAsyncOptions): DynamicModule;
|
|
25
|
+
private static createAsyncProviders;
|
|
26
|
+
private static createAsyncOptionsProvider;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare class LoggerInterceptor implements NestInterceptor {
|
|
30
|
+
private readonly sysWatch;
|
|
31
|
+
constructor(sysWatch: SysWatchService);
|
|
32
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
33
|
+
private logRequest;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { LoggerInterceptor, SYSWATCH_OPTIONS, SysWatchModule, type SysWatchModuleAsyncOptions, type SysWatchModuleOptions, type SysWatchOptionsFactory, SysWatchService };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ModuleMetadata, Type, DynamicModule, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
2
|
+
import { SysWatchConfig, SysWatch } from '@syswatch/core';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
4
|
+
|
|
5
|
+
type SysWatchModuleOptions = SysWatchConfig;
|
|
6
|
+
interface SysWatchOptionsFactory {
|
|
7
|
+
createSysWatchOptions(): Promise<SysWatchModuleOptions> | SysWatchModuleOptions;
|
|
8
|
+
}
|
|
9
|
+
interface SysWatchModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
|
|
10
|
+
useExisting?: Type<SysWatchOptionsFactory>;
|
|
11
|
+
useClass?: Type<SysWatchOptionsFactory>;
|
|
12
|
+
useFactory?: (...args: any[]) => Promise<SysWatchModuleOptions> | SysWatchModuleOptions;
|
|
13
|
+
inject?: any[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const SYSWATCH_OPTIONS = "SYSWATCH_OPTIONS";
|
|
17
|
+
|
|
18
|
+
declare class SysWatchService extends SysWatch {
|
|
19
|
+
constructor(options: SysWatchModuleOptions);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class SysWatchModule {
|
|
23
|
+
static forRoot(options: SysWatchModuleOptions): DynamicModule;
|
|
24
|
+
static forRootAsync(options: SysWatchModuleAsyncOptions): DynamicModule;
|
|
25
|
+
private static createAsyncProviders;
|
|
26
|
+
private static createAsyncOptionsProvider;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
declare class LoggerInterceptor implements NestInterceptor {
|
|
30
|
+
private readonly sysWatch;
|
|
31
|
+
constructor(sysWatch: SysWatchService);
|
|
32
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
33
|
+
private logRequest;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { LoggerInterceptor, SYSWATCH_OPTIONS, SysWatchModule, type SysWatchModuleAsyncOptions, type SysWatchModuleOptions, type SysWatchOptionsFactory, SysWatchService };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var O=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var q=(o,t)=>{for(var r in t)O(o,r,{get:t[r],enumerable:!0})},T=(o,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of w(t))!P.call(o,e)&&e!==r&&O(o,e,{get:()=>t[e],enumerable:!(s=A(t,e))||s.enumerable});return o};var b=o=>T(O({},"__esModule",{value:!0}),o),d=(o,t,r,s)=>{for(var e=s>1?void 0:s?A(t,r):t,i=o.length-1,c;i>=0;i--)(c=o[i])&&(e=(s?c(t,r,e):c(e))||e);return s&&e&&O(t,r,e),e},x=(o,t)=>(r,s)=>t(r,s,o);var H={};q(H,{LoggerInterceptor:()=>S,SYSWATCH_OPTIONS:()=>m,SysWatchModule:()=>p,SysWatchService:()=>n});module.exports=b(H);var m="SYSWATCH_OPTIONS";var v=require("@nestjs/common"),C=require("@syswatch/core");var n=class extends C.SysWatch{constructor(t){super(t)}};n=d([(0,v.Injectable)(),x(0,(0,v.Inject)(m))],n);var g=require("@nestjs/common");var p=class{static forRoot(t){return{module:p,providers:[{provide:m,useValue:t},n],exports:[n]}}static forRootAsync(t){return{module:p,imports:t.imports||[],providers:[...this.createAsyncProviders(t),n],exports:[n]}}static createAsyncProviders(t){return t.useExisting||t.useFactory?[this.createAsyncOptionsProvider(t)]:[this.createAsyncOptionsProvider(t),{provide:t.useClass,useClass:t.useClass}]}static createAsyncOptionsProvider(t){return t.useFactory?{provide:m,useFactory:t.useFactory,inject:t.inject||[]}:{provide:m,useFactory:async r=>await r.createSysWatchOptions(),inject:[t.useExisting||t.useClass]}}};p=d([(0,g.Global)(),(0,g.Module)({})],p);var a=require("@nestjs/common"),E=require("rxjs"),W=require("rxjs/operators");var S=class{constructor(t){this.sysWatch=t}intercept(t,r){let s=t.switchToHttp().getRequest(),{method:e,url:i}=s,c=Date.now(),y=s.user?.id||s.user?.sub||s.user?._id,l=s.id||s.headers["x-request-id"]||s.headers["x-correlation-id"];return r.handle().pipe((0,W.tap)(()=>{let h=t.switchToHttp().getResponse().statusCode,f=Date.now()-c;this.logRequest({method:e,url:i,statusCode:h,duration:f,userId:y,requestId:l})}),(0,W.catchError)(u=>{let h=Date.now()-c,f=u instanceof a.HttpException?u.getStatus():a.HttpStatus.INTERNAL_SERVER_ERROR;return this.logRequest({method:e,url:i,statusCode:f,duration:h,error:u,userId:y,requestId:l}),(0,E.throwError)(()=>u)}))}async logRequest({method:t,url:r,statusCode:s,duration:e,error:i,userId:c,requestId:y}){if(!this.sysWatch||!this.sysWatch.log)return a.Logger.error("SysWatchService not injected. LoggerInterceptor will not log requests.");let l=`${t} ${r} ${s} - ${e}ms`,u={method:t,url:r,statusCode:s,duration:e,slow:e>1e3,...y&&{requestId:y},...i&&i instanceof Error&&{error:i.message,exception:i.name,..."code"in i?{code:i.code}:{},...process.env.NODE_ENV!=="production"?{stack:i.stack}:{}}},h=s.toString().startsWith("2"),f=s.toString().startsWith("4"),R=s.toString().startsWith("5");h&&await this.sysWatch.log.success("http_request",l,{...c&&{userId:c},meta:u}),f&&await this.sysWatch.log.failure("http_request",l,{...c&&{userId:c},meta:u}),R&&await this.sysWatch.log.error("http_request",l,{...c&&{userId:c},meta:u})}};S=d([(0,a.Injectable)(),x(0,(0,a.Inject)(n))],S);0&&(module.exports={LoggerInterceptor,SYSWATCH_OPTIONS,SysWatchModule,SysWatchService});
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/syswatch.service.ts","../src/syswatch.module.ts","../src/interceptors/logger.interceptor.ts"],"sourcesContent":["export * from \"./interfaces\";\nexport * from \"./constants\";\nexport * from \"./syswatch.service\";\nexport * from \"./syswatch.module\";\n\nexport * from \"./interceptors\";\n","export const SYSWATCH_OPTIONS = 'SYSWATCH_OPTIONS';\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { SysWatch } from \"@syswatch/core\";\nimport { SYSWATCH_OPTIONS } from \"./constants\";\nimport { SysWatchModuleOptions } from \"./interfaces\";\n\n@Injectable()\nexport class SysWatchService extends SysWatch {\n constructor(@Inject(SYSWATCH_OPTIONS) options: SysWatchModuleOptions) {\n super(options);\n }\n}\n","import { DynamicModule, Global, Module, Provider } from '@nestjs/common';\nimport { SysWatchService } from './syswatch.service';\nimport { SYSWATCH_OPTIONS } from './constants';\nimport { SysWatchModuleAsyncOptions, SysWatchModuleOptions, SysWatchOptionsFactory } from './interfaces';\n\n@Global()\n@Module({})\nexport class SysWatchModule {\n static forRoot(options: SysWatchModuleOptions): DynamicModule {\n return {\n module: SysWatchModule,\n providers: [\n {\n provide: SYSWATCH_OPTIONS,\n useValue: options,\n },\n SysWatchService,\n ],\n exports: [SysWatchService],\n };\n }\n\n static forRootAsync(options: SysWatchModuleAsyncOptions): DynamicModule {\n return {\n module: SysWatchModule,\n imports: options.imports || [],\n providers: [\n ...this.createAsyncProviders(options),\n SysWatchService,\n ],\n exports: [SysWatchService],\n };\n }\n\n private static createAsyncProviders(options: SysWatchModuleAsyncOptions): Provider[] {\n if (options.useExisting || options.useFactory) {\n return [this.createAsyncOptionsProvider(options)];\n }\n return [\n this.createAsyncOptionsProvider(options),\n {\n provide: options.useClass!,\n useClass: options.useClass!,\n },\n ];\n }\n\n private static createAsyncOptionsProvider(options: SysWatchModuleAsyncOptions): Provider {\n if (options.useFactory) {\n return {\n provide: SYSWATCH_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject || [],\n };\n }\n return {\n provide: SYSWATCH_OPTIONS,\n useFactory: async (optionsFactory: SysWatchOptionsFactory) =>\n await optionsFactory.createSysWatchOptions(),\n inject: [options.useExisting || options.useClass!],\n };\n }\n}\n","import {\n CallHandler,\n ExecutionContext,\n Injectable,\n NestInterceptor,\n HttpException,\n HttpStatus,\n Inject,\n Logger,\n} from \"@nestjs/common\";\nimport { Observable, throwError } from \"rxjs\";\nimport { catchError, tap } from \"rxjs/operators\";\nimport { SysWatchService } from \"../syswatch.service\";\n\n@Injectable()\nexport class LoggerInterceptor implements NestInterceptor {\n constructor(\n @Inject(SysWatchService) private readonly sysWatch: SysWatchService,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n const request = context.switchToHttp().getRequest();\n const { method, url } = request;\n const start = Date.now();\n\n const userId: string | undefined =\n request[\"user\"]?.id || request[\"user\"]?.sub || request[\"user\"]?._id;\n\n const requestId =\n request.id ||\n request.headers[\"x-request-id\"] ||\n request.headers[\"x-correlation-id\"];\n\n return next.handle().pipe(\n tap(() => {\n const response = context.switchToHttp().getResponse();\n const statusCode = response.statusCode;\n const duration = Date.now() - start;\n\n this.logRequest({\n method,\n url,\n statusCode,\n duration,\n userId,\n requestId,\n });\n }),\n catchError((error) => {\n const duration = Date.now() - start;\n const statusCode =\n error instanceof HttpException\n ? error.getStatus()\n : HttpStatus.INTERNAL_SERVER_ERROR;\n\n this.logRequest({\n method,\n url,\n statusCode,\n duration,\n error,\n userId,\n requestId,\n });\n return throwError(() => error);\n }),\n );\n }\n\n private async logRequest({\n method,\n url,\n statusCode,\n duration,\n error,\n userId,\n requestId,\n }: {\n method: string;\n url: string;\n statusCode: number;\n duration: number;\n error?: any;\n userId?: string;\n requestId?: string;\n }) {\n if (!this.sysWatch || !this.sysWatch.log) {\n // Fail silently or warn if service is not injected correctly\n // This happens if the interceptor is instantiated manually without passing the service\n return Logger.error(\n \"SysWatchService not injected. LoggerInterceptor will not log requests.\",\n );\n }\n\n const message = `${method} ${url} ${statusCode} - ${duration}ms`;\n const meta = {\n method,\n url,\n statusCode,\n duration,\n slow: duration > 1000,\n ...(requestId && { requestId }),\n ...(error &&\n error instanceof Error && {\n error: error.message,\n exception: error.name,\n ...(\"code\" in error ? { code: error.code } : {}),\n ...(process.env.NODE_ENV !== \"production\"\n ? { stack: error.stack }\n : {}),\n }),\n };\n\n const statusCodeSuccess = statusCode.toString().startsWith(\"2\");\n const statusCodeFailure = statusCode.toString().startsWith(\"4\");\n const statusCodeError = statusCode.toString().startsWith(\"5\");\n\n if (statusCodeSuccess) {\n await this.sysWatch.log.success(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n if (statusCodeFailure) {\n await this.sysWatch.log.failure(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n if (statusCodeError) {\n await this.sysWatch.log.error(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n }\n}\n"],"mappings":"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","names":["index_exports","__export","LoggerInterceptor","SYSWATCH_OPTIONS","SysWatchModule","SysWatchService","__toCommonJS","SYSWATCH_OPTIONS","import_common","import_core","SysWatchService","options","__decorateClass","__decorateParam","SYSWATCH_OPTIONS","import_common","SysWatchModule","options","SYSWATCH_OPTIONS","SysWatchService","optionsFactory","__decorateClass","import_common","import_rxjs","import_operators","LoggerInterceptor","sysWatch","context","next","request","method","url","start","userId","requestId","statusCode","duration","error","message","meta","statusCodeSuccess","statusCodeFailure","statusCodeError","__decorateClass","__decorateParam","SysWatchService"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var x=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var m=(u,t,i,s)=>{for(var e=s>1?void 0:s?v(t,i):t,r=u.length-1,o;r>=0;r--)(o=u[r])&&(e=(s?o(t,i,e):o(e))||e);return s&&e&&x(t,i,e),e},f=(u,t)=>(i,s)=>t(i,s,u);var l="SYSWATCH_OPTIONS";import{Inject as g,Injectable as W}from"@nestjs/common";import{SysWatch as A}from"@syswatch/core";var c=class extends A{constructor(t){super(t)}};c=m([W(),f(0,g(l))],c);import{Global as C,Module as E}from"@nestjs/common";var a=class{static forRoot(t){return{module:a,providers:[{provide:l,useValue:t},c],exports:[c]}}static forRootAsync(t){return{module:a,imports:t.imports||[],providers:[...this.createAsyncProviders(t),c],exports:[c]}}static createAsyncProviders(t){return t.useExisting||t.useFactory?[this.createAsyncOptionsProvider(t)]:[this.createAsyncOptionsProvider(t),{provide:t.useClass,useClass:t.useClass}]}static createAsyncOptionsProvider(t){return t.useFactory?{provide:l,useFactory:t.useFactory,inject:t.inject||[]}:{provide:l,useFactory:async i=>await i.createSysWatchOptions(),inject:[t.useExisting||t.useClass]}}};a=m([C(),E({})],a);import{Injectable as R,HttpException as w,HttpStatus as P,Inject as q,Logger as T}from"@nestjs/common";import{throwError as b}from"rxjs";import{catchError as H,tap as N}from"rxjs/operators";var S=class{constructor(t){this.sysWatch=t}intercept(t,i){let s=t.switchToHttp().getRequest(),{method:e,url:r}=s,o=Date.now(),d=s.user?.id||s.user?.sub||s.user?._id,p=s.id||s.headers["x-request-id"]||s.headers["x-correlation-id"];return i.handle().pipe(N(()=>{let y=t.switchToHttp().getResponse().statusCode,h=Date.now()-o;this.logRequest({method:e,url:r,statusCode:y,duration:h,userId:d,requestId:p})}),H(n=>{let y=Date.now()-o,h=n instanceof w?n.getStatus():P.INTERNAL_SERVER_ERROR;return this.logRequest({method:e,url:r,statusCode:h,duration:y,error:n,userId:d,requestId:p}),b(()=>n)}))}async logRequest({method:t,url:i,statusCode:s,duration:e,error:r,userId:o,requestId:d}){if(!this.sysWatch||!this.sysWatch.log)return T.error("SysWatchService not injected. LoggerInterceptor will not log requests.");let p=`${t} ${i} ${s} - ${e}ms`,n={method:t,url:i,statusCode:s,duration:e,slow:e>1e3,...d&&{requestId:d},...r&&r instanceof Error&&{error:r.message,exception:r.name,..."code"in r?{code:r.code}:{},...process.env.NODE_ENV!=="production"?{stack:r.stack}:{}}},y=s.toString().startsWith("2"),h=s.toString().startsWith("4"),O=s.toString().startsWith("5");y&&await this.sysWatch.log.success("http_request",p,{...o&&{userId:o},meta:n}),h&&await this.sysWatch.log.failure("http_request",p,{...o&&{userId:o},meta:n}),O&&await this.sysWatch.log.error("http_request",p,{...o&&{userId:o},meta:n})}};S=m([R(),f(0,q(c))],S);export{S as LoggerInterceptor,l as SYSWATCH_OPTIONS,a as SysWatchModule,c as SysWatchService};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/syswatch.service.ts","../src/syswatch.module.ts","../src/interceptors/logger.interceptor.ts"],"sourcesContent":["export const SYSWATCH_OPTIONS = 'SYSWATCH_OPTIONS';\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { SysWatch } from \"@syswatch/core\";\nimport { SYSWATCH_OPTIONS } from \"./constants\";\nimport { SysWatchModuleOptions } from \"./interfaces\";\n\n@Injectable()\nexport class SysWatchService extends SysWatch {\n constructor(@Inject(SYSWATCH_OPTIONS) options: SysWatchModuleOptions) {\n super(options);\n }\n}\n","import { DynamicModule, Global, Module, Provider } from '@nestjs/common';\nimport { SysWatchService } from './syswatch.service';\nimport { SYSWATCH_OPTIONS } from './constants';\nimport { SysWatchModuleAsyncOptions, SysWatchModuleOptions, SysWatchOptionsFactory } from './interfaces';\n\n@Global()\n@Module({})\nexport class SysWatchModule {\n static forRoot(options: SysWatchModuleOptions): DynamicModule {\n return {\n module: SysWatchModule,\n providers: [\n {\n provide: SYSWATCH_OPTIONS,\n useValue: options,\n },\n SysWatchService,\n ],\n exports: [SysWatchService],\n };\n }\n\n static forRootAsync(options: SysWatchModuleAsyncOptions): DynamicModule {\n return {\n module: SysWatchModule,\n imports: options.imports || [],\n providers: [\n ...this.createAsyncProviders(options),\n SysWatchService,\n ],\n exports: [SysWatchService],\n };\n }\n\n private static createAsyncProviders(options: SysWatchModuleAsyncOptions): Provider[] {\n if (options.useExisting || options.useFactory) {\n return [this.createAsyncOptionsProvider(options)];\n }\n return [\n this.createAsyncOptionsProvider(options),\n {\n provide: options.useClass!,\n useClass: options.useClass!,\n },\n ];\n }\n\n private static createAsyncOptionsProvider(options: SysWatchModuleAsyncOptions): Provider {\n if (options.useFactory) {\n return {\n provide: SYSWATCH_OPTIONS,\n useFactory: options.useFactory,\n inject: options.inject || [],\n };\n }\n return {\n provide: SYSWATCH_OPTIONS,\n useFactory: async (optionsFactory: SysWatchOptionsFactory) =>\n await optionsFactory.createSysWatchOptions(),\n inject: [options.useExisting || options.useClass!],\n };\n }\n}\n","import {\n CallHandler,\n ExecutionContext,\n Injectable,\n NestInterceptor,\n HttpException,\n HttpStatus,\n Inject,\n Logger,\n} from \"@nestjs/common\";\nimport { Observable, throwError } from \"rxjs\";\nimport { catchError, tap } from \"rxjs/operators\";\nimport { SysWatchService } from \"../syswatch.service\";\n\n@Injectable()\nexport class LoggerInterceptor implements NestInterceptor {\n constructor(\n @Inject(SysWatchService) private readonly sysWatch: SysWatchService,\n ) {}\n\n intercept(context: ExecutionContext, next: CallHandler): Observable<any> {\n const request = context.switchToHttp().getRequest();\n const { method, url } = request;\n const start = Date.now();\n\n const userId: string | undefined =\n request[\"user\"]?.id || request[\"user\"]?.sub || request[\"user\"]?._id;\n\n const requestId =\n request.id ||\n request.headers[\"x-request-id\"] ||\n request.headers[\"x-correlation-id\"];\n\n return next.handle().pipe(\n tap(() => {\n const response = context.switchToHttp().getResponse();\n const statusCode = response.statusCode;\n const duration = Date.now() - start;\n\n this.logRequest({\n method,\n url,\n statusCode,\n duration,\n userId,\n requestId,\n });\n }),\n catchError((error) => {\n const duration = Date.now() - start;\n const statusCode =\n error instanceof HttpException\n ? error.getStatus()\n : HttpStatus.INTERNAL_SERVER_ERROR;\n\n this.logRequest({\n method,\n url,\n statusCode,\n duration,\n error,\n userId,\n requestId,\n });\n return throwError(() => error);\n }),\n );\n }\n\n private async logRequest({\n method,\n url,\n statusCode,\n duration,\n error,\n userId,\n requestId,\n }: {\n method: string;\n url: string;\n statusCode: number;\n duration: number;\n error?: any;\n userId?: string;\n requestId?: string;\n }) {\n if (!this.sysWatch || !this.sysWatch.log) {\n // Fail silently or warn if service is not injected correctly\n // This happens if the interceptor is instantiated manually without passing the service\n return Logger.error(\n \"SysWatchService not injected. LoggerInterceptor will not log requests.\",\n );\n }\n\n const message = `${method} ${url} ${statusCode} - ${duration}ms`;\n const meta = {\n method,\n url,\n statusCode,\n duration,\n slow: duration > 1000,\n ...(requestId && { requestId }),\n ...(error &&\n error instanceof Error && {\n error: error.message,\n exception: error.name,\n ...(\"code\" in error ? { code: error.code } : {}),\n ...(process.env.NODE_ENV !== \"production\"\n ? { stack: error.stack }\n : {}),\n }),\n };\n\n const statusCodeSuccess = statusCode.toString().startsWith(\"2\");\n const statusCodeFailure = statusCode.toString().startsWith(\"4\");\n const statusCodeError = statusCode.toString().startsWith(\"5\");\n\n if (statusCodeSuccess) {\n await this.sysWatch.log.success(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n if (statusCodeFailure) {\n await this.sysWatch.log.failure(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n if (statusCodeError) {\n await this.sysWatch.log.error(\"http_request\", message, {\n ...(userId && { userId }),\n meta,\n });\n }\n }\n}\n"],"mappings":"iOAAO,IAAMA,EAAmB,mBCAhC,OAAS,UAAAC,EAAQ,cAAAC,MAAkB,iBACnC,OAAS,YAAAC,MAAgB,iBAKlB,IAAMC,EAAN,cAA8BC,CAAS,CAC5C,YAAsCC,EAAgC,CACpE,MAAMA,CAAO,CACf,CACF,EAJaF,EAANG,EAAA,CADNC,EAAW,EAEGC,EAAA,EAAAC,EAAOC,CAAgB,IADzBP,GCNb,OAAwB,UAAAQ,EAAQ,UAAAC,MAAwB,iBAOjD,IAAMC,EAAN,KAAqB,CAC1B,OAAO,QAAQC,EAA+C,CAC5D,MAAO,CACL,OAAQD,EACR,UAAW,CACT,CACE,QAASE,EACT,SAAUD,CACZ,EACAE,CACF,EACA,QAAS,CAACA,CAAe,CAC3B,CACF,CAEA,OAAO,aAAaF,EAAoD,CACtE,MAAO,CACL,OAAQD,EACR,QAASC,EAAQ,SAAW,CAAC,EAC7B,UAAW,CACT,GAAG,KAAK,qBAAqBA,CAAO,EACpCE,CACF,EACA,QAAS,CAACA,CAAe,CAC3B,CACF,CAEA,OAAe,qBAAqBF,EAAiD,CACnF,OAAIA,EAAQ,aAAeA,EAAQ,WAC1B,CAAC,KAAK,2BAA2BA,CAAO,CAAC,EAE3C,CACL,KAAK,2BAA2BA,CAAO,EACvC,CACE,QAASA,EAAQ,SACjB,SAAUA,EAAQ,QACpB,CACF,CACF,CAEA,OAAe,2BAA2BA,EAA+C,CACvF,OAAIA,EAAQ,WACH,CACL,QAASC,EACT,WAAYD,EAAQ,WACpB,OAAQA,EAAQ,QAAU,CAAC,CAC7B,EAEK,CACL,QAASC,EACT,WAAY,MAAOE,GACjB,MAAMA,EAAe,sBAAsB,EAC7C,OAAQ,CAACH,EAAQ,aAAeA,EAAQ,QAAS,CACnD,CACF,CACF,EAvDaD,EAANK,EAAA,CAFNC,EAAO,EACPC,EAAO,CAAC,CAAC,GACGP,GCPb,OAGE,cAAAQ,EAEA,iBAAAC,EACA,cAAAC,EACA,UAAAC,EACA,UAAAC,MACK,iBACP,OAAqB,cAAAC,MAAkB,OACvC,OAAS,cAAAC,EAAY,OAAAC,MAAW,iBAIzB,IAAMC,EAAN,KAAmD,CACxD,YAC4CC,EAC1C,CAD0C,cAAAA,CACzC,CAEH,UAAUC,EAA2BC,EAAoC,CACvE,IAAMC,EAAUF,EAAQ,aAAa,EAAE,WAAW,EAC5C,CAAE,OAAAG,EAAQ,IAAAC,CAAI,EAAIF,EAClBG,EAAQ,KAAK,IAAI,EAEjBC,EACJJ,EAAQ,MAAS,IAAMA,EAAQ,MAAS,KAAOA,EAAQ,MAAS,IAE5DK,EACJL,EAAQ,IACRA,EAAQ,QAAQ,cAAc,GAC9BA,EAAQ,QAAQ,kBAAkB,EAEpC,OAAOD,EAAK,OAAO,EAAE,KACnBO,EAAI,IAAM,CAER,IAAMC,EADWT,EAAQ,aAAa,EAAE,YAAY,EACxB,WACtBU,EAAW,KAAK,IAAI,EAAIL,EAE9B,KAAK,WAAW,CACd,OAAAF,EACA,IAAAC,EACA,WAAAK,EACA,SAAAC,EACA,OAAAJ,EACA,UAAAC,CACF,CAAC,CACH,CAAC,EACDI,EAAYC,GAAU,CACpB,IAAMF,EAAW,KAAK,IAAI,EAAIL,EACxBI,EACJG,aAAiBC,EACbD,EAAM,UAAU,EAChBE,EAAW,sBAEjB,YAAK,WAAW,CACd,OAAAX,EACA,IAAAC,EACA,WAAAK,EACA,SAAAC,EACA,MAAAE,EACA,OAAAN,EACA,UAAAC,CACF,CAAC,EACMQ,EAAW,IAAMH,CAAK,CAC/B,CAAC,CACH,CACF,CAEA,MAAc,WAAW,CACvB,OAAAT,EACA,IAAAC,EACA,WAAAK,EACA,SAAAC,EACA,MAAAE,EACA,OAAAN,EACA,UAAAC,CACF,EAQG,CACD,GAAI,CAAC,KAAK,UAAY,CAAC,KAAK,SAAS,IAGnC,OAAOS,EAAO,MACZ,wEACF,EAGF,IAAMC,EAAU,GAAGd,CAAM,IAAIC,CAAG,IAAIK,CAAU,MAAMC,CAAQ,KACtDQ,EAAO,CACX,OAAAf,EACA,IAAAC,EACA,WAAAK,EACA,SAAAC,EACA,KAAMA,EAAW,IACjB,GAAIH,GAAa,CAAE,UAAAA,CAAU,EAC7B,GAAIK,GACFA,aAAiB,OAAS,CACxB,MAAOA,EAAM,QACb,UAAWA,EAAM,KACjB,GAAI,SAAUA,EAAQ,CAAE,KAAMA,EAAM,IAAK,EAAI,CAAC,EAC9C,GAAI,QAAQ,IAAI,WAAa,aACzB,CAAE,MAAOA,EAAM,KAAM,EACrB,CAAC,CACP,CACJ,EAEMO,EAAoBV,EAAW,SAAS,EAAE,WAAW,GAAG,EACxDW,EAAoBX,EAAW,SAAS,EAAE,WAAW,GAAG,EACxDY,EAAkBZ,EAAW,SAAS,EAAE,WAAW,GAAG,EAExDU,GACF,MAAM,KAAK,SAAS,IAAI,QAAQ,eAAgBF,EAAS,CACvD,GAAIX,GAAU,CAAE,OAAAA,CAAO,EACvB,KAAAY,CACF,CAAC,EAECE,GACF,MAAM,KAAK,SAAS,IAAI,QAAQ,eAAgBH,EAAS,CACvD,GAAIX,GAAU,CAAE,OAAAA,CAAO,EACvB,KAAAY,CACF,CAAC,EAECG,GACF,MAAM,KAAK,SAAS,IAAI,MAAM,eAAgBJ,EAAS,CACrD,GAAIX,GAAU,CAAE,OAAAA,CAAO,EACvB,KAAAY,CACF,CAAC,CAEL,CACF,EAzHapB,EAANwB,EAAA,CADNC,EAAW,EAGPC,EAAA,EAAAC,EAAOC,CAAe,IAFd5B","names":["SYSWATCH_OPTIONS","Inject","Injectable","SysWatch","SysWatchService","SysWatch","options","__decorateClass","Injectable","__decorateParam","Inject","SYSWATCH_OPTIONS","Global","Module","SysWatchModule","options","SYSWATCH_OPTIONS","SysWatchService","optionsFactory","__decorateClass","Global","Module","Injectable","HttpException","HttpStatus","Inject","Logger","throwError","catchError","tap","LoggerInterceptor","sysWatch","context","next","request","method","url","start","userId","requestId","tap","statusCode","duration","catchError","error","HttpException","HttpStatus","throwError","Logger","message","meta","statusCodeSuccess","statusCodeFailure","statusCodeError","__decorateClass","Injectable","__decorateParam","Inject","SysWatchService"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@syswatch/nestjs",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "NestJS module for SysWatch SDK",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@nestjs/common": ">=8.0.0",
|
|
26
|
+
"@nestjs/core": ">=8.0.0",
|
|
27
|
+
"@syswatch/core": "^1.x",
|
|
28
|
+
"rxjs": "^7.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@nestjs/common": "^10.0.0",
|
|
32
|
+
"@nestjs/core": "^10.0.0",
|
|
33
|
+
"@nestjs/platform-express": "^10.0.0",
|
|
34
|
+
"@syswatch/core": "file:../core/syswatch-core-1.0.2.tgz",
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"reflect-metadata": "^0.2.0",
|
|
37
|
+
"rxjs": "^7.8.1",
|
|
38
|
+
"tsup": "^8.5.1",
|
|
39
|
+
"typescript": "^5.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|