feat: complete proxy to fastify patch

This commit is contained in:
Shinwoo PARK 2025-03-27 01:35:01 +09:00
parent 0c722ae9d7
commit 9951c75549
10 changed files with 534 additions and 7 deletions

View File

@ -1,10 +1,4 @@
export {
LoggedRoute,
LoggedFunction,
LoggedController,
LoggedInjectable,
LoggedGuard,
LoggedInterceptor,
ScopedLogger,
InjectLogger,
LoggedParam,
@ -14,4 +8,13 @@ export {
Logged,
Returns,
getRequestLogger
} from 'nestlogged';
} from 'nestlogged';
export {
LoggedRoute,
LoggedFunction,
LoggedController,
LoggedInjectable,
LoggedGuard,
LoggedInterceptor,
LoggedMiddleware,
} from './logged'

View File

@ -0,0 +1,81 @@
import {
Injectable,
Controller,
ControllerOptions,
ScopeOptions,
} from '@nestjs/common';
import { loggerInit, RevRequestMethod } from 'nestlogged/lib/logged/utils';
import { LoggedRoute, LoggedFunction } from './methods';
export function LoggedInjectable(
options?: ScopeOptions & { verbose?: boolean },
) {
return (target: any) => {
loggerInit(target.prototype);
const logger = target.prototype.logger;
const methods = Object.getOwnPropertyNames(target.prototype);
methods.forEach((method) => {
if (
method !== 'constructor' &&
typeof target.prototype[method] === 'function'
) {
if (options && options.verbose)
logger.log(`LoggedFunction applied to ${method}`);
LoggedFunction()(target.prototype, method, {
value: target.prototype[method],
});
}
});
Injectable(options)(target);
};
}
export function LoggedController(): (target: any) => void;
export function LoggedController(
prefix: string | string[],
): (target: any) => void;
export function LoggedController(
options: ControllerOptions & { verbose?: boolean },
): (target: any) => void;
export function LoggedController(param?: any): (target: any) => void {
return (target: any) => {
loggerInit(target.prototype);
const logger = target.prototype.logger;
const methods = Object.getOwnPropertyNames(target.prototype);
let verbose =
typeof param === 'object' && Object.keys(param).includes('verbose')
? param.verbose
: false;
methods.forEach((method) => {
if (
method !== 'constructor' &&
typeof target.prototype[method] === 'function'
) {
if (verbose) {
const path = Reflect.getMetadata('path', target.prototype[method]);
const httpMethod = Reflect.getMetadata(
'method',
target.prototype[method],
);
logger.log(
`LoggedRoute applied to ${method} (${RevRequestMethod[httpMethod]} ${path})`,
);
}
LoggedRoute()(target.prototype, method, {
value: target.prototype[method],
});
}
});
Controller(param)(target);
};
}

View File

@ -0,0 +1,2 @@
export * from './methods';
export { LoggedController, LoggedInjectable } from './class';

View File

@ -0,0 +1,90 @@
import { Logger } from '@nestjs/common';
import { OverrideBuildOptions, loggerInit } from 'nestlogged/lib/logged/utils';
import { LoggedMetadata, nestLoggedMetadata } from 'nestlogged/lib/logged/metadata';
import {
loggedParam,
scopedLogger,
returns,
ReturnsReflectData,
LoggedParamReflectData,
} from 'nestlogged/lib/reflected';
import { overrideBuild } from '../override';
export function LoggedFunction<F extends Array<any>, R>(
options?: Partial<OverrideBuildOptions>,
) {
return (
_target: any,
key: string,
descriptor: TypedPropertyDescriptor<(...args: F) => R | Promise<R>>,
) => {
loggerInit(_target);
const logger: Logger = _target.logger;
const fn = descriptor.value;
if (!fn || typeof fn !== 'function') {
logger.warn(
`LoggedFunction decorator applied to non-function property: ${key}`,
);
return;
}
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key,
);
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options);
return;
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [
k,
Reflect.getMetadata(k, fn),
]);
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
scopedLogger,
_target,
key,
);
const loggedParams: LoggedParamReflectData[] = Reflect.getOwnMetadata(
loggedParam,
_target,
key,
);
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
returns,
fn,
);
const overrideFunction = overrideBuild(
'function',
fn,
logger,
{
scopedLoggerInjectableParam,
loggedParams,
},
key,
returnsData,
newMetadata,
);
_target[key] = overrideFunction;
descriptor.value = overrideFunction;
Reflect.defineMetadata(nestLoggedMetadata, newMetadata, _target, key);
all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value);
});
};
}

View File

@ -0,0 +1,80 @@
import { ExecutionContext, Logger } from '@nestjs/common';
import { OverrideBuildOptions, loggerInit } from 'nestlogged/lib/logged/utils';
import { LoggedMetadata, nestLoggedMetadata } from 'nestlogged/lib/logged/metadata';
import { scopedLogger, returns, ReturnsReflectData } from 'nestlogged/lib/reflected';
import { overrideBuild } from '../override';
export function LoggedGuard<F extends Array<any>, R>(
options?: Partial<OverrideBuildOptions>,
) {
return (
_target: any,
key: string,
descriptor: TypedPropertyDescriptor<
(context: ExecutionContext, ...args: F) => R
>,
) => {
loggerInit(_target);
const logger: Logger = _target.logger;
const fn = descriptor.value;
if (!fn || typeof fn !== 'function') {
logger.warn(
`LoggedGuard decorator applied to non-function property: ${key}`,
);
return;
}
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key,
);
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options);
return;
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [
k,
Reflect.getMetadata(k, fn),
]);
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
scopedLogger,
_target,
key,
);
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
returns,
fn,
);
const overrideFunction = overrideBuild(
'guard',
fn,
logger,
{
scopedLoggerInjectableParam,
loggedParams: [],
},
_target.constructor.name,
returnsData,
newMetadata,
);
_target[key] = overrideFunction;
descriptor.value = overrideFunction;
Reflect.defineMetadata(nestLoggedMetadata, newMetadata, _target, key);
all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value);
});
};
}

View File

@ -0,0 +1,5 @@
export { LoggedFunction } from './function';
export { LoggedRoute } from './route';
export { LoggedGuard } from './guard';
export { LoggedInterceptor } from './interceptor';
export { LoggedMiddleware } from './middleware';

View File

@ -0,0 +1,81 @@
import { OverrideBuildOptions } from 'nestlogged/lib/logged/utils';
import { ExecutionContext, Logger } from '@nestjs/common';
import { loggerInit } from 'nestlogged/lib/logged/utils';
import { LoggedMetadata, nestLoggedMetadata } from 'nestlogged/lib/logged/metadata';
import { scopedLogger, returns, ReturnsReflectData } from 'nestlogged/lib/reflected';
import { overrideBuild } from '../override';
export function LoggedInterceptor<F extends Array<any>, R>(
options?: Partial<OverrideBuildOptions>,
) {
return (
_target: any,
key: string,
descriptor: TypedPropertyDescriptor<
(context: ExecutionContext, ...args: F) => R
>,
) => {
loggerInit(_target);
const logger: Logger = _target.logger;
const fn = descriptor.value;
if (!fn || typeof fn !== 'function') {
logger.warn(
`LoggedInterceptor decorator applied to non-function property: ${key}`,
);
return;
}
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key,
);
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options);
return;
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [
k,
Reflect.getMetadata(k, fn),
]);
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
scopedLogger,
_target,
key,
);
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
returns,
fn,
);
const overrideFunction = overrideBuild(
'interceptor',
fn,
logger,
{
scopedLoggerInjectableParam,
loggedParams: [],
},
_target.constructor.name,
returnsData,
newMetadata,
);
_target[key] = overrideFunction;
descriptor.value = overrideFunction;
Reflect.defineMetadata(nestLoggedMetadata, newMetadata, _target, key);
all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value);
});
};
}

View File

@ -0,0 +1,81 @@
import { OverrideBuildOptions } from 'nestlogged/lib/logged/utils';
import { Logger } from '@nestjs/common';
import { loggerInit } from 'nestlogged/lib/logged/utils';
import { LoggedMetadata, nestLoggedMetadata } from 'nestlogged/lib/logged/metadata';
import { scopedLogger, returns, ReturnsReflectData } from 'nestlogged/lib/reflected';
import { overrideBuild } from '../override';
export function LoggedMiddleware<F extends Array<any>, R>(
options?: Partial<OverrideBuildOptions>,
) {
return (
_target: any,
key: string,
descriptor: TypedPropertyDescriptor<
(...args: F) => R
>,
) => {
loggerInit(_target);
const logger: Logger = _target.logger;
const fn = descriptor.value;
if (!fn || typeof fn !== 'function') {
logger.warn(
`LoggedMiddleware decorator applied to non-function property: ${key}`,
);
return;
}
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key,
);
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options);
return;
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [
k,
Reflect.getMetadata(k, fn),
]);
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
scopedLogger,
_target,
key,
);
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
returns,
fn,
);
const overrideFunction = overrideBuild(
'middleware',
fn,
logger,
{
scopedLoggerInjectableParam,
loggedParams: [],
},
_target.constructor.name,
returnsData,
newMetadata,
);
_target[key] = overrideFunction;
descriptor.value = overrideFunction;
Reflect.defineMetadata(nestLoggedMetadata, newMetadata, _target, key);
all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value);
});
};
}

View File

@ -0,0 +1,104 @@
import { RequestMethod } from '@nestjs/common';
import { OverrideBuildOptions, loggerInit, RevRequestMethod } from 'nestlogged/lib/logged/utils';
import { LoggedMetadata, nestLoggedMetadata } from 'nestlogged/lib/logged/metadata';
import {
loggedParam,
scopedLogger,
returns,
ReturnsReflectData,
LoggedParamReflectData,
} from 'nestlogged/lib/reflected';
import { overrideBuild } from '../override';
import { createRouteParamDecorator } from 'nestlogged/lib/internals/nest';
export function LoggedRoute<F extends Array<any>, R>(
route?: string,
options?: Partial<OverrideBuildOptions>,
) {
return (
_target: any,
key: string,
descriptor: TypedPropertyDescriptor<(...args: F) => R>,
) => {
loggerInit(_target);
const logger = _target.logger;
const fn = descriptor.value;
if (!fn || typeof fn !== 'function') {
logger.warn(
`LoggedRoute decorator applied to non-function property: ${key}`,
);
return;
}
const logMetadata: LoggedMetadata | undefined = Reflect.getOwnMetadata(
nestLoggedMetadata,
_target,
key,
);
if (logMetadata) {
// already applied, override instead
logMetadata.updateOption(options);
return;
}
const newMetadata = new LoggedMetadata(options);
const all = Reflect.getMetadataKeys(fn).map((k) => [
k,
Reflect.getMetadata(k, fn),
]);
const httpPath: string = Reflect.getMetadata('path', fn);
const httpMethod: RequestMethod = Reflect.getMetadata('method', fn);
const fullRoute = `${_target.constructor.name}::${route ?? httpPath}[${
RevRequestMethod[httpMethod]
}]`;
const scopedLoggerInjectableParam: number = Reflect.getOwnMetadata(
scopedLogger,
_target,
key,
);
// if @InjectLogger exists, fake nestjs as it is @Req()
if (scopedLoggerInjectableParam !== undefined) {
createRouteParamDecorator(0)()(_target, key, scopedLoggerInjectableParam);
}
const loggedParams: LoggedParamReflectData[] = Reflect.getOwnMetadata(
loggedParam,
_target,
key,
);
const returnsData: ReturnsReflectData[] | true = Reflect.getOwnMetadata(
returns,
fn,
);
const overrideFunction = overrideBuild(
'route',
fn,
logger,
{
scopedLoggerInjectableParam,
loggedParams,
},
key,
returnsData,
newMetadata,
fullRoute,
);
_target[key] = overrideFunction;
descriptor.value = overrideFunction;
Reflect.defineMetadata(nestLoggedMetadata, newMetadata, _target, key);
all.forEach(([k, v]) => {
Reflect.defineMetadata(k, v, _target[key]);
Reflect.defineMetadata(k, v, descriptor.value);
});
};
}