From 3c0f4bbccaab3ac96410e80d016cb73041f64c41 Mon Sep 17 00:00:00 2001 From: Roman Khabarov Date: Sun, 7 Jul 2024 22:56:53 +0200 Subject: [PATCH] Init --- .github/CODEOWNERS | 0 .github/COMMIT_CONVENTION.md | 0 .github/ISSUE_TEMPLATE/config.yml | 0 .github/ISSUE_TEMPLATE/feature_request.yml | 0 .github/PULL_REQUEST_TEMPLATE.md | 0 .github/dependabot.yml | 0 .github/husky/.gitignore | 0 .github/workflows/codeql-analysis.yml | 0 .gitignore | 0 .vscode/settings.json | 0 LICENSE | 0 README.md | 0 examples/app/.eslintrc.js | 0 examples/app/.gitignore | 0 examples/app/.prettierrc | 0 examples/app/README.md | 0 examples/app/nest-cli.json | 0 examples/app/package.json | 0 examples/app/src/app.controller.spec.ts | 0 examples/app/src/app.controller.ts | 0 examples/app/src/app.module.ts | 2 +- examples/app/src/app.service.ts | 6 ++ examples/app/src/main.ts | 0 examples/app/test/app.e2e-spec.ts | 0 examples/app/test/jest-e2e.json | 0 examples/app/tsconfig.build.json | 0 examples/app/tsconfig.json | 0 package.json | 0 packages/core/index.ts | 0 packages/core/package.json | 0 packages/core/src/context/index.ts | 7 ++ .../src/context/nestgram-arguments-host.ts | 29 +++++++ .../src/context/nestgram-base.discovery.ts | 44 +++++++++++ .../src/context/nestgram-context.interface.ts | 3 + .../src/context/nestgram-execution-context.ts | 14 ++++ .../src/context/nestgram-params.factory.ts | 20 +++++ .../src/context/nestgram-paramtype.enum.ts | 4 + packages/core/src/index.ts | 1 + .../src/listener/decorators/on.decorator.ts | 18 ----- .../core/src/listener/listeners.discovery.ts | 0 .../core/src/listener/listeners.module.ts | 19 ----- .../core/src/listeners/decorators/index.ts | 2 + .../decorators/listener.decorator.ts | 11 +++ .../src/listeners/decorators/on.decorator.ts | 11 +++ .../handlers/base.handler.ts | 2 +- .../{listener => listeners}/handlers/index.ts | 0 packages/core/src/listeners/index.ts | 6 ++ .../core/src/listeners/listener.discovery.ts | 27 +++++++ .../listeners.interfaces.ts | 0 .../core/src/listeners/listeners.module.ts | 32 ++++++++ .../core/src/nestgram-explorer.service.ts | 79 +++++++++++++++++++ .../core/src/nestgram-options.interface.ts | 0 .../core/src/nestgram.module-definition.ts | 2 +- packages/core/src/nestgram.module.ts | 8 +- .../core/src/providers/client.provider.ts | 0 packages/core/src/providers/index.ts | 0 packages/core/tsconfig.build.json | 0 packages/core/tsconfig.json | 0 packages/tsconfig.build.json | 0 pnpm-lock.yaml | 0 pnpm-workspace.yaml | 0 tsconfig.json | 0 62 files changed, 304 insertions(+), 43 deletions(-) mode change 100644 => 100755 .github/CODEOWNERS mode change 100644 => 100755 .github/COMMIT_CONVENTION.md mode change 100644 => 100755 .github/ISSUE_TEMPLATE/config.yml mode change 100644 => 100755 .github/ISSUE_TEMPLATE/feature_request.yml mode change 100644 => 100755 .github/PULL_REQUEST_TEMPLATE.md mode change 100644 => 100755 .github/dependabot.yml mode change 100644 => 100755 .github/husky/.gitignore mode change 100644 => 100755 .github/workflows/codeql-analysis.yml mode change 100644 => 100755 .gitignore mode change 100644 => 100755 .vscode/settings.json mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md mode change 100644 => 100755 examples/app/.eslintrc.js mode change 100644 => 100755 examples/app/.gitignore mode change 100644 => 100755 examples/app/.prettierrc mode change 100644 => 100755 examples/app/README.md mode change 100644 => 100755 examples/app/nest-cli.json mode change 100644 => 100755 examples/app/package.json mode change 100644 => 100755 examples/app/src/app.controller.spec.ts mode change 100644 => 100755 examples/app/src/app.controller.ts mode change 100644 => 100755 examples/app/src/app.module.ts mode change 100644 => 100755 examples/app/src/app.service.ts mode change 100644 => 100755 examples/app/src/main.ts mode change 100644 => 100755 examples/app/test/app.e2e-spec.ts mode change 100644 => 100755 examples/app/test/jest-e2e.json mode change 100644 => 100755 examples/app/tsconfig.build.json mode change 100644 => 100755 examples/app/tsconfig.json mode change 100644 => 100755 package.json mode change 100644 => 100755 packages/core/index.ts mode change 100644 => 100755 packages/core/package.json create mode 100755 packages/core/src/context/index.ts create mode 100755 packages/core/src/context/nestgram-arguments-host.ts create mode 100755 packages/core/src/context/nestgram-base.discovery.ts create mode 100644 packages/core/src/context/nestgram-context.interface.ts create mode 100644 packages/core/src/context/nestgram-execution-context.ts create mode 100644 packages/core/src/context/nestgram-params.factory.ts create mode 100644 packages/core/src/context/nestgram-paramtype.enum.ts mode change 100644 => 100755 packages/core/src/index.ts delete mode 100644 packages/core/src/listener/decorators/on.decorator.ts delete mode 100644 packages/core/src/listener/listeners.discovery.ts delete mode 100644 packages/core/src/listener/listeners.module.ts create mode 100755 packages/core/src/listeners/decorators/index.ts create mode 100755 packages/core/src/listeners/decorators/listener.decorator.ts create mode 100755 packages/core/src/listeners/decorators/on.decorator.ts rename packages/core/src/{listener => listeners}/handlers/base.handler.ts (86%) mode change 100644 => 100755 rename packages/core/src/{listener => listeners}/handlers/index.ts (100%) mode change 100644 => 100755 create mode 100755 packages/core/src/listeners/index.ts create mode 100755 packages/core/src/listeners/listener.discovery.ts rename packages/core/src/{listener => listeners}/listeners.interfaces.ts (100%) mode change 100644 => 100755 create mode 100755 packages/core/src/listeners/listeners.module.ts create mode 100755 packages/core/src/nestgram-explorer.service.ts mode change 100644 => 100755 packages/core/src/nestgram-options.interface.ts mode change 100644 => 100755 packages/core/src/nestgram.module-definition.ts mode change 100644 => 100755 packages/core/src/nestgram.module.ts mode change 100644 => 100755 packages/core/src/providers/client.provider.ts mode change 100644 => 100755 packages/core/src/providers/index.ts mode change 100644 => 100755 packages/core/tsconfig.build.json mode change 100644 => 100755 packages/core/tsconfig.json mode change 100644 => 100755 packages/tsconfig.build.json mode change 100644 => 100755 pnpm-lock.yaml mode change 100644 => 100755 pnpm-workspace.yaml mode change 100644 => 100755 tsconfig.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS old mode 100644 new mode 100755 diff --git a/.github/COMMIT_CONVENTION.md b/.github/COMMIT_CONVENTION.md old mode 100644 new mode 100755 diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml old mode 100644 new mode 100755 diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml old mode 100644 new mode 100755 diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md old mode 100644 new mode 100755 diff --git a/.github/dependabot.yml b/.github/dependabot.yml old mode 100644 new mode 100755 diff --git a/.github/husky/.gitignore b/.github/husky/.gitignore old mode 100644 new mode 100755 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/.vscode/settings.json b/.vscode/settings.json old mode 100644 new mode 100755 diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/examples/app/.eslintrc.js b/examples/app/.eslintrc.js old mode 100644 new mode 100755 diff --git a/examples/app/.gitignore b/examples/app/.gitignore old mode 100644 new mode 100755 diff --git a/examples/app/.prettierrc b/examples/app/.prettierrc old mode 100644 new mode 100755 diff --git a/examples/app/README.md b/examples/app/README.md old mode 100644 new mode 100755 diff --git a/examples/app/nest-cli.json b/examples/app/nest-cli.json old mode 100644 new mode 100755 diff --git a/examples/app/package.json b/examples/app/package.json old mode 100644 new mode 100755 diff --git a/examples/app/src/app.controller.spec.ts b/examples/app/src/app.controller.spec.ts old mode 100644 new mode 100755 diff --git a/examples/app/src/app.controller.ts b/examples/app/src/app.controller.ts old mode 100644 new mode 100755 diff --git a/examples/app/src/app.module.ts b/examples/app/src/app.module.ts old mode 100644 new mode 100755 index cd4d904..1642948 --- a/examples/app/src/app.module.ts +++ b/examples/app/src/app.module.ts @@ -6,7 +6,7 @@ import { NestGramModule } from '../../../packages/core'; @Module({ imports: [ NestGramModule.forRoot({ - token: process.env.TG_TOKEN, + token: '7261491149:AAEPXNCO6H5LZCFK7-jJW-bOVCY3i8Uv0c0', }), ], controllers: [AppController], diff --git a/examples/app/src/app.service.ts b/examples/app/src/app.service.ts old mode 100644 new mode 100755 index 927d7cc..097e8d6 --- a/examples/app/src/app.service.ts +++ b/examples/app/src/app.service.ts @@ -1,8 +1,14 @@ import { Injectable } from '@nestjs/common'; +import { On } from '../../../packages/core'; @Injectable() export class AppService { getHello(): string { return 'Hello World!'; } + + @On('message') + onReady() { + console.log(2); + } } diff --git a/examples/app/src/main.ts b/examples/app/src/main.ts old mode 100644 new mode 100755 diff --git a/examples/app/test/app.e2e-spec.ts b/examples/app/test/app.e2e-spec.ts old mode 100644 new mode 100755 diff --git a/examples/app/test/jest-e2e.json b/examples/app/test/jest-e2e.json old mode 100644 new mode 100755 diff --git a/examples/app/tsconfig.build.json b/examples/app/tsconfig.build.json old mode 100644 new mode 100755 diff --git a/examples/app/tsconfig.json b/examples/app/tsconfig.json old mode 100644 new mode 100755 diff --git a/package.json b/package.json old mode 100644 new mode 100755 diff --git a/packages/core/index.ts b/packages/core/index.ts old mode 100644 new mode 100755 diff --git a/packages/core/package.json b/packages/core/package.json old mode 100644 new mode 100755 diff --git a/packages/core/src/context/index.ts b/packages/core/src/context/index.ts new file mode 100755 index 0000000..cf4dd18 --- /dev/null +++ b/packages/core/src/context/index.ts @@ -0,0 +1,7 @@ +export * from './nestgram-base.discovery'; +export * from './nestgram-arguments-host'; +export * from './nestgram-execution-context'; +export * from './nestgram-context.interface'; +export * from './nestgram-execution-context'; +export * from './nestgram-params.factory'; +export * from './nestgram-paramtype.enum'; \ No newline at end of file diff --git a/packages/core/src/context/nestgram-arguments-host.ts b/packages/core/src/context/nestgram-arguments-host.ts new file mode 100755 index 0000000..ef70836 --- /dev/null +++ b/packages/core/src/context/nestgram-arguments-host.ts @@ -0,0 +1,29 @@ +import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host'; +import { ArgumentsHost } from '@nestjs/common'; +import { NestGramContextType } from './nestgram-execution-context'; +import { NestGramBaseDiscovery } from '.'; +import { ContextOf } from './nestgram-context.interface'; +import { NestGramEvents } from '../listeners'; + +export class NestGramArgumentsHost extends ExecutionContextHost { + public static create(context: ArgumentsHost): NestGramArgumentsHost { + const type = context.getType(); + const necContext = new NestGramArgumentsHost(context.getArgs()); + necContext.setType(type); + return necContext; + } + + public getType(): TContext { + return super.getType(); + } + + public getContext(): ContextOf; + public getContext(): T; + public getContext(): ContextOf { + return this.getArgByIndex(0); + } + + public getDiscovery(): NestGramBaseDiscovery { + return this.getArgByIndex(1); + } +} diff --git a/packages/core/src/context/nestgram-base.discovery.ts b/packages/core/src/context/nestgram-base.discovery.ts new file mode 100755 index 0000000..07941b7 --- /dev/null +++ b/packages/core/src/context/nestgram-base.discovery.ts @@ -0,0 +1,44 @@ +import { Reflector } from '@nestjs/core'; +import { ListenerDiscovery } from '../listeners'; + +interface DiscoveredItem { + class: new (...args: unknown[]) => unknown; + handler?: (...args: unknown[]) => void; +} + +export abstract class NestGramBaseDiscovery { + protected readonly reflector = new Reflector(); + + protected discovery: DiscoveredItem; + + protected contextCallback: (context: unknown, discovery: NestGramBaseDiscovery) => unknown; + + public constructor(public meta: T) {} + + public getClass() { + return this.discovery?.class; + } + + public getHandler() { + return this.discovery?.handler; + } + + public setDiscoveryMeta(meta: DiscoveredItem) { + this.discovery ||= meta; + } + + public setContextCallback(fn: (context: unknown, discovery: NestGramBaseDiscovery) => unknown) { + this.contextCallback ||= fn; + } + + public execute(context: unknown = []) { + return this.contextCallback(context, this); + } + + public isListener(): this is ListenerDiscovery { + return false; + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public abstract toJSON(): Record; +} diff --git a/packages/core/src/context/nestgram-context.interface.ts b/packages/core/src/context/nestgram-context.interface.ts new file mode 100644 index 0000000..294a144 --- /dev/null +++ b/packages/core/src/context/nestgram-context.interface.ts @@ -0,0 +1,3 @@ +import { NestGramEvents } from '../listeners'; + +export type ContextOf = E[K]; diff --git a/packages/core/src/context/nestgram-execution-context.ts b/packages/core/src/context/nestgram-execution-context.ts new file mode 100644 index 0000000..ad74e2c --- /dev/null +++ b/packages/core/src/context/nestgram-execution-context.ts @@ -0,0 +1,14 @@ +import { ContextType, ExecutionContext } from '@nestjs/common'; +import { NestGramArgumentsHost } from './nestgram-arguments-host'; + +export type NestGramContextType = 'nestgram' | ContextType; + +export class NestGramExecutionContext extends NestGramArgumentsHost { + public static create(context: ExecutionContext): NestGramExecutionContext { + const type = context.getType(); + const necContext = new NestGramExecutionContext(context.getArgs(), context.getClass(), context.getHandler()); + necContext.setType(type); + + return necContext; + } +} diff --git a/packages/core/src/context/nestgram-params.factory.ts b/packages/core/src/context/nestgram-params.factory.ts new file mode 100644 index 0000000..3596164 --- /dev/null +++ b/packages/core/src/context/nestgram-params.factory.ts @@ -0,0 +1,20 @@ +import { ParamsFactory } from '@nestjs/core/helpers/external-context-creator'; +import { NestGramParamType } from './nestgram-paramtype.enum'; +import { NestGramBaseDiscovery } from '.'; +import { ParamData } from '@nestjs/common'; + +export class NestGramParamsFactory implements ParamsFactory { + public exchangeKeyForValue(type: number, data: ParamData, args: [Array, NestGramBaseDiscovery]) { + if (!args) { + return null; + } + switch (type as NestGramParamType) { + case NestGramParamType.CONTEXT: + return args[0]; + case NestGramParamType.DISCOVERY: + return args[1]; + default: + return null; + } + } +} diff --git a/packages/core/src/context/nestgram-paramtype.enum.ts b/packages/core/src/context/nestgram-paramtype.enum.ts new file mode 100644 index 0000000..7667924 --- /dev/null +++ b/packages/core/src/context/nestgram-paramtype.enum.ts @@ -0,0 +1,4 @@ +export enum NestGramParamType { + CONTEXT, + DISCOVERY, +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts old mode 100644 new mode 100755 index d4ea5bc..7595972 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1 +1,2 @@ export * from './nestgram.module'; +export * from './listeners'; diff --git a/packages/core/src/listener/decorators/on.decorator.ts b/packages/core/src/listener/decorators/on.decorator.ts deleted file mode 100644 index 24e828d..0000000 --- a/packages/core/src/listener/decorators/on.decorator.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Listener } from './listener.decorator'; -import { NestGram } from '../listeners.interfaces'; -import 'reflect-metadata'; - -/** - * Decorator that marks a method as a listener for discord.js client. - * @param events - The event or events names. - * @returns The decorated method. - */ -export const On = (events: E | E[]): MethodDecorator => { - const eventsArray = Array.isArray(events) ? events : [events]; - - return (target: string, propertyKey: string | symbol, descriptor: PropertyDescriptor) => { - const decorators = eventsArray.map((event: E) => Listener({ type: 'on', event })); - - return Reflect.decorate(decorators, target, propertyKey, descriptor); - }; -}; diff --git a/packages/core/src/listener/listeners.discovery.ts b/packages/core/src/listener/listeners.discovery.ts deleted file mode 100644 index e69de29..0000000 diff --git a/packages/core/src/listener/listeners.module.ts b/packages/core/src/listener/listeners.module.ts deleted file mode 100644 index ef7f026..0000000 --- a/packages/core/src/listener/listeners.module.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {Module, OnApplicationBootstrap, OnModuleInit} from '@nestjs/common'; -import { Telegraf } from 'telegraf'; - -@Module({ - imports: [] -}) -export class ListenersModule implements OnModuleInit, OnApplicationBootstrap { - constructor( - private readonly client: Telegraf, - ) {} - - onModuleInit() { - // console.log(this.client.on()) - // throw new Error('Method not implemented.'); - } - onApplicationBootstrap() { - // throw new Error('Method not implemented.'); - } -} \ No newline at end of file diff --git a/packages/core/src/listeners/decorators/index.ts b/packages/core/src/listeners/decorators/index.ts new file mode 100755 index 0000000..76ece30 --- /dev/null +++ b/packages/core/src/listeners/decorators/index.ts @@ -0,0 +1,2 @@ +export * from './on.decorator'; +export * from './listener.decorator'; \ No newline at end of file diff --git a/packages/core/src/listeners/decorators/listener.decorator.ts b/packages/core/src/listeners/decorators/listener.decorator.ts new file mode 100755 index 0000000..ddea2c6 --- /dev/null +++ b/packages/core/src/listeners/decorators/listener.decorator.ts @@ -0,0 +1,11 @@ +import { ListenerDiscovery, ListenerMeta } from '../listener.discovery'; +import { Reflector } from '@nestjs/core'; + +/** + * Decorator that marks a method as a listener for discord.js client. + * @param options The listener options. + * @returns The decorated method. + */ +export const Listener = Reflector.createDecorator({ + transform: (options) => new ListenerDiscovery(options), +}); diff --git a/packages/core/src/listeners/decorators/on.decorator.ts b/packages/core/src/listeners/decorators/on.decorator.ts new file mode 100755 index 0000000..ee547cb --- /dev/null +++ b/packages/core/src/listeners/decorators/on.decorator.ts @@ -0,0 +1,11 @@ +import { NestGramEvents } from '../listeners.interfaces'; +import 'reflect-metadata'; +import { Listener } from './listener.decorator'; + +/** + * Decorator that marks a method as a listener for telegraf client. + * @param events - The event or events names. + * @returns The decorated method. + */ +export const On = (event: E) => + Listener({ type: 'on', event }); diff --git a/packages/core/src/listener/handlers/base.handler.ts b/packages/core/src/listeners/handlers/base.handler.ts old mode 100644 new mode 100755 similarity index 86% rename from packages/core/src/listener/handlers/base.handler.ts rename to packages/core/src/listeners/handlers/base.handler.ts index a8f4c60..6ce365b --- a/packages/core/src/listener/handlers/base.handler.ts +++ b/packages/core/src/listeners/handlers/base.handler.ts @@ -5,7 +5,7 @@ import { Guard, MaybeArray, NonemptyReadonlyArray } from 'telegraf/typings/core/ import { UpdateType } from 'telegraf/typings/telegram-types'; @Injectable() -export abstract class BaseHandler> { +export abstract class BaseHandler { @Inject(Telegraf) private readonly client: Telegraf; diff --git a/packages/core/src/listener/handlers/index.ts b/packages/core/src/listeners/handlers/index.ts old mode 100644 new mode 100755 similarity index 100% rename from packages/core/src/listener/handlers/index.ts rename to packages/core/src/listeners/handlers/index.ts diff --git a/packages/core/src/listeners/index.ts b/packages/core/src/listeners/index.ts new file mode 100755 index 0000000..9ac3357 --- /dev/null +++ b/packages/core/src/listeners/index.ts @@ -0,0 +1,6 @@ +export * from './listener.discovery'; +export * from './listener.discovery'; +export * from './listeners.interfaces'; +export * from './listeners.module'; + +export * from './decorators'; diff --git a/packages/core/src/listeners/listener.discovery.ts b/packages/core/src/listeners/listener.discovery.ts new file mode 100755 index 0000000..d5d9e68 --- /dev/null +++ b/packages/core/src/listeners/listener.discovery.ts @@ -0,0 +1,27 @@ +import { NestGramBaseDiscovery } from '../context'; + +export interface ListenerMeta { + type: 'on'; + event: string; +} + +/** + * Represents a listener discovery. + */ +export class ListenerDiscovery extends NestGramBaseDiscovery { + public getType() { + return this.meta.type; + } + + public getEvent() { + return this.meta.event.toString(); + } + + public isListener(): this is ListenerDiscovery { + return true; + } + + public override toJSON(): ListenerMeta { + return this.meta; + } +} diff --git a/packages/core/src/listener/listeners.interfaces.ts b/packages/core/src/listeners/listeners.interfaces.ts old mode 100644 new mode 100755 similarity index 100% rename from packages/core/src/listener/listeners.interfaces.ts rename to packages/core/src/listeners/listeners.interfaces.ts diff --git a/packages/core/src/listeners/listeners.module.ts b/packages/core/src/listeners/listeners.module.ts new file mode 100755 index 0000000..0f5bbab --- /dev/null +++ b/packages/core/src/listeners/listeners.module.ts @@ -0,0 +1,32 @@ +import {Module, OnApplicationBootstrap, OnModuleInit} from '@nestjs/common'; +import { Telegraf } from 'telegraf'; + +import * as CustomListeners from './handlers'; +import { DiscoveryModule } from '@nestjs/core'; +import { ExplorerService } from '../nestgram-explorer.service'; +import { ListenerDiscovery } from './listener.discovery'; +import { Listener } from './decorators'; + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const { BaseHandler, ...listeners } = CustomListeners; + +@Module({ + imports: [DiscoveryModule], + providers: Object.values(listeners), +}) +export class ListenersModule implements OnModuleInit { + constructor( + private readonly client: Telegraf, + private readonly explorerService: ExplorerService, + ) {} + + onModuleInit() { + const explorer = this.explorerService.explore(Listener.KEY); + + explorer.forEach((listener) => { + const eventType = listener.getType(); + const event = listener.getEvent(); + this.client[eventType](event, (...args: unknown[]) => listener.execute(args)); + }); + } +} \ No newline at end of file diff --git a/packages/core/src/nestgram-explorer.service.ts b/packages/core/src/nestgram-explorer.service.ts new file mode 100755 index 0000000..3cc2b70 --- /dev/null +++ b/packages/core/src/nestgram-explorer.service.ts @@ -0,0 +1,79 @@ +import { Injectable } from '@nestjs/common'; +import { NestGramBaseDiscovery, NestGramContextType, NestGramParamsFactory } from './context'; +import { DiscoveryService, MetadataScanner, Reflector } from '@nestjs/core'; +import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper'; +import { ExternalContextCreator } from '@nestjs/core/helpers/external-context-creator'; +import { ROUTE_ARGS_METADATA } from '@nestjs/common/constants'; +import { ParamMetadata } from '@nestjs/core/helpers/interfaces'; +import { STATIC_CONTEXT } from '@nestjs/core/injector/constants'; + +/** + * Represents a explorer service. + * This service is used to explore the application and retrieve the discovery items. + */ +@Injectable() +export class ExplorerService extends Reflector { + private readonly NestGramParamsFactory = new NestGramParamsFactory(); + + private readonly wrappers = this.discoveryService.getProviders().filter((wrapper) => { + const { instance } = wrapper; + const prototype = instance ? Object.getPrototypeOf(instance) : null; + + return instance && prototype && wrapper.isDependencyTreeStatic(); + }); + private readonly controllerWrappers = this.discoveryService.getControllers().filter((wrapper) => { + const { instance } = wrapper; + const prototype = instance ? Object.getPrototypeOf(instance) : null; + + return instance && prototype && wrapper.isDependencyTreeStatic(); + }); + + public constructor( + private readonly discoveryService: DiscoveryService, + private readonly externalContextCreator: ExternalContextCreator, + private readonly metadataScanner: MetadataScanner, + ) { + super(); + } + + public explore(metadataKey: string): T[] { + return this.flatMap((wrapper) => this.filterProperties(wrapper, metadataKey)); + } + + private flatMap(callback: (wrapper: InstanceWrapper) => T[]) { + return [ + ...this.wrappers.flatMap(callback).filter(Boolean), + ...this.controllerWrappers.flatMap(callback).filter(Boolean), + ]; + } + + private filterProperties({ instance }: InstanceWrapper, metadataKey: string) { + const prototype = Object.getPrototypeOf(instance); + + return this.metadataScanner.getAllMethodNames(prototype).map((methodName) => { + const item = this.get(metadataKey, instance[methodName]); + if (!item) { + return; + } + + item.setDiscoveryMeta({ class: instance.constructor, handler: instance[methodName] }); + item.setContextCallback(this.createContextCallback(instance, prototype, methodName)); + + return item; + }); + } + + private createContextCallback(instance: object, prototype: unknown, methodName: string) { + return this.externalContextCreator.create, NestGramContextType>( + instance, + prototype[methodName], + methodName, + ROUTE_ARGS_METADATA, + this.NestGramParamsFactory, + STATIC_CONTEXT, + undefined, + { guards: true, filters: true, interceptors: true }, + 'nestgram', + ); + } +} diff --git a/packages/core/src/nestgram-options.interface.ts b/packages/core/src/nestgram-options.interface.ts old mode 100644 new mode 100755 diff --git a/packages/core/src/nestgram.module-definition.ts b/packages/core/src/nestgram.module-definition.ts old mode 100644 new mode 100755 index f976023..b219cec --- a/packages/core/src/nestgram.module-definition.ts +++ b/packages/core/src/nestgram.module-definition.ts @@ -8,5 +8,5 @@ export const { ASYNC_OPTIONS_TYPE: NESTGRAM_ASYNC_OPTIONS_TYPE, } = new ConfigurableModuleBuilder() .setClassMethodName('forRoot') - .setFactoryMethodName('createNestCordOptions') + .setFactoryMethodName('createNestGramOptions') .build(); diff --git a/packages/core/src/nestgram.module.ts b/packages/core/src/nestgram.module.ts old mode 100644 new mode 100755 index b36750a..c3c656a --- a/packages/core/src/nestgram.module.ts +++ b/packages/core/src/nestgram.module.ts @@ -4,14 +4,16 @@ import { NestGramModuleOptions } from './nestgram-options.interface'; import { Telegraf } from 'telegraf'; import * as ProvidersMap from './providers'; import { ListenersModule } from './listeners/listeners.module'; +import { ExplorerService } from './nestgram-explorer.service'; +import { DiscoveryModule } from '@nestjs/core'; const Providers = Object.values(ProvidersMap); @Global() @Module({ - imports: [ListenersModule], - providers: [...Providers], - exports: [ListenersModule, ...Providers], + imports: [DiscoveryModule, ListenersModule], + providers: [ExplorerService, ...Providers], + exports: [ListenersModule, ExplorerService, ...Providers], }) export class NestGramModule extends ConfigurableModuleClass implements OnApplicationBootstrap, OnApplicationShutdown { public constructor( diff --git a/packages/core/src/providers/client.provider.ts b/packages/core/src/providers/client.provider.ts old mode 100644 new mode 100755 diff --git a/packages/core/src/providers/index.ts b/packages/core/src/providers/index.ts old mode 100644 new mode 100755 diff --git a/packages/core/tsconfig.build.json b/packages/core/tsconfig.build.json old mode 100644 new mode 100755 diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json old mode 100644 new mode 100755 diff --git a/packages/tsconfig.build.json b/packages/tsconfig.build.json old mode 100644 new mode 100755 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml old mode 100644 new mode 100755 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml old mode 100644 new mode 100755 diff --git a/tsconfig.json b/tsconfig.json old mode 100644 new mode 100755