mirror of
https://github.com/Maks1mS/nestjs-telegraf.git
synced 2024-12-23 22:52:59 +03:00
refactor(): use ExternalContextCreator
This commit is contained in:
parent
d7f397b375
commit
798494a5b2
@ -1,38 +0,0 @@
|
||||
import { NestContainer } from '@nestjs/core';
|
||||
import { BaseExceptionFilterContext } from '@nestjs/core/exceptions/base-exception-filter-context';
|
||||
import { EXCEPTION_FILTERS_METADATA } from '@nestjs/common/constants';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
import { TelegrafExceptionsHandler } from '../exceptions/telegraf-exceptions-handler';
|
||||
|
||||
export class FiltersContextCreator extends BaseExceptionFilterContext {
|
||||
constructor(container: NestContainer) {
|
||||
super(container);
|
||||
}
|
||||
|
||||
public create(
|
||||
instance: object,
|
||||
callback: (...args: any[]) => void,
|
||||
moduleKey: string,
|
||||
): TelegrafExceptionsHandler {
|
||||
this.moduleContext = moduleKey;
|
||||
|
||||
const exceptionHandler = new TelegrafExceptionsHandler();
|
||||
const filters = this.createContext(
|
||||
instance,
|
||||
callback,
|
||||
EXCEPTION_FILTERS_METADATA,
|
||||
);
|
||||
|
||||
if (isEmpty(filters)) {
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
exceptionHandler.setCustomFilters(filters.reverse());
|
||||
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
public getGlobalMetadata<T extends any[]>(): T {
|
||||
return [] as T;
|
||||
}
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
import { Controller, PipeTransform } from '@nestjs/common/interfaces';
|
||||
import { PipesContextCreator } from '@nestjs/core/pipes/pipes-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator';
|
||||
import { GuardsConsumer } from '@nestjs/core/guards/guards-consumer';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { InterceptorsConsumer } from '@nestjs/core/interceptors/interceptors-consumer';
|
||||
import {
|
||||
ContextUtils,
|
||||
ParamProperties,
|
||||
} from '@nestjs/core/helpers/context-utils';
|
||||
import { HandlerMetadataStorage } from '@nestjs/core/helpers/handler-metadata-storage';
|
||||
import { FORBIDDEN_MESSAGE } from '@nestjs/core/guards/constants';
|
||||
import { ParamsMetadata } from '@nestjs/core/helpers/interfaces';
|
||||
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
||||
|
||||
import { FiltersContextCreator } from './filters-context-creator';
|
||||
import { TelegrafContextType } from '../execution-context/telegraf-execution-context';
|
||||
import { TelegrafProxy } from './telegraf-proxy';
|
||||
import { TelegrafException } from '../errors';
|
||||
import {
|
||||
CUSTOM_LISTENER_AGRS_METADATA,
|
||||
LISTENER_ARGS_METADATA,
|
||||
} from '../telegraf.constants';
|
||||
import { TelegrafParamsFactory } from '../factories/telegraf-params-factory';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
|
||||
export type Update = Controller;
|
||||
type TelegrafParamProperties = ParamProperties & { metatype?: any };
|
||||
|
||||
export interface TelegrafHandlerMetadata {
|
||||
argsLength: number;
|
||||
paramtypes: any[];
|
||||
getParamsMetadata: (moduleKey: string) => TelegrafParamProperties[];
|
||||
}
|
||||
|
||||
export class TelegrafContextCreator {
|
||||
private readonly contextUtils = new ContextUtils();
|
||||
private readonly telegrafParamsFactory = new TelegrafParamsFactory();
|
||||
private readonly handlerMetadataStorage = new HandlerMetadataStorage<TelegrafHandlerMetadata>();
|
||||
|
||||
constructor(
|
||||
private readonly telegrafProxy: TelegrafProxy,
|
||||
private readonly exceptionFiltersContext: FiltersContextCreator,
|
||||
private readonly pipesContextCreator: PipesContextCreator,
|
||||
private readonly pipesConsumer: PipesConsumer,
|
||||
private readonly guardsContextCreator: GuardsContextCreator,
|
||||
private readonly guardsConsumer: GuardsConsumer,
|
||||
private readonly interceptorsContextCreator: InterceptorsContextCreator,
|
||||
private readonly interceptorsConsumer: InterceptorsConsumer,
|
||||
) {}
|
||||
|
||||
public create<T extends ParamsMetadata = ParamsMetadata>(
|
||||
instance: Update,
|
||||
methodRef: (...args: unknown[]) => void,
|
||||
moduleName: string,
|
||||
methodKey: string,
|
||||
): (...args: any[]) => Promise<void> {
|
||||
const contextType: TelegrafContextType = 'telegraf';
|
||||
const { argsLength, paramtypes, getParamsMetadata } = this.getMetadata<T>(
|
||||
instance,
|
||||
methodKey,
|
||||
contextType,
|
||||
);
|
||||
|
||||
const exceptionHandler = this.exceptionFiltersContext.create(
|
||||
instance,
|
||||
methodRef,
|
||||
moduleName,
|
||||
);
|
||||
|
||||
const pipes = this.pipesContextCreator.create(
|
||||
instance,
|
||||
methodRef,
|
||||
moduleName,
|
||||
);
|
||||
|
||||
const guards = this.guardsContextCreator.create(
|
||||
instance,
|
||||
methodRef,
|
||||
moduleName,
|
||||
);
|
||||
|
||||
const interceptors = this.interceptorsContextCreator.create(
|
||||
instance,
|
||||
methodRef,
|
||||
moduleName,
|
||||
);
|
||||
|
||||
const paramsMetadata = getParamsMetadata(moduleName);
|
||||
const paramsOptions = paramsMetadata
|
||||
? this.contextUtils.mergeParamsMetatypes(paramsMetadata, paramtypes)
|
||||
: [];
|
||||
const fnApplyPipes = this.createPipesFn(pipes, paramsOptions);
|
||||
|
||||
const fnCanActivate = this.createGuardsFn(
|
||||
guards,
|
||||
instance,
|
||||
methodRef,
|
||||
contextType,
|
||||
);
|
||||
|
||||
const handler = <TContext>(
|
||||
initialArgs: unknown[],
|
||||
ctx: TContext,
|
||||
next: Function,
|
||||
) => async () => {
|
||||
if (fnApplyPipes) {
|
||||
await fnApplyPipes(initialArgs, ctx, next);
|
||||
return methodRef.apply(instance, initialArgs);
|
||||
}
|
||||
return methodRef.apply(instance, [ctx, next]);
|
||||
};
|
||||
|
||||
const targetCallback = async <TContext>(ctx: TContext, next: Function) => {
|
||||
const initialArgs = this.contextUtils.createNullArray(argsLength);
|
||||
fnCanActivate && (await fnCanActivate([ctx, next]));
|
||||
|
||||
return this.interceptorsConsumer.intercept(
|
||||
interceptors,
|
||||
[ctx, next],
|
||||
instance,
|
||||
methodRef,
|
||||
handler(initialArgs, ctx, next),
|
||||
contextType,
|
||||
);
|
||||
};
|
||||
|
||||
return this.telegrafProxy.create(targetCallback, exceptionHandler);
|
||||
}
|
||||
|
||||
public getMetadata<
|
||||
TMetadata,
|
||||
TContext extends TelegrafContextType = TelegrafContextType
|
||||
>(
|
||||
instance: Controller,
|
||||
methodName: string,
|
||||
contextType: TContext,
|
||||
): TelegrafHandlerMetadata {
|
||||
const cachedMetadata = this.handlerMetadataStorage.get(
|
||||
instance,
|
||||
methodName,
|
||||
);
|
||||
if (cachedMetadata) return cachedMetadata;
|
||||
|
||||
const metadata =
|
||||
this.contextUtils.reflectCallbackMetadata<TMetadata>(
|
||||
instance,
|
||||
methodName,
|
||||
LISTENER_ARGS_METADATA,
|
||||
) || {};
|
||||
|
||||
const keys = Object.keys(metadata);
|
||||
const argsLength = this.contextUtils.getArgumentsLength(keys, metadata);
|
||||
const contextFactory = this.contextUtils.getContextFactory(
|
||||
contextType,
|
||||
instance,
|
||||
instance[methodName],
|
||||
);
|
||||
const getParamsMetadata = (moduleKey: string) =>
|
||||
this.exchangeKeysForValues(
|
||||
keys,
|
||||
metadata,
|
||||
moduleKey,
|
||||
this.telegrafParamsFactory,
|
||||
contextFactory,
|
||||
);
|
||||
|
||||
const paramtypes = this.contextUtils.reflectCallbackParamtypes(
|
||||
instance,
|
||||
methodName,
|
||||
);
|
||||
const handlerMetadata: TelegrafHandlerMetadata = {
|
||||
argsLength,
|
||||
paramtypes,
|
||||
getParamsMetadata,
|
||||
};
|
||||
this.handlerMetadataStorage.set(instance, methodName, handlerMetadata);
|
||||
return handlerMetadata;
|
||||
}
|
||||
|
||||
public exchangeKeysForValues<TMetadata = any>(
|
||||
keys: string[],
|
||||
metadata: TMetadata,
|
||||
moduleContext: string,
|
||||
paramsFactory: TelegrafParamsFactory,
|
||||
contextFactory: (args: unknown[]) => ExecutionContextHost,
|
||||
): ParamProperties[] {
|
||||
this.pipesContextCreator.setModuleContext(moduleContext);
|
||||
|
||||
return keys.map((key) => {
|
||||
const { index, data, pipes: pipesCollection } = metadata[key];
|
||||
const pipes = this.pipesContextCreator.createConcreteContext(
|
||||
pipesCollection,
|
||||
);
|
||||
const type = this.contextUtils.mapParamType(key);
|
||||
|
||||
if (key.includes(CUSTOM_LISTENER_AGRS_METADATA)) {
|
||||
const { factory } = metadata[key];
|
||||
const customExtractValue = this.contextUtils.getCustomFactory(
|
||||
factory,
|
||||
data,
|
||||
contextFactory,
|
||||
);
|
||||
return { index, extractValue: customExtractValue, type, data, pipes };
|
||||
}
|
||||
const numericType = Number(type);
|
||||
const extractValue = <TContext>(ctx: TContext, next: Function) =>
|
||||
paramsFactory.exchangeKeyForValue(numericType, ctx, next);
|
||||
|
||||
return { index, extractValue, type: numericType, data, pipes };
|
||||
});
|
||||
}
|
||||
|
||||
public createGuardsFn<TContext extends string = TelegrafContextType>(
|
||||
guards: any[],
|
||||
instance: Controller,
|
||||
callback: (...args: unknown[]) => any,
|
||||
contextType?: TContext,
|
||||
): Function | null {
|
||||
const canActivateFn = async (args: any[]) => {
|
||||
const canActivate = await this.guardsConsumer.tryActivate<TContext>(
|
||||
guards,
|
||||
args,
|
||||
instance,
|
||||
callback,
|
||||
contextType,
|
||||
);
|
||||
if (!canActivate) {
|
||||
throw new TelegrafException(FORBIDDEN_MESSAGE);
|
||||
}
|
||||
};
|
||||
return guards.length ? canActivateFn : null;
|
||||
}
|
||||
|
||||
public createPipesFn(
|
||||
pipes: PipeTransform[],
|
||||
paramsOptions: (ParamProperties & { metatype?: unknown })[],
|
||||
) {
|
||||
const pipesFn = async <TContext>(
|
||||
args: unknown[],
|
||||
ctx: TContext,
|
||||
next: Function,
|
||||
) => {
|
||||
const resolveParamValue = async (
|
||||
param: ParamProperties & { metatype?: unknown },
|
||||
) => {
|
||||
const {
|
||||
index,
|
||||
extractValue,
|
||||
type,
|
||||
data,
|
||||
metatype,
|
||||
pipes: paramPipes,
|
||||
} = param;
|
||||
const value = extractValue(ctx, next);
|
||||
|
||||
args[index] = await this.getParamValue(
|
||||
value,
|
||||
{ metatype, type, data },
|
||||
pipes.concat(paramPipes),
|
||||
);
|
||||
};
|
||||
await Promise.all(paramsOptions.map(resolveParamValue));
|
||||
};
|
||||
return paramsOptions.length ? pipesFn : null;
|
||||
}
|
||||
|
||||
public async getParamValue<T>(
|
||||
value: T,
|
||||
{ metatype, type, data }: { metatype: any; type: any; data: any },
|
||||
pipes: PipeTransform[],
|
||||
): Promise<any> {
|
||||
return isEmpty(pipes)
|
||||
? value
|
||||
: this.pipesConsumer.apply(value, { metatype, type, data }, pipes);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { EMPTY } from 'rxjs';
|
||||
import { isObservable } from '../helpers/is-observable.helper';
|
||||
import { TelegrafExceptionsHandler } from '../exceptions/telegraf-exceptions-handler';
|
||||
|
||||
export class TelegrafProxy {
|
||||
public create(
|
||||
targetCallback: <TContext>(ctx: TContext, next: Function) => Promise<any>,
|
||||
exceptionsHandler: TelegrafExceptionsHandler,
|
||||
): <TContext>(ctx: TContext, next: Function) => Promise<any> {
|
||||
return async <TContext>(ctx: TContext, next: Function) => {
|
||||
try {
|
||||
const result = await targetCallback(ctx, next);
|
||||
return !isObservable(result)
|
||||
? result
|
||||
: result.pipe(
|
||||
catchError((error) => {
|
||||
this.handleError(exceptionsHandler, [ctx, next], error);
|
||||
return EMPTY;
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
this.handleError(exceptionsHandler, [ctx, next], error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
handleError<T>(
|
||||
exceptionsHandler: TelegrafExceptionsHandler,
|
||||
args: unknown[],
|
||||
error: T,
|
||||
): void {
|
||||
const host = new ExecutionContextHost(args);
|
||||
host.setType('telegraf');
|
||||
exceptionsHandler.handle(error, host);
|
||||
}
|
||||
}
|
@ -1,15 +1,10 @@
|
||||
import { PipeTransform, Type } from '@nestjs/common';
|
||||
import { createPipesTelegrafParamDecorator } from '../../utils/param-decorator.util';
|
||||
import { createTelegrafPipesParamDecorator } from '../../utils/param-decorator.util';
|
||||
import { TelegrafParamtype } from '../../enums/telegraf-paramtype.enum';
|
||||
|
||||
export function MessageText(): ParameterDecorator;
|
||||
export function MessageText(
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator;
|
||||
export function MessageText(
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator {
|
||||
return createPipesTelegrafParamDecorator(TelegrafParamtype.MESSAGE_TEXT)(
|
||||
export function MessageText(...pipes: (Type<PipeTransform> | PipeTransform)[]) {
|
||||
return createTelegrafPipesParamDecorator(TelegrafParamtype.MESSAGE_TEXT)(
|
||||
undefined,
|
||||
...pipes,
|
||||
);
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
import { ArgumentsHost, Logger } from '@nestjs/common';
|
||||
import { MESSAGES } from '@nestjs/core/constants';
|
||||
import { Context } from 'telegraf';
|
||||
import { TelegrafExceptionFilter } from '../interfaces/telegraf-exception-filter.interface';
|
||||
import { TelegrafException } from '../errors';
|
||||
import { isErrorObject } from '../helpers/is-error-object.helper';
|
||||
import { TelegrafArgumentsHost } from '../execution-context';
|
||||
|
||||
export class BaseTelegrafExceptionFilter<TError = any>
|
||||
implements TelegrafExceptionFilter {
|
||||
private static readonly logger = new Logger('TelegrafExceptionsHandler');
|
||||
|
||||
catch(exception: TError, host: ArgumentsHost): void {
|
||||
const context = TelegrafArgumentsHost.create(host).getContext<Context>();
|
||||
this.handleError(exception, context);
|
||||
}
|
||||
|
||||
public handleError(exception: TError, context: Context): void {
|
||||
if (!(exception instanceof TelegrafException)) {
|
||||
return this.handleUnknownError(exception, context);
|
||||
}
|
||||
|
||||
context.reply(exception.message);
|
||||
}
|
||||
|
||||
public handleUnknownError(exception: TError, context: Context): void {
|
||||
context.reply(MESSAGES.UNKNOWN_EXCEPTION_MESSAGE);
|
||||
|
||||
const errorMessage = isErrorObject(exception)
|
||||
? exception.message
|
||||
: exception;
|
||||
BaseTelegrafExceptionFilter.logger.error(errorMessage);
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './base-telegraf-exception-filter';
|
@ -1,48 +0,0 @@
|
||||
import { ArgumentsHost } from '@nestjs/common';
|
||||
import { ExceptionFilterMetadata } from '@nestjs/common/interfaces/exceptions';
|
||||
import { BaseTelegrafExceptionFilter } from './base-telegraf-exception-filter';
|
||||
import { TelegrafException } from '../errors';
|
||||
import { InvalidExceptionFilterException } from '@nestjs/core/errors/exceptions/invalid-exception-filter.exception';
|
||||
import { isEmpty } from '@nestjs/common/utils/shared.utils';
|
||||
|
||||
export class TelegrafExceptionsHandler extends BaseTelegrafExceptionFilter {
|
||||
private filters: ExceptionFilterMetadata[] = [];
|
||||
|
||||
public handle(
|
||||
exception: Error | TelegrafException | any,
|
||||
host: ArgumentsHost,
|
||||
): void {
|
||||
const isFilterInvoked = this.invokeCustomFilters(exception, host);
|
||||
if (!isFilterInvoked) {
|
||||
super.catch(exception, host);
|
||||
}
|
||||
}
|
||||
|
||||
public invokeCustomFilters<T = any>(
|
||||
exception: T,
|
||||
args: ArgumentsHost,
|
||||
): boolean {
|
||||
if (isEmpty(this.filters)) return false;
|
||||
|
||||
const filter = this.filters.find(({ exceptionMetatypes }) => {
|
||||
const hasMetatype =
|
||||
!exceptionMetatypes.length ||
|
||||
exceptionMetatypes.some(
|
||||
(ExceptionMetatype) => exception instanceof ExceptionMetatype,
|
||||
);
|
||||
return hasMetatype;
|
||||
});
|
||||
|
||||
filter && filter.func(exception, args);
|
||||
|
||||
return !!filter;
|
||||
}
|
||||
|
||||
public setCustomFilters(filters: ExceptionFilterMetadata[]): void {
|
||||
if (!Array.isArray(filters)) {
|
||||
throw new InvalidExceptionFilterException();
|
||||
}
|
||||
|
||||
this.filters = filters;
|
||||
}
|
||||
}
|
@ -3,25 +3,18 @@ import { Injectable as IInjectable } from '@nestjs/common/interfaces/injectable.
|
||||
import { DiscoveryService, ModuleRef, ModulesContainer } from '@nestjs/core';
|
||||
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
|
||||
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
||||
import { PipesContextCreator } from '@nestjs/core/pipes/pipes-context-creator';
|
||||
import { PipesConsumer } from '@nestjs/core/pipes/pipes-consumer';
|
||||
import { GuardsContextCreator } from '@nestjs/core/guards/guards-context-creator';
|
||||
import { GuardsConsumer } from '@nestjs/core/guards/guards-consumer';
|
||||
import { InterceptorsContextCreator } from '@nestjs/core/interceptors/interceptors-context-creator';
|
||||
import { InterceptorsConsumer } from '@nestjs/core/interceptors/interceptors-consumer';
|
||||
import { isFunction, isNil } from '@nestjs/common/utils/shared.utils';
|
||||
import { fromPromise } from 'rxjs/internal-compatibility';
|
||||
import { filter, mergeAll } from 'rxjs/operators';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Context, Telegraf } from 'telegraf';
|
||||
import { TelegrafMetadataAccessor } from '../telegraf.metadata-accessor';
|
||||
import { TelegrafContextCreator } from '../context/telegraf-context-creator';
|
||||
import { TelegrafProxy } from '../context/telegraf-proxy';
|
||||
import { FiltersContextCreator } from '../context/filters-context-creator';
|
||||
import { ExternalContextCreator } from '@nestjs/core/helpers/external-context-creator';
|
||||
import { TelegrafParamsFactory } from '../factories/telegraf-params-factory';
|
||||
|
||||
@Injectable()
|
||||
export class TelegrafUpdateExplorer implements OnModuleInit {
|
||||
private readonly contextCreator: TelegrafContextCreator;
|
||||
private readonly telegrafParamsFactory = new TelegrafParamsFactory();
|
||||
|
||||
constructor(
|
||||
private readonly moduleRef: ModuleRef,
|
||||
@ -29,24 +22,9 @@ export class TelegrafUpdateExplorer implements OnModuleInit {
|
||||
private readonly discoveryService: DiscoveryService,
|
||||
private readonly metadataAccessor: TelegrafMetadataAccessor,
|
||||
private readonly metadataScanner: MetadataScanner,
|
||||
private readonly externalContextCreator: ExternalContextCreator,
|
||||
@Inject(Telegraf) private readonly telegraf: Telegraf<never>,
|
||||
) {
|
||||
this.contextCreator = this.getContextCreator();
|
||||
}
|
||||
|
||||
private getContextCreator(): TelegrafContextCreator {
|
||||
const { container } = this.moduleRef as any;
|
||||
return new TelegrafContextCreator(
|
||||
new TelegrafProxy(),
|
||||
new FiltersContextCreator(container),
|
||||
new PipesContextCreator(container),
|
||||
new PipesConsumer(),
|
||||
new GuardsContextCreator(container),
|
||||
new GuardsConsumer(),
|
||||
new InterceptorsContextCreator(container),
|
||||
new InterceptorsConsumer(),
|
||||
);
|
||||
}
|
||||
) {}
|
||||
|
||||
onModuleInit(): void {
|
||||
this.explore();
|
||||
@ -87,11 +65,20 @@ export class TelegrafUpdateExplorer implements OnModuleInit {
|
||||
moduleName: string,
|
||||
): void {
|
||||
const methodRef = instance[methodKey] as (...args: unknown[]) => unknown;
|
||||
const contextHandlerFn = this.contextCreator.create(
|
||||
const contextHandlerFn = this.externalContextCreator.create(
|
||||
instance,
|
||||
methodRef,
|
||||
moduleName,
|
||||
methodKey,
|
||||
this.telegrafParamsFactory,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
interceptors: true,
|
||||
filters: true,
|
||||
guards: true,
|
||||
},
|
||||
'telegraf',
|
||||
);
|
||||
|
||||
const listenerMetadata = this.metadataAccessor.getListenerMetadata(
|
||||
|
@ -1,5 +0,0 @@
|
||||
import { isObject } from '@nestjs/common/utils/shared.utils';
|
||||
|
||||
export function isErrorObject(err: any): err is Error {
|
||||
return isObject(err) && !!(err as Error).message;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import { isFunction } from '@nestjs/common/utils/shared.utils';
|
||||
|
||||
export function isObservable(result: any): boolean {
|
||||
return result && isFunction(result.subscribe);
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
import {
|
||||
CUSTOM_ROUTE_AGRS_METADATA,
|
||||
ROUTE_ARGS_METADATA,
|
||||
} from '@nestjs/common/constants';
|
||||
import { ROUTE_ARGS_METADATA } from '@nestjs/common/constants';
|
||||
|
||||
export const TELEGRAF_MODULE_OPTIONS = 'TELEGRAF_MODULE_OPTIONS';
|
||||
|
||||
@ -10,5 +7,4 @@ export const UPDATE_LISTENER_METADATA = 'UPDATE_LISTENER_METADATA';
|
||||
|
||||
export const SCENE_METADATA = 'SCENE_METADATA';
|
||||
|
||||
export const LISTENER_ARGS_METADATA = ROUTE_ARGS_METADATA;
|
||||
export const CUSTOM_LISTENER_AGRS_METADATA = CUSTOM_ROUTE_AGRS_METADATA;
|
||||
export const PARAM_ARGS_METADATA = ROUTE_ARGS_METADATA;
|
||||
|
@ -1,39 +1,86 @@
|
||||
import { assignMetadata, PipeTransform, Type } from '@nestjs/common';
|
||||
import { isNil, isString } from '@nestjs/common/utils/shared.utils';
|
||||
import { TelegrafParamtype } from '../enums/telegraf-paramtype.enum';
|
||||
import { LISTENER_ARGS_METADATA } from '../telegraf.constants';
|
||||
import { PARAM_ARGS_METADATA } from '../telegraf.constants';
|
||||
|
||||
export function createTelegrafParamDecorator(
|
||||
paramtype: TelegrafParamtype,
|
||||
): (...pipes: (Type<PipeTransform> | PipeTransform)[]) => ParameterDecorator {
|
||||
return (...pipes: (Type<PipeTransform> | PipeTransform)[]) => (
|
||||
target,
|
||||
key,
|
||||
index,
|
||||
) => {
|
||||
export type ParamData = object | string | number;
|
||||
|
||||
export const createTelegrafParamDecorator = (paramtype: TelegrafParamtype) => {
|
||||
return (data?: ParamData): ParameterDecorator => (target, key, index) => {
|
||||
const args =
|
||||
Reflect.getMetadata(LISTENER_ARGS_METADATA, target.constructor, key) ||
|
||||
{};
|
||||
Reflect.getMetadata(PARAM_ARGS_METADATA, target.constructor, key) || {};
|
||||
Reflect.defineMetadata(
|
||||
LISTENER_ARGS_METADATA,
|
||||
assignMetadata(args, paramtype, index, undefined, ...pipes),
|
||||
PARAM_ARGS_METADATA,
|
||||
assignMetadata(args, paramtype, index, data),
|
||||
target.constructor,
|
||||
key,
|
||||
);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const createPipesTelegrafParamDecorator = (
|
||||
export const createTelegrafPipesParamDecorator = (
|
||||
paramtype: TelegrafParamtype,
|
||||
) => (
|
||||
data?: any,
|
||||
...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
): ParameterDecorator => (target, key, index) => {
|
||||
addPipesMetadata(paramtype, data, pipes, target, key, index);
|
||||
};
|
||||
|
||||
export const addPipesMetadata = (
|
||||
paramtype: TelegrafParamtype,
|
||||
data: any,
|
||||
pipes: (Type<PipeTransform> | PipeTransform)[],
|
||||
target: Record<string, any>,
|
||||
key: string | symbol,
|
||||
index: number,
|
||||
) => {
|
||||
const args =
|
||||
Reflect.getMetadata(LISTENER_ARGS_METADATA, target.constructor, key) || {};
|
||||
Reflect.getMetadata(PARAM_ARGS_METADATA, target.constructor, key) || {};
|
||||
const hasParamData = isNil(data) || isString(data);
|
||||
const paramData = hasParamData ? data : undefined;
|
||||
const paramPipes = hasParamData ? pipes : [data, ...pipes];
|
||||
|
||||
Reflect.defineMetadata(
|
||||
LISTENER_ARGS_METADATA,
|
||||
assignMetadata(args, paramtype, index, undefined, ...pipes),
|
||||
PARAM_ARGS_METADATA,
|
||||
assignMetadata(args, paramtype, index, paramData, ...paramPipes),
|
||||
target.constructor,
|
||||
key,
|
||||
);
|
||||
};
|
||||
|
||||
// export function createTelegrafParamDecorator(
|
||||
// paramtype: TelegrafParamtype,
|
||||
// ): (...pipes: (Type<PipeTransform> | PipeTransform)[]) => ParameterDecorator {
|
||||
// return (...pipes: (Type<PipeTransform> | PipeTransform)[]) => (
|
||||
// target,
|
||||
// key,
|
||||
// index,
|
||||
// ) => {
|
||||
// const args =
|
||||
// Reflect.getMetadata(LISTENER_ARGS_METADATA, target.constructor, key) ||
|
||||
// {};
|
||||
// Reflect.defineMetadata(
|
||||
// LISTENER_ARGS_METADATA,
|
||||
// assignMetadata(args, paramtype, index, undefined, ...pipes),
|
||||
// target.constructor,
|
||||
// key,
|
||||
// );
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// export const createPipesTelegrafParamDecorator = (
|
||||
// paramtype: TelegrafParamtype,
|
||||
// ) => (
|
||||
// ...pipes: (Type<PipeTransform> | PipeTransform)[]
|
||||
// ): ParameterDecorator => (target, key, index) => {
|
||||
// const args =
|
||||
// Reflect.getMetadata(LISTENER_ARGS_METADATA, target.constructor, key) || {};
|
||||
//
|
||||
// Reflect.defineMetadata(
|
||||
// LISTENER_ARGS_METADATA,
|
||||
// assignMetadata(args, paramtype, index, undefined, ...pipes),
|
||||
// target.constructor,
|
||||
// key,
|
||||
// );
|
||||
// };
|
||||
|
Loading…
Reference in New Issue
Block a user