@pikokr/command.ts 5.0.0-dev.6f835eb → 5.0.0-dev.97799e9

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.
@@ -9,14 +9,14 @@
9
9
  # the `language` matrix defined below to confirm you have the correct set of
10
10
  # supported CodeQL languages.
11
11
  #
12
- name: "CodeQL"
12
+ name: 'CodeQL'
13
13
 
14
14
  on:
15
15
  push:
16
- branches: [ dev ]
16
+ branches: [dev]
17
17
  pull_request:
18
18
  # The branches below must be a subset of the branches above
19
- branches: [ dev ]
19
+ branches: [dev]
20
20
  schedule:
21
21
  - cron: '31 4 * * 2'
22
22
 
@@ -32,39 +32,39 @@ jobs:
32
32
  strategy:
33
33
  fail-fast: false
34
34
  matrix:
35
- language: [ 'javascript' ]
35
+ language: ['javascript']
36
36
  # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37
37
  # Learn more about CodeQL language support at https://git.io/codeql-language-support
38
38
 
39
39
  steps:
40
- - name: Checkout repository
41
- uses: actions/checkout@v2
40
+ - name: Checkout repository
41
+ uses: actions/checkout@v2
42
42
 
43
- # Initializes the CodeQL tools for scanning.
44
- - name: Initialize CodeQL
45
- uses: github/codeql-action/init@v1
46
- with:
47
- languages: ${{ matrix.language }}
48
- # If you wish to specify custom queries, you can do so here or in a config file.
49
- # By default, queries listed here will override any specified in a config file.
50
- # Prefix the list here with "+" to use these queries and those in the config file.
51
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
43
+ # Initializes the CodeQL tools for scanning.
44
+ - name: Initialize CodeQL
45
+ uses: github/codeql-action/init@v1
46
+ with:
47
+ languages: ${{ matrix.language }}
48
+ # If you wish to specify custom queries, you can do so here or in a config file.
49
+ # By default, queries listed here will override any specified in a config file.
50
+ # Prefix the list here with "+" to use these queries and those in the config file.
51
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
52
52
 
53
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54
- # If this step fails, then you should remove it and run the build manually (see below)
55
- - name: Autobuild
56
- uses: github/codeql-action/autobuild@v1
53
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
54
+ # If this step fails, then you should remove it and run the build manually (see below)
55
+ - name: Autobuild
56
+ uses: github/codeql-action/autobuild@v1
57
57
 
58
- # ℹ️ Command-line programs to run using the OS shell.
59
- # 📚 https://git.io/JvXDl
58
+ # ℹ️ Command-line programs to run using the OS shell.
59
+ # 📚 https://git.io/JvXDl
60
60
 
61
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62
- # and modify them (or add more) to build your code if your project
63
- # uses a compiled language
61
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
62
+ # and modify them (or add more) to build your code if your project
63
+ # uses a compiled language
64
64
 
65
- #- run: |
66
- # make bootstrap
67
- # make release
65
+ #- run: |
66
+ # make bootstrap
67
+ # make release
68
68
 
69
- - name: Perform CodeQL Analysis
70
- uses: github/codeql-action/analyze@v1
69
+ - name: Perform CodeQL Analysis
70
+ uses: github/codeql-action/analyze@v1
@@ -76,4 +76,4 @@ jobs:
76
76
  git config user.email 41898282+github-actions[bot]@users.noreply.github.com
77
77
  git add .
78
78
  git commit -m "Docs build for ${BRANCH_OR_TAG} ${BRANCH_NAME}: ${SHA}" || true
79
- git push
79
+ git push
@@ -1,10 +1,10 @@
1
1
  {
2
- "license-header-manager.additionalCommentStyles": [
3
- {
4
- "extension": ".ts",
5
- "commentStart": "/*",
6
- "commentEnd": "*/",
7
- "commentMiddle": "*"
8
- }
9
- ]
10
- }
2
+ "license-header-manager.additionalCommentStyles": [
3
+ {
4
+ "extension": ".ts",
5
+ "commentStart": "/*",
6
+ "commentEnd": "*/",
7
+ "commentMiddle": "*"
8
+ }
9
+ ]
10
+ }
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![.github/workflows/publish.yml](https://github.com/pikokr/command.ts/actions/workflows/publish.yml/badge.svg)](https://github.com/pikokr/command.ts/actions/workflows/publish.yml) <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4
4
  [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-)
5
+
5
6
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
6
7
 
7
8
  ![cts](https://user-images.githubusercontent.com/68010770/145200458-b14c5e4e-6927-4516-8d48-c68a384d2a20.png)
@@ -11,6 +12,7 @@ Command framework for discord.js
11
12
  [Discord](https://discord.gg/EEhcPzsGHV) / [문서](https://v3.cts.pikokr.dev) / [V2 문서](https://command-ts-docs-ezojnktwv-pikokr.vercel.app/)
12
13
 
13
14
  ## Contributors
15
+
14
16
  <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
15
17
  <!-- prettier-ignore-start -->
16
18
  <!-- markdownlint-disable -->
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- import { Collection, APIApplicationCommandOption } from 'discord.js';
1
+ import * as discord_js from 'discord.js';
2
+ import { Collection, Snowflake, Interaction, ChatInputCommandInteraction, MessageContextMenuCommandInteraction, UserContextMenuCommandInteraction, Client, UserApplicationCommandData, MessageApplicationCommandData, ChatInputApplicationCommandData, ApplicationCommandType, APIApplicationCommandOption } from 'discord.js';
3
+ import EventEmitter from 'events';
4
+ import { Logger } from 'tslog';
2
5
 
3
6
  declare class ComponentArgumentDecorator<Options = unknown> {
4
7
  options: Options;
@@ -12,32 +15,101 @@ declare class ComponentArgument {
12
15
  constructor(type: unknown);
13
16
  }
14
17
 
15
- declare class BaseComponent<Options = unknown> {
18
+ declare class BaseComponent<Options = unknown, OptionsArg = Options> {
16
19
  options: Options;
17
20
  method: Function;
18
21
  argTypes: Collection<number, ComponentArgument>;
19
- constructor(options: Partial<Options>, method: Function, argTypes: unknown[]);
20
- defaultOptions(): Options;
22
+ constructor(options: OptionsArg, method: Function, argTypes: unknown[]);
23
+ convertOptions(options: OptionsArg): Options;
21
24
  execute(target: object, args: unknown[]): any;
22
25
  }
23
26
 
24
27
  declare type ComponentStore = Collection<string | symbol, BaseComponent>;
25
28
  declare type ComponentArgumentStore = Collection<number, ComponentArgumentDecorator>;
26
29
  declare const getComponentStore: (target: object) => ComponentStore;
27
- declare const getComponent: (target: object, key: string | symbol) => BaseComponent<unknown> | undefined;
28
- declare const createComponentDecorator: <Options>(type: {
29
- new (options: Partial<Options>, method: Function, argTypes: unknown[]): BaseComponent<Options>;
30
- }) => (options: Options) => MethodDecorator;
30
+ declare const getComponent: (target: object, key: string | symbol) => BaseComponent<unknown, unknown> | undefined;
31
+ declare const createComponentDecorator: <Options, OptionArgs>(type: {
32
+ new (options: OptionArgs, method: Function, argTypes: unknown[]): BaseComponent<Options, OptionArgs>;
33
+ }) => (options: OptionArgs) => MethodDecorator;
31
34
  declare const getComponentArgumentStore: (target: object, key: string | symbol) => ComponentArgumentStore;
32
35
  declare const createArgumentDecorator: <Options>(type: {
33
36
  new (options: Partial<Options>): ComponentArgumentDecorator<Options>;
34
37
  }) => (options: Options) => ParameterDecorator;
35
38
 
36
- declare const applicationCommand: (options: {
37
- name: string;
38
- description: string;
39
+ declare class Extension {
40
+ protected get commandClient(): CommandClient;
41
+ protected get client(): discord_js.Client<boolean>;
42
+ private _logger?;
43
+ protected get logger(): Logger;
44
+ protected convertArguments(component: typeof BaseComponent<unknown>, argList: unknown[], args: Collection<number, ComponentArgument>, getConverterArgs: (arg: ComponentArgument, index: number) => unknown[] | Promise<unknown[]>): Promise<void>;
45
+ }
46
+
47
+ declare type ApplicationCommandExtensionConfig = {
48
+ guilds?: Snowflake[];
49
+ };
50
+ declare class ApplicationCommandExtension extends Extension {
51
+ config: ApplicationCommandExtensionConfig;
52
+ constructor(config: ApplicationCommandExtensionConfig);
53
+ interactionCreate(i: Interaction): Promise<void>;
54
+ load(): Promise<void>;
55
+ sync(): Promise<void>;
56
+ chatInteraction(i: ChatInputCommandInteraction): Promise<ChatInputCommandInteraction<discord_js.CacheType>>;
57
+ messageInteraction(i: MessageContextMenuCommandInteraction): Promise<MessageContextMenuCommandInteraction<discord_js.CacheType>>;
58
+ userInteraction(i: UserContextMenuCommandInteraction): Promise<UserContextMenuCommandInteraction<discord_js.CacheType>>;
59
+ }
60
+
61
+ declare class CommandClient extends EventEmitter {
62
+ discord: Client;
63
+ logger: Logger;
64
+ ctsLogger: Logger;
65
+ registry: Registry;
66
+ constructor(discord: Client, logger?: Logger);
67
+ enableApplicationCommandsExtension(config: ApplicationCommandExtensionConfig): Promise<void>;
68
+ getApplicationCommandsExtension(): ApplicationCommandExtension | undefined;
69
+ static getFromModule(ext: object): CommandClient;
70
+ }
71
+
72
+ declare class Registry {
73
+ client: CommandClient;
74
+ extensions: object[];
75
+ emitters: Collection<string, EventEmitter>;
76
+ logger: Logger;
77
+ constructor(logger: Logger, client: CommandClient);
78
+ getComponentsWithTypeGlobal<T extends typeof BaseComponent<Config>, Config>(type: T): InstanceType<T>[];
79
+ getComponentsWithType<T extends typeof BaseComponent<Config>, Config>(ext: object, type: T): InstanceType<T>[];
80
+ registerEventListeners(ext: object): void;
81
+ unregisterEventListeners(ext: object): void;
82
+ registerModule(ext: object): Promise<void>;
83
+ unregisterModule(ext: object): Promise<void>;
84
+ runModuleHook(ext: object, hookName: string, ...args: unknown[]): void;
85
+ registerEventEmitter(name: string, emitter: EventEmitter): void;
86
+ }
87
+
88
+ declare type ModuleHookStore = Collection<string | symbol, Function[]>;
89
+ declare const getModuleHookStore: (target: object) => ModuleHookStore;
90
+ declare const moduleHook: (name: string) => MethodDecorator;
91
+
92
+ declare type Options = {
93
+ component: typeof BaseComponent<unknown>;
94
+ type: Function;
95
+ parameterless: boolean;
96
+ };
97
+ declare class ConverterComponent extends BaseComponent<Options, Options & {
98
+ parameterless?: boolean;
99
+ }> {
100
+ }
101
+ declare const argConverter: (options: Options & {
102
+ parameterless?: boolean | undefined;
103
+ }) => MethodDecorator;
104
+
105
+ declare class ApplicationCommandComponent extends BaseComponent<(UserApplicationCommandData | MessageApplicationCommandData | Omit<ChatInputApplicationCommandData, 'options'>) & {
106
+ type: ApplicationCommandType;
107
+ }> {
108
+ }
109
+ declare const applicationCommand: (options: (UserApplicationCommandData | MessageApplicationCommandData | Omit<ChatInputApplicationCommandData, "options">) & {
110
+ type: ApplicationCommandType;
39
111
  }) => MethodDecorator;
40
112
 
41
113
  declare const option: (options: APIApplicationCommandOption) => ParameterDecorator;
42
114
 
43
- export { BaseComponent, applicationCommand, createArgumentDecorator, createComponentDecorator, getComponent, getComponentArgumentStore, getComponentStore, option };
115
+ export { ApplicationCommandComponent, BaseComponent, CommandClient, ConverterComponent, Registry, applicationCommand, argConverter, createArgumentDecorator, createComponentDecorator, getComponent, getComponentArgumentStore, getComponentStore, getModuleHookStore, moduleHook, option };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var E=Object.create;var m=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,F=Object.prototype.hasOwnProperty;var b=e=>m(e,"__esModule",{value:!0}),r=(e,t)=>m(e,"name",{value:t,configurable:!0});var G=(e,t)=>{for(var o in t)m(e,o,{get:t[o],enumerable:!0})},w=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of z(t))!F.call(e,n)&&(o||n!=="default")&&m(e,n,{get:()=>t[n],enumerable:!(s=q(t,n))||s.enumerable});return e},R=(e,t)=>w(b(m(e!=null?E(B(e)):{},"default",!t&&e&&e.__esModule?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e),H=(e=>(t,o)=>e&&e.get(t)||(o=w(b({}),t,1),e&&e.set(t,o),o))(typeof WeakMap!="undefined"?new WeakMap:0);var J={};G(J,{BaseComponent:()=>a,applicationCommand:()=>O,createArgumentDecorator:()=>h,createComponentDecorator:()=>d,getComponent:()=>I,getComponentArgumentStore:()=>g,getComponentStore:()=>x,option:()=>j});var X=require("reflect-metadata");var M=require("discord.js"),D=R(require("lodash"));var f=class{constructor(t){this.type=t,this.decorators=[]}};r(f,"ComponentArgument");var a=class{argTypes=new M.Collection;constructor(t,o,s){typeof t=="object"?this.options=D.default.merge(this.defaultOptions(),t):this.options=t,this.method=o;for(let n=0;n<s.length;n++){let c=s[n];this.argTypes.set(n,new f(c))}}defaultOptions(){return{}}execute(t,o){return this.method.apply(t,o)}};r(a,"BaseComponent");var u=require("discord.js");var i=Symbol(),Q=Symbol();var x=r(e=>{let t=Reflect.getMetadata(i,e);return t||(t=new u.Collection,Reflect.defineMetadata(i,t,e)),t},"getComponentStore"),I=r((e,t)=>x(e).get(t),"getComponent"),d=r(e=>t=>(o,s)=>{var n=new e(t,Reflect.get(o,s),Reflect.getMetadata("design:paramtypes",o,s));let c=x(o);g(o,s).forEach((T,_)=>{var y;(y=n.argTypes.get(_))==null||y.decorators.push(T)}),c.set(s,n)},"createComponentDecorator"),g=r((e,t)=>{let o=Reflect.getMetadata(i,e,t);return o||(o=new u.Collection,Reflect.defineMetadata(i,o,e,t)),o},"getComponentArgumentStore"),h=r(e=>t=>(o,s,n)=>{var c=new e(t);g(o,s).set(n,c)},"createArgumentDecorator");var C=class extends a{defaultOptions(){return{name:"",description:""}}};r(C,"SlashCommand");var O=d(C);var A=R(require("lodash")),l=class{constructor(t){typeof t=="object"?this.options=A.default.merge(this.defaultOptions(),t):this.options=t}defaultOptions(){return{}}};r(l,"ComponentArgumentDecorator");var S=class extends l{};r(S,"ApplicationCommandOption");var j=h(S);module.exports=H(J);0&&(module.exports={BaseComponent,applicationCommand,createArgumentDecorator,createComponentDecorator,getComponent,getComponentArgumentStore,getComponentStore,option});
1
+ var it=Object.create;var v=Object.defineProperty;var ct=Object.getOwnPropertyDescriptor;var mt=Object.getOwnPropertyNames,B=Object.getOwnPropertySymbols,at=Object.getPrototypeOf,G=Object.prototype.hasOwnProperty,pt=Object.prototype.propertyIsEnumerable;var z=(o,t,e)=>t in o?v(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e,U=(o,t)=>{for(var e in t||(t={}))G.call(t,e)&&z(o,e,t[e]);if(B)for(var e of B(t))pt.call(t,e)&&z(o,e,t[e]);return o};var Z=o=>v(o,"__esModule",{value:!0}),i=(o,t)=>v(o,"name",{value:t,configurable:!0});var lt=(o,t)=>{for(var e in t)v(o,e,{get:t[e],enumerable:!0})},q=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of mt(t))!G.call(o,r)&&(e||r!=="default")&&v(o,r,{get:()=>t[r],enumerable:!(n=ct(t,r))||n.enumerable});return o},x=(o,t)=>q(Z(v(o!=null?it(at(o)):{},"default",!t&&o&&o.__esModule?{get:()=>o.default,enumerable:!0}:{value:o,enumerable:!0})),o),ft=(o=>(t,e)=>o&&o.get(t)||(e=q(Z({}),t,1),o&&o.set(t,e),e))(typeof WeakMap!="undefined"?new WeakMap:0);var ut={};lt(ut,{ApplicationCommandComponent:()=>l,BaseComponent:()=>u,CommandClient:()=>b,ConverterComponent:()=>w,Registry:()=>E,applicationCommand:()=>gt,argConverter:()=>I,createArgumentDecorator:()=>k,createComponentDecorator:()=>C,getComponent:()=>dt,getComponentArgumentStore:()=>W,getComponentStore:()=>T,getModuleHookStore:()=>O,moduleHook:()=>P,option:()=>tt});var wt=require("reflect-metadata");var J=require("discord.js");var A=class{constructor(t){this.type=t,this.decorators=[]}};i(A,"ComponentArgument");var u=class{argTypes=new J.Collection;constructor(t,e,n){this.options=this.convertOptions(t),this.method=e;for(let r=0;r<n.length;r++){let s=n[r];this.argTypes.set(r,new A(s))}}convertOptions(t){return t}execute(t,e){return this.method.call(t,...e)}};i(u,"BaseComponent");var D=require("discord.js");var R=Symbol(),bt=Symbol(),H=Symbol(),L=Symbol();var T=i(o=>{let t=Reflect.getMetadata(R,o);return t||(t=new D.Collection,Reflect.defineMetadata(R,t,o)),t},"getComponentStore"),dt=i((o,t)=>T(o).get(t),"getComponent"),C=i(o=>t=>(e,n)=>{var r=new o(t,Reflect.get(e,n),Reflect.getMetadata("design:paramtypes",e,n));let s=T(e);W(e,n).forEach((m,f)=>{var h;(h=r.argTypes.get(f))==null||h.decorators.push(m)}),s.set(n,r)},"createComponentDecorator"),W=i((o,t)=>{let e=Reflect.getMetadata(R,o,t);return e||(e=new D.Collection,Reflect.defineMetadata(R,e,o,t)),e},"getComponentArgumentStore"),k=i(o=>t=>(e,n,r)=>{var s=new o(t);W(e,n).set(r,s)},"createArgumentDecorator");var _=x(require("chalk")),V=require("discord.js"),X=x(require("lodash"));var K=require("discord.js");var O=i(o=>{let t=Reflect.getMetadata(H,o);return t||(t=new K.Collection,Reflect.defineMetadata(H,t,o)),t},"getModuleHookStore"),P=i(o=>(t,e)=>{let n=O(t),r=n.get(e);r||(r=[],n.set(e,r)),r.push(Reflect.get(t,e))},"moduleHook");var M=class extends u{defaultOptions(){return{emitter:"discord"}}constructor(t,e,n){super({event:t.event,emitter:(r=t.emitter)!=null?r:"discord"},e,n);var r}};i(M,"ListenerComponent");var Q=C(M);var E=class{constructor(t,e){this.client=e,this.extensions=[],this.emitters=new V.Collection,this.logger=t.getChildLogger({prefix:[_.default.green("[Registry]")]})}getComponentsWithTypeGlobal(t){let e=[];for(let n of this.extensions)e.push(...this.getComponentsWithType(n,t));return e}getComponentsWithType(t,e){let n=T(t);return Array.from(n.filter(r=>r.constructor===e).values())}registerEventListeners(t){let e=this.getComponentsWithType(t,M);for(let n of e){let r=this.emitters.get(n.options.emitter);if(r){let s=n.method.bind(t);Reflect.defineMetadata("bound",s,n),r.addListener(n.options.event,s)}}}unregisterEventListeners(t){let e=this.getComponentsWithType(t,M);for(let n of e){let r=this.emitters.get(n.options.emitter),s=Reflect.getMetadata("bound",n);r&&s&&r.removeListener(n.options.event,s)}}async registerModule(t){Reflect.defineMetadata(L,this.client,t),this.registerEventListeners(t),await this.runModuleHook(t,"load"),this.extensions.push(t),this.logger.info(`Module registered: ${_.default.green(t.constructor.name)}`)}async unregisterModule(t){this.unregisterEventListeners(t),await this.runModuleHook(t,"unload"),X.default.remove(this.extensions,e=>e===t),this.logger.info(`Module unregistered: ${_.default.green(t.constructor.name)}`)}runModuleHook(t,e,...n){let s=O(t).get(e);if(s)for(let c of s)c.call(t,...n)}registerEventEmitter(t,e){this.emitters.set(t,e)}};i(E,"Registry");var rt=x(require("chalk")),nt=x(require("events")),st=require("tslog");var y=x(require("chalk")),p=require("discord.js");var l=class extends u{};i(l,"ApplicationCommandComponent");var gt=C(l);var Y=x(require("lodash")),$=class{constructor(t){typeof t=="object"?this.options=Y.default.merge(this.defaultOptions(),t):this.options=t}defaultOptions(){return{}}};i($,"ComponentArgumentDecorator");var S=class extends ${};i(S,"ApplicationCommandOption");var tt=k(S);var et=x(require("chalk")),ot=require("discord.js");var w=class extends u{};i(w,"ConverterComponent");var I=C(w);var j=class{get commandClient(){return b.getFromModule(this)}get client(){return this.commandClient.discord}get logger(){return this._logger||(this._logger=this.commandClient.logger.getChildLogger({prefix:[et.default.green(`[${this.constructor.name}]`)],displayFunctionName:!1})),this._logger}async convertArguments(t,e,n,r){let s=new ot.Collection;for(let c of this.commandClient.registry.extensions)for(let m of this.commandClient.registry.getComponentsWithType(c,w))m.options.component==t&&s.set(m.options.type,{component:m,ext:c});for(let[c,m]of n){let f=s.get(m.type);if(!f){e[c]=void 0;continue}let h=await r(m,c);e[c]=await f.component.execute(f.ext,h)}}};i(j,"Extension");var F=function(o,t,e,n){var r=arguments.length,s=r<3?t:n===null?n=Object.getOwnPropertyDescriptor(t,e):n,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(o,t,e,n);else for(var m=o.length-1;m>=0;m--)(c=o[m])&&(s=(r<3?c(s):r>3?c(t,e,s):c(t,e))||s);return r>3&&s&&Object.defineProperty(t,e,s),s},d=function(o,t){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(o,t)},g=class extends j{constructor(t){super();this.config=t}async interactionCreate(t){var s;if(t.type!==p.InteractionType.ApplicationCommand)return;let e=null,n=null,r=this.commandClient.registry.extensions;for(let c of r){let m=this.commandClient.registry.getComponentsWithType(c,l);for(let f of m)f.options.name===t.commandName&&(n=c,e=f)}if(e&&n){let c=[];await this.convertArguments(l,c,e.argTypes,()=>[t]);for(let[m,f]of e.argTypes){let h=null;for(let N of f.decorators)if(N instanceof S){h=(s=t.options.get(N.options.name,!1))==null?void 0:s.value;break}h&&(c[m]=h)}try{await e.execute(n,c)}catch(m){this.logger.error(m),this.commandClient.emit("applicationCommandInvokeError",m,t)}}}async load(){}async sync(){let t=b.getFromModule(this);this.logger.info("Trying to sync commands...");let e=[];for(let n of t.registry.getComponentsWithTypeGlobal(l)){let r=U({},n.options);if(r.type===p.ApplicationCommandType.ChatInput){r.options=[];for(let[,s]of n.argTypes){let c=s.decorators.find(m=>m.constructor===S);c&&r.options.push(c.options)}}e.push(r)}if(this.logger.info(`Processing ${y.default.green(e.length)} commands(${e.map(n=>y.default.blue(n.name)).join(", ")})`),this.config.guilds)for(let n of this.config.guilds)try{let r=await this.client.guilds.fetch(n);await r.fetch(),this.logger.info(`Registering commands for guild ${y.default.green(r.name)}(${y.default.blue(r.id)})`),await r.commands.set(e),this.logger.info(`Successfully registered commands for guild ${y.default.green(r.name)}(${y.default.blue(r.id)})`)}catch(r){this.logger.error(`Failed to register commands to guild ${y.default.green(n)}: ${r.message}`)}else try{this.logger.info("Registering commands globally..."),await this.client.application.commands.set(e),this.logger.info("Successfully registered commands.")}catch(n){this.logger.error(`Failed to register commands to global: ${n.message}`)}}async chatInteraction(t){return t}async messageInteraction(t){return t}async userInteraction(t){return t}};i(g,"ApplicationCommandExtension");F([Q({event:"interactionCreate"}),d("design:type",Function),d("design:paramtypes",[typeof p.Interaction=="undefined"?Object:p.Interaction])],g.prototype,"interactionCreate",null);F([P("load"),d("design:type",Function),d("design:paramtypes",[])],g.prototype,"load",null);F([I({component:l,parameterless:!0,type:p.ChatInputCommandInteraction}),d("design:type",Function),d("design:paramtypes",[typeof p.ChatInputCommandInteraction=="undefined"?Object:p.ChatInputCommandInteraction])],g.prototype,"chatInteraction",null);F([I({component:l,parameterless:!0,type:p.MessageContextMenuCommandInteraction}),d("design:type",Function),d("design:paramtypes",[typeof p.MessageContextMenuCommandInteraction=="undefined"?Object:p.MessageContextMenuCommandInteraction])],g.prototype,"messageInteraction",null);F([I({component:l,parameterless:!0,type:p.UserContextMenuCommandInteraction}),d("design:type",Function),d("design:paramtypes",[typeof p.UserContextMenuCommandInteraction=="undefined"?Object:p.UserContextMenuCommandInteraction])],g.prototype,"userInteraction",null);var b=class extends nt.default{constructor(t,e=new st.Logger({dateTimeTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone})){super();this.discord=t,this.logger=e,this.ctsLogger=e.getChildLogger({prefix:[rt.default.blue("[command.ts]")],displayFilePath:"hidden",displayFunctionName:!1}),this.registry=new E(this.ctsLogger,this),this.registry.registerEventEmitter("cts",this),this.registry.registerEventEmitter("discord",this.discord)}async enableApplicationCommandsExtension(t){await this.registry.registerModule(new g(t)),this.ctsLogger.info("Application command extension enabled.")}getApplicationCommandsExtension(){return this.registry.extensions.find(t=>t.constructor===g)}static getFromModule(t){return Reflect.getMetadata(L,t)}};i(b,"CommandClient");module.exports=ft(ut);0&&(module.exports={ApplicationCommandComponent,BaseComponent,CommandClient,ConverterComponent,Registry,applicationCommand,argConverter,createArgumentDecorator,createComponentDecorator,getComponent,getComponentArgumentStore,getComponentStore,getModuleHookStore,moduleHook,option});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/home/runner/work/command.ts/command.ts/src/index.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/index.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/BaseComponent.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/ComponentArgument.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/decoratorCreator.ts","../src/core/home/runner/work/command.ts/command.ts/src/core/symbols.ts","../src/applicationCommand/home/runner/work/command.ts/command.ts/src/applicationCommand/ApplicationCommand.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/ComponentArgumentDecorator.ts","../src/applicationCommand/home/runner/work/command.ts/command.ts/src/applicationCommand/ApplicationCommandOption.ts"],"sourcesContent":["/*\r\n * File: index.ts\r\n *\r\n * Copyright (c) 2022-2022 pikokr\r\n *\r\n * Licensed under MIT License. Please see more defails in LICENSE file.\r\n */\r\n\r\nexport * from './core'\r\nexport * from './applicationCommand'\r\n","import 'reflect-metadata'\nexport * from './BaseComponent'\nexport * from './decoratorCreator'\n","import { Collection } from 'discord.js'\nimport _ from 'lodash'\nimport { ComponentArgument } from './ComponentArgument'\n\nexport class BaseComponent<Options = unknown> {\n options: Options\n\n method: Function\n\n argTypes: Collection<number, ComponentArgument> = new Collection()\n\n constructor(options: Partial<Options>, method: Function, argTypes: unknown[]) {\n if (typeof options === 'object') {\n this.options = _.merge(this.defaultOptions(), options)\n } else {\n this.options = options\n }\n this.method = method\n for (let i = 0; i < argTypes.length; i++) {\n const element = argTypes[i]\n this.argTypes.set(i, new ComponentArgument(element))\n }\n }\n\n defaultOptions(): Options {\n return ({} as unknown) as Options\n }\n\n execute(target: object, args: unknown[]) {\n return this.method.apply(target, args)\n }\n}\n","import { ComponentArgumentDecorator } from './ComponentArgumentDecorator'\n\nexport class ComponentArgument {\n decorators: ComponentArgumentDecorator[] = []\n\n constructor(public type: unknown) {}\n}\n","import { Collection } from 'discord.js'\nimport { ComponentStoreSymbol } from '../symbols'\nimport { BaseComponent } from './BaseComponent'\nimport { ComponentArgumentDecorator } from './ComponentArgumentDecorator'\n\ntype ComponentStore = Collection<string|symbol, BaseComponent>\ntype ComponentArgumentStore = Collection<number, ComponentArgumentDecorator>\n\nexport const getComponentStore = (target: object): ComponentStore => {\n let result: ComponentStore|null = Reflect.getMetadata(ComponentStoreSymbol, target)\n\n if (!result) {\n result = new Collection()\n\n Reflect.defineMetadata(ComponentStoreSymbol, result, target)\n }\n\n return result\n}\n\nexport const getComponent = (target: object, key: string|symbol) => {\n const store = getComponentStore(target)\n\n return store.get(key)\n}\n\nexport const createComponentDecorator = <Options>(type: typeof BaseComponent<Options>) => {\n return (options: Options): MethodDecorator => {\n return (target, key) => {\n var component: BaseComponent<Options> = new type(options, Reflect.get(target, key), Reflect.getMetadata('design:paramtypes', target, key))\n\n const store = getComponentStore(target)\n\n const decorators = getComponentArgumentStore(target, key)\n\n decorators.forEach((x, i)=> {\n component.argTypes.get(i)?.decorators.push(x)\n })\n\n store.set(key, component)\n }\n }\n}\n\nexport const getComponentArgumentStore = (target: object, key: string|symbol): ComponentArgumentStore => {\n let result: ComponentArgumentStore|null = Reflect.getMetadata(ComponentStoreSymbol, target, key)\n\n if (!result) {\n result = new Collection()\n\n Reflect.defineMetadata(ComponentStoreSymbol, result, target, key)\n }\n\n return result\n}\n\nexport const createArgumentDecorator = <Options>(type: typeof ComponentArgumentDecorator<Options>) => {\n return (options: Options): ParameterDecorator => {\n return (target, key, idx) => {\n var arg: ComponentArgumentDecorator<Options> = new type(options)\n\n const store = getComponentArgumentStore(target, key)\n\n store.set(idx, arg)\n }\n }\n}\n\n","export const ComponentStoreSymbol = Symbol()\nexport const ComponentArgStoreSymbol = Symbol()\n","import { BaseComponent, createComponentDecorator } from '../core'\n\nexport type ApplicationCommandOptions = {\n name: string\n description: string\n}\n\nexport class SlashCommand extends BaseComponent<ApplicationCommandOptions> {\n defaultOptions() {\n return {\n name: '',\n description: '',\n }\n }\n}\n\nexport const applicationCommand = createComponentDecorator(SlashCommand)\n","import _ from 'lodash'\n\nexport class ComponentArgumentDecorator<Options = unknown> {\n options: Options\n\n constructor(options: Partial<Options>) {\n if (typeof options === 'object') {\n this.options = _.merge(this.defaultOptions(), options)\n } else {\n this.options = options\n }\n }\n\n defaultOptions(): Options {\n return ({} as unknown) as Options\n }\n}\n","import { APIApplicationCommandOption } from 'discord.js'\nimport { createArgumentDecorator } from '../core'\nimport { ComponentArgumentDecorator } from '../core/components/ComponentArgumentDecorator'\n\ntype Options = APIApplicationCommandOption\n\nexport class ApplicationCommandOption extends ComponentArgumentDecorator<Options> {}\n\nexport const option = createArgumentDecorator(ApplicationCommandOption)\n"],"mappings":"ouBAAA,kNCAA,MAAO,4BCAP,MAA2B,sBAC3B,EAAc,qBCCP,WAAuB,CAG5B,YAAmB,EAAe,MAAf,KAAA,OAFnB,WAA2C,KADtC,yBDEA,WAAmB,CAKxB,SAAkD,GAAI,cAEtD,YAAY,EAA2B,EAAkB,EAAqB,CAC5E,AAAI,MAAO,IAAY,SACrB,KAAK,QAAU,UAAE,MAAM,KAAK,iBAAkB,GAE9C,KAAK,QAAU,EAEjB,KAAK,OAAS,EACd,OAAS,GAAI,EAAG,EAAI,EAAS,OAAQ,IAAK,CACxC,GAAM,GAAU,EAAS,GACzB,KAAK,SAAS,IAAI,EAAG,GAAI,GAAkB,KAI/C,gBAA0B,CACxB,MAAQ,GAGV,QAAQ,EAAgB,EAAiB,CACvC,MAAO,MAAK,OAAO,MAAM,EAAQ,KAzB9B,qBEJP,MAA2B,sBCApB,GAAM,GAAuB,SACvB,EAA0B,SDOhC,GAAM,GAAoB,EAAC,GAAmC,CACnE,GAAI,GAA8B,QAAQ,YAAY,EAAsB,GAE5E,MAAK,IACH,GAAS,GAAI,cAEb,QAAQ,eAAe,EAAsB,EAAQ,IAGhD,GATwB,qBAYpB,EAAe,GAAC,EAAgB,IAGpC,AAFO,EAAkB,GAEnB,IAAI,GAHS,gBAMf,EAA2B,EAAU,GACzC,AAAC,GACC,CAAC,EAAQ,IAAQ,CACtB,GAAI,GAAoC,GAAI,GAAK,EAAS,QAAQ,IAAI,EAAQ,GAAM,QAAQ,YAAY,oBAAqB,EAAQ,IAErI,GAAM,GAAQ,EAAkB,GAIhC,AAFmB,EAA0B,EAAQ,GAE1C,QAAQ,CAAC,EAAG,IAAK,CAnClC,MAoCQ,KAAU,SAAS,IAAI,KAAvB,QAA2B,WAAW,KAAK,KAG7C,EAAM,IAAI,EAAK,IAbmB,4BAkB3B,EAA4B,GAAC,EAAgB,IAA+C,CACvG,GAAI,GAAsC,QAAQ,YAAY,EAAsB,EAAQ,GAE5F,MAAK,IACH,GAAS,GAAI,cAEb,QAAQ,eAAe,EAAsB,EAAQ,EAAQ,IAGxD,GATgC,6BAY5B,EAA0B,EAAU,GACxC,AAAC,GACC,CAAC,EAAQ,EAAK,IAAQ,CAC3B,GAAI,GAA2C,GAAI,GAAK,GAIxD,AAFc,EAA0B,EAAQ,GAE1C,IAAI,EAAK,IAPkB,2BEjDhC,mBAA2B,EAAa,CAC7C,gBAAiB,CACf,MAAO,CACL,KAAM,GACN,YAAa,MAJZ,oBASA,GAAM,GAAqB,EAAyB,GChB3D,MAAc,qBAEP,OAAgC,CAGrC,YAAY,EAA2B,CACrC,AAAI,MAAO,IAAY,SACrB,KAAK,QAAU,UAAE,MAAM,KAAK,iBAAkB,GAE9C,KAAK,QAAU,EAInB,gBAA0B,CACxB,MAAQ,KAZL,kCCIA,mBAAuC,EAA0B,GAAjE,gCAEA,GAAM,GAAS,EAAwB","names":[]}
1
+ {"version":3,"sources":["../src/home/runner/work/command.ts/command.ts/src/index.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/index.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/BaseComponent.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/ComponentArgument.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/decoratorCreator.ts","../src/core/home/runner/work/command.ts/command.ts/src/core/symbols.ts","../src/core/structures/home/runner/work/command.ts/command.ts/src/core/structures/Registry.ts","../src/core/hooks/home/runner/work/command.ts/command.ts/src/core/hooks/moduleHook.ts","../src/core/listener/home/runner/work/command.ts/command.ts/src/core/listener/index.ts","../src/core/structures/home/runner/work/command.ts/command.ts/src/core/structures/CommandClient.ts","../src/applicationCommand/home/runner/work/command.ts/command.ts/src/applicationCommand/ApplicationCommandExtension.ts","../src/applicationCommand/home/runner/work/command.ts/command.ts/src/applicationCommand/ApplicationCommand.ts","../src/core/components/home/runner/work/command.ts/command.ts/src/core/components/ComponentArgumentDecorator.ts","../src/applicationCommand/home/runner/work/command.ts/command.ts/src/applicationCommand/ApplicationCommandOption.ts","../src/core/extensions/home/runner/work/command.ts/command.ts/src/core/extensions/Extension.ts","../src/core/converter/home/runner/work/command.ts/command.ts/src/core/converter/index.ts"],"sourcesContent":["/*\n * File: index.ts\n *\n * Copyright (c) 2022-2022 pikokr\n *\n * Licensed under MIT License. Please see more defails in LICENSE file.\n */\n\nexport * from './core'\nexport * from './applicationCommand'\n","import 'reflect-metadata'\nexport * from './BaseComponent'\nexport * from './decoratorCreator'\n","import { Collection } from 'discord.js'\nimport _ from 'lodash'\nimport { ComponentArgument } from './ComponentArgument'\n\nexport class BaseComponent<Options = unknown, OptionsArg = Options> {\n options: Options\n\n method: Function\n\n argTypes: Collection<number, ComponentArgument> = new Collection()\n\n constructor(options: OptionsArg, method: Function, argTypes: unknown[]) {\n this.options = this.convertOptions(options)\n\n this.method = method\n for (let i = 0; i < argTypes.length; i++) {\n const element = argTypes[i]\n this.argTypes.set(i, new ComponentArgument(element))\n }\n }\n\n convertOptions(options: OptionsArg): Options {\n return options as unknown as Options\n }\n\n execute(target: object, args: unknown[]) {\n return this.method.call(target, ...args)\n }\n}\n","import { ComponentArgumentDecorator } from './ComponentArgumentDecorator'\n\nexport class ComponentArgument {\n decorators: ComponentArgumentDecorator[] = []\n\n constructor(public type: unknown) {}\n}\n","import { Collection } from 'discord.js'\nimport { ComponentStoreSymbol } from '../symbols'\nimport { BaseComponent } from './BaseComponent'\nimport { ComponentArgumentDecorator } from './ComponentArgumentDecorator'\n\ntype ComponentStore = Collection<string | symbol, BaseComponent>\ntype ComponentArgumentStore = Collection<number, ComponentArgumentDecorator>\n\nexport const getComponentStore = (target: object): ComponentStore => {\n let result: ComponentStore | null = Reflect.getMetadata(ComponentStoreSymbol, target)\n\n if (!result) {\n result = new Collection()\n\n Reflect.defineMetadata(ComponentStoreSymbol, result, target)\n }\n\n return result\n}\n\nexport const getComponent = (target: object, key: string | symbol) => {\n const store = getComponentStore(target)\n\n return store.get(key)\n}\n\nexport const createComponentDecorator = <Options, OptionArgs>(type: typeof BaseComponent<Options, OptionArgs>) => {\n return (options: OptionArgs): MethodDecorator => {\n return (target, key) => {\n var component: BaseComponent<Options, OptionArgs> = new type(options, Reflect.get(target, key), Reflect.getMetadata('design:paramtypes', target, key))\n\n const store = getComponentStore(target)\n\n const decorators = getComponentArgumentStore(target, key)\n\n decorators.forEach((x, i) => {\n component.argTypes.get(i)?.decorators.push(x)\n })\n\n store.set(key, component)\n }\n }\n}\n\nexport const getComponentArgumentStore = (target: object, key: string | symbol): ComponentArgumentStore => {\n let result: ComponentArgumentStore | null = Reflect.getMetadata(ComponentStoreSymbol, target, key)\n\n if (!result) {\n result = new Collection()\n\n Reflect.defineMetadata(ComponentStoreSymbol, result, target, key)\n }\n\n return result\n}\n\nexport const createArgumentDecorator = <Options>(type: typeof ComponentArgumentDecorator<Options>) => {\n return (options: Options): ParameterDecorator => {\n return (target, key, idx) => {\n var arg: ComponentArgumentDecorator<Options> = new type(options)\n\n const store = getComponentArgumentStore(target, key)\n\n store.set(idx, arg)\n }\n }\n}\n","export const ComponentStoreSymbol = Symbol()\nexport const ComponentArgStoreSymbol = Symbol()\nexport const ModuleHookStoreSymbol = Symbol()\nexport const CommandClientSymbol = Symbol()\n","import chalk from 'chalk'\nimport { Collection } from 'discord.js'\nimport EventEmitter from 'events'\nimport _ from 'lodash'\nimport { Logger } from 'tslog'\nimport { BaseComponent, getComponentStore } from '../components'\nimport { getModuleHookStore } from '../hooks'\nimport { ListenerComponent } from '../listener'\nimport { CommandClientSymbol } from '../symbols'\nimport { CommandClient } from './CommandClient'\n\nexport class Registry {\n extensions: object[] = []\n\n emitters: Collection<string, EventEmitter> = new Collection()\n\n logger: Logger\n\n constructor(logger: Logger, public client: CommandClient) {\n this.logger = logger.getChildLogger({\n prefix: [chalk.green('[Registry]')],\n })\n }\n\n getComponentsWithTypeGlobal<T extends typeof BaseComponent<Config>, Config>(type: T): InstanceType<T>[] {\n const result: InstanceType<T>[] = []\n\n for (const ext of this.extensions) {\n result.push(...this.getComponentsWithType(ext, type))\n }\n\n return result\n }\n\n getComponentsWithType<T extends typeof BaseComponent<Config>, Config>(ext: object, type: T): InstanceType<T>[] {\n const componentStore = getComponentStore(ext)\n\n return Array.from(componentStore.filter((x) => (x.constructor as unknown) === type).values() as Iterable<InstanceType<T>>)\n }\n\n registerEventListeners(ext: object) {\n const listeners = this.getComponentsWithType(ext, ListenerComponent)\n\n for (const listener of listeners) {\n const emitter = this.emitters.get(listener.options.emitter)\n\n if (emitter) {\n const bound = listener.method.bind(ext)\n\n Reflect.defineMetadata('bound', bound, listener)\n\n emitter.addListener(listener.options.event, bound)\n }\n }\n }\n\n unregisterEventListeners(ext: object) {\n const listeners = this.getComponentsWithType(ext, ListenerComponent)\n\n for (const listener of listeners) {\n const emitter = this.emitters.get(listener.options.emitter)\n const bound = Reflect.getMetadata('bound', listener)\n\n if (emitter && bound) {\n emitter.removeListener(listener.options.event, bound)\n }\n }\n }\n\n async registerModule(ext: object) {\n Reflect.defineMetadata(CommandClientSymbol, this.client, ext)\n\n this.registerEventListeners(ext)\n await this.runModuleHook(ext, 'load')\n this.extensions.push(ext)\n this.logger.info(`Module registered: ${chalk.green(ext.constructor.name)}`)\n }\n\n async unregisterModule(ext: object) {\n this.unregisterEventListeners(ext)\n await this.runModuleHook(ext, 'unload')\n _.remove(this.extensions, (x) => x === ext)\n this.logger.info(`Module unregistered: ${chalk.green(ext.constructor.name)}`)\n }\n\n runModuleHook(ext: object, hookName: string, ...args: unknown[]) {\n const hooks = getModuleHookStore(ext)\n\n const functions = hooks.get(hookName)\n\n if (functions) {\n for (const fn of functions) {\n fn.call(ext, ...args)\n }\n }\n }\n\n registerEventEmitter(name: string, emitter: EventEmitter) {\n this.emitters.set(name, emitter)\n }\n}\n","import { Collection } from 'discord.js'\nimport { ModuleHookStoreSymbol } from '../symbols'\n\ntype ModuleHookStore = Collection<string | symbol, Function[]>\n\nexport const getModuleHookStore = (target: object) => {\n let result: ModuleHookStore | null = Reflect.getMetadata(ModuleHookStoreSymbol, target)\n\n if (!result) {\n result = new Collection()\n\n Reflect.defineMetadata(ModuleHookStoreSymbol, result, target)\n }\n\n return result\n}\n\nexport const moduleHook = (name: string): MethodDecorator => {\n return (target, key) => {\n const store = getModuleHookStore(target)\n\n let v = store.get(key)\n\n if (!v) {\n v = []\n store.set(key, v)\n }\n\n v.push(Reflect.get(target, key))\n }\n}\n","import { BaseComponent, createComponentDecorator } from '../components'\n\nexport class ListenerComponent extends BaseComponent<{ emitter: string; event: string }, { emitter?: string; event: string }> {\n defaultOptions() {\n return { emitter: 'discord' }\n }\n\n constructor(options: ListenerComponent['options'], method: Function, argTypes: unknown[]) {\n super(\n {\n event: options.event,\n emitter: options.emitter ?? 'discord',\n },\n method,\n argTypes,\n )\n }\n}\n\nexport const listener = createComponentDecorator(ListenerComponent)\n","import chalk from 'chalk'\nimport { Client } from 'discord.js'\nimport EventEmitter from 'events'\nimport { Logger } from 'tslog'\nimport { ApplicationCommandExtension, ApplicationCommandExtensionConfig } from '../../applicationCommand/ApplicationCommandExtension'\nimport { CommandClientSymbol } from '../symbols'\nimport { Registry } from './Registry'\n\nexport class CommandClient extends EventEmitter {\n ctsLogger: Logger\n registry: Registry\n\n constructor(public discord: Client, public logger: Logger = new Logger({ dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone })) {\n super()\n\n this.ctsLogger = logger.getChildLogger({ prefix: [chalk.blue('[command.ts]')], displayFilePath: 'hidden', displayFunctionName: false })\n\n this.registry = new Registry(this.ctsLogger, this)\n\n this.registry.registerEventEmitter('cts', this)\n this.registry.registerEventEmitter('discord', this.discord)\n }\n\n async enableApplicationCommandsExtension(config: ApplicationCommandExtensionConfig) {\n await this.registry.registerModule(new ApplicationCommandExtension(config))\n this.ctsLogger.info('Application command extension enabled.')\n }\n\n getApplicationCommandsExtension() {\n return this.registry.extensions.find((x) => x.constructor === ApplicationCommandExtension) as ApplicationCommandExtension | undefined\n }\n\n static getFromModule(ext: object): CommandClient {\n return Reflect.getMetadata(CommandClientSymbol, ext)\n }\n}\n","import chalk from 'chalk'\nimport {\n ApplicationCommandData,\n ApplicationCommandType,\n ChatInputCommandInteraction,\n GuildAuditLogs,\n Interaction,\n InteractionType,\n MessageContextMenuCommandInteraction,\n Snowflake,\n UserContextMenuCommandInteraction,\n} from 'discord.js'\nimport { ApplicationCommandComponent } from '.'\nimport { ApplicationCommandOption } from './ApplicationCommandOption'\nimport { moduleHook } from '../core/hooks'\nimport { listener } from '../core/listener'\nimport { CommandClient } from '../core/structures'\nimport { Extension } from '../core/extensions/Extension'\nimport { argConverter } from '../core/converter'\n\nexport type ApplicationCommandExtensionConfig = {\n guilds?: Snowflake[]\n}\n\nexport class ApplicationCommandExtension extends Extension {\n constructor(public config: ApplicationCommandExtensionConfig) {\n super()\n }\n\n @listener({ event: 'interactionCreate' })\n async interactionCreate(i: Interaction) {\n if (i.type !== InteractionType.ApplicationCommand) return\n\n let cmd: ApplicationCommandComponent | null = null\n let ext: object | null = null\n\n const extensions = this.commandClient.registry.extensions\n\n for (const extension of extensions) {\n const components = this.commandClient.registry.getComponentsWithType(extension, ApplicationCommandComponent)\n\n for (const command of components) {\n if (command.options.name === i.commandName) {\n ext = extension\n cmd = command\n }\n }\n }\n\n if (cmd && ext) {\n const argList: unknown[] = []\n\n await this.convertArguments(ApplicationCommandComponent, argList, cmd.argTypes, () => [i])\n\n for (const [idx, arg] of cmd.argTypes) {\n let value: unknown = null\n\n for (const decorator of arg.decorators) {\n if (decorator instanceof ApplicationCommandOption) {\n value = i.options.get(decorator.options.name, false)?.value\n break\n }\n }\n\n if (value) {\n argList[idx] = value\n }\n }\n\n try {\n await cmd.execute(ext, argList)\n } catch (e) {\n this.logger.error(e)\n this.commandClient.emit('applicationCommandInvokeError', e, i)\n }\n }\n }\n\n @moduleHook('load')\n async load() {}\n\n async sync() {\n const client = CommandClient.getFromModule(this)\n\n this.logger.info('Trying to sync commands...')\n\n const commands: ApplicationCommandData[] = []\n\n for (const command of client.registry.getComponentsWithTypeGlobal(ApplicationCommandComponent)) {\n const cmd: ApplicationCommandData = { ...command.options }\n\n if (cmd.type === ApplicationCommandType.ChatInput) {\n cmd.options = []\n\n for (const [, arg] of command.argTypes) {\n const option = arg.decorators.find((x) => x.constructor === ApplicationCommandOption) as ApplicationCommandOption\n\n if (option) {\n cmd.options.push(option.options)\n }\n }\n }\n\n commands.push(cmd)\n }\n\n this.logger.info(`Processing ${chalk.green(commands.length)} commands(${commands.map((x) => chalk.blue(x.name)).join(', ')})`)\n\n if (this.config.guilds) {\n for (const guild of this.config.guilds) {\n try {\n const g = await this.client.guilds.fetch(guild)\n await g.fetch()\n this.logger.info(`Registering commands for guild ${chalk.green(g.name)}(${chalk.blue(g.id)})`)\n\n await g.commands.set(commands)\n\n this.logger.info(`Successfully registered commands for guild ${chalk.green(g.name)}(${chalk.blue(g.id)})`)\n } catch (e) {\n this.logger.error(`Failed to register commands to guild ${chalk.green(guild)}: ${(e as Error).message}`)\n }\n }\n } else {\n try {\n this.logger.info(`Registering commands globally...`)\n\n await this.client.application!.commands.set(commands)\n\n this.logger.info('Successfully registered commands.')\n } catch (e) {\n this.logger.error(`Failed to register commands to global: ${(e as Error).message}`)\n }\n }\n }\n\n @argConverter({\n component: ApplicationCommandComponent,\n parameterless: true,\n type: ChatInputCommandInteraction,\n })\n async chatInteraction(i: ChatInputCommandInteraction) {\n return i\n }\n\n @argConverter({\n component: ApplicationCommandComponent,\n parameterless: true,\n type: MessageContextMenuCommandInteraction,\n })\n async messageInteraction(i: MessageContextMenuCommandInteraction) {\n return i\n }\n\n @argConverter({\n component: ApplicationCommandComponent,\n parameterless: true,\n type: UserContextMenuCommandInteraction,\n })\n async userInteraction(i: UserContextMenuCommandInteraction) {\n return i\n }\n}\n","import { ApplicationCommandType, ChatInputApplicationCommandData, MessageApplicationCommandData, UserApplicationCommandData } from 'discord.js'\nimport { BaseComponent, createComponentDecorator } from '../core'\n\nexport class ApplicationCommandComponent extends BaseComponent<\n (UserApplicationCommandData | MessageApplicationCommandData | Omit<ChatInputApplicationCommandData, 'options'>) & { type: ApplicationCommandType }\n> {}\n\nexport const applicationCommand = createComponentDecorator(ApplicationCommandComponent)\n","import _ from 'lodash'\n\nexport class ComponentArgumentDecorator<Options = unknown> {\n options: Options\n\n constructor(options: Partial<Options>) {\n if (typeof options === 'object') {\n this.options = _.merge(this.defaultOptions(), options)\n } else {\n this.options = options\n }\n }\n\n defaultOptions(): Options {\n return {} as unknown as Options\n }\n}\n","import { APIApplicationCommandOption } from 'discord.js'\nimport { createArgumentDecorator } from '../core'\nimport { ComponentArgumentDecorator } from '../core/components/ComponentArgumentDecorator'\n\ntype Options = APIApplicationCommandOption\n\nexport class ApplicationCommandOption extends ComponentArgumentDecorator<Options> {}\n\nexport const option = createArgumentDecorator(ApplicationCommandOption)\n","import chalk from 'chalk'\nimport { Collection } from 'discord.js'\nimport { Logger } from 'tslog'\nimport { BaseComponent } from '../components'\nimport { ComponentArgument } from '../components/ComponentArgument'\nimport { ConverterComponent } from '../converter'\nimport { CommandClient } from '../structures'\n\nexport class Extension {\n protected get commandClient() {\n return CommandClient.getFromModule(this)\n }\n\n protected get client() {\n return this.commandClient.discord\n }\n\n private _logger?: Logger\n\n protected get logger() {\n if (!this._logger) this._logger = this.commandClient.logger.getChildLogger({ prefix: [chalk.green(`[${this.constructor.name}]`)], displayFunctionName: false })\n return this._logger\n }\n\n protected async convertArguments(\n component: typeof BaseComponent<unknown>,\n argList: unknown[],\n args: Collection<number, ComponentArgument>,\n getConverterArgs: (arg: ComponentArgument, index: number) => unknown[] | Promise<unknown[]>,\n ) {\n const items = new Collection<unknown, { ext: object; component: ConverterComponent }>()\n\n for (const extension of this.commandClient.registry.extensions) {\n for (const converter of this.commandClient.registry.getComponentsWithType(extension, ConverterComponent)) {\n if (converter.options.component != component) continue\n\n items.set(converter.options.type, { component: converter, ext: extension })\n }\n }\n\n for (const [index, arg] of args) {\n const converter = items.get(arg.type)\n\n if (!converter) {\n argList[index] = undefined\n continue\n }\n\n const converterArgs = await getConverterArgs(arg, index)\n\n argList[index] = await converter.component.execute(converter.ext, converterArgs)\n }\n }\n}\n","import { BaseComponent, createComponentDecorator } from '../components'\n\ntype Options = { component: typeof BaseComponent<unknown>; type: Function; parameterless: boolean }\n\nexport class ConverterComponent extends BaseComponent<Options, Options & { parameterless?: boolean }> {}\n\nexport const argConverter = createComponentDecorator(ConverterComponent)\n"],"mappings":"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","names":[]}
package/docs/index.yml CHANGED
@@ -2,4 +2,4 @@
2
2
  files:
3
3
  - name: Welcome
4
4
  id: welcome
5
- path: ../../README.md
5
+ path: ../../README.md
package/package.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "@pikokr/command.ts",
3
3
  "description": "Discord.js command framework for typescript.",
4
- "version": "5.0.0-dev.6f835eb",
4
+ "version": "5.0.0-dev.97799e9",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "MIT",
8
8
  "devDependencies": {
9
9
  "@discordjs/ts-docgen": "^0.4.1",
10
10
  "@swc/core": "^1.2.218",
11
+ "@types/chalk": "^2.2.0",
11
12
  "@types/lodash": "^4.14.172",
12
13
  "all-contributors-cli": "^6.20.0",
13
14
  "discord.js": "^14.0.1",
14
- "prettier": "^2.2.1",
15
+ "dotenv": "^16.0.1",
16
+ "prettier": "^2.7.1",
15
17
  "ts-node": "^10.9.1",
16
18
  "tsup": "^5.11.12",
17
19
  "typedoc": "^0.22.11",
@@ -19,6 +21,7 @@
19
21
  },
20
22
  "dependencies": {
21
23
  "@types/node": "^14.14.37",
24
+ "chalk": "4.1.2",
22
25
  "discord-api-types": "^0.23.1",
23
26
  "lodash": "^4.17.21",
24
27
  "reflect-metadata": "^0.1.13",
@@ -34,7 +37,8 @@
34
37
  "build": "tsup-node",
35
38
  "docs:dev": "typedoc",
36
39
  "docs:build": "typedoc",
37
- "docs": "typedoc --json docs/typedoc-out.json --tsconfig tsconfig.prod.json src/index.ts && ts-node scripts/docs"
40
+ "docs": "typedoc --json docs/typedoc-out.json --tsconfig tsconfig.prod.json src/index.ts && ts-node scripts/docs",
41
+ "test": "yarn ts-node --swc test"
38
42
  },
39
43
  "peerDependencies": {
40
44
  "discord.js": "^14.0.1"
@@ -1,13 +1,13 @@
1
- /*
2
- * This is the default license template.
3
- *
4
- * File: publish-version.js
5
- * Author: pikokr
6
- * Copyright (c) 2022 pikokr
7
- *
8
- * To edit this license information: Press Ctrl+Shift+P and press 'Create new License Template...'.
9
- */
10
-
1
+ /*
2
+ * This is the default license template.
3
+ *
4
+ * File: publish-version.js
5
+ * Author: pikokr
6
+ * Copyright (c) 2022 pikokr
7
+ *
8
+ * To edit this license information: Press Ctrl+Shift+P and press 'Create new License Template...'.
9
+ */
10
+
11
11
  /*
12
12
  * Copyright (c) 2022 pikokr. Licensed under the MIT license
13
13
  */
package/scripts/docs.ts CHANGED
@@ -1,11 +1,11 @@
1
- /*
2
- * File: docs.ts
3
- *
4
- * Copyright (c) 2022-2022 pikokr
5
- *
6
- * Licensed under MIT License. Please see more defails in LICENSE file.
7
- */
8
-
1
+ /*
2
+ * File: docs.ts
3
+ *
4
+ * Copyright (c) 2022-2022 pikokr
5
+ *
6
+ * Licensed under MIT License. Please see more defails in LICENSE file.
7
+ */
8
+
9
9
  import { runGenerator } from '@discordjs/ts-docgen'
10
10
 
11
11
  runGenerator({
@@ -1,17 +1,8 @@
1
+ import { ApplicationCommandType, ChatInputApplicationCommandData, MessageApplicationCommandData, UserApplicationCommandData } from 'discord.js'
1
2
  import { BaseComponent, createComponentDecorator } from '../core'
2
3
 
3
- export type ApplicationCommandOptions = {
4
- name: string
5
- description: string
6
- }
4
+ export class ApplicationCommandComponent extends BaseComponent<
5
+ (UserApplicationCommandData | MessageApplicationCommandData | Omit<ChatInputApplicationCommandData, 'options'>) & { type: ApplicationCommandType }
6
+ > {}
7
7
 
8
- export class SlashCommand extends BaseComponent<ApplicationCommandOptions> {
9
- defaultOptions() {
10
- return {
11
- name: '',
12
- description: '',
13
- }
14
- }
15
- }
16
-
17
- export const applicationCommand = createComponentDecorator(SlashCommand)
8
+ export const applicationCommand = createComponentDecorator(ApplicationCommandComponent)
@@ -0,0 +1,162 @@
1
+ import chalk from 'chalk'
2
+ import {
3
+ ApplicationCommandData,
4
+ ApplicationCommandType,
5
+ ChatInputCommandInteraction,
6
+ GuildAuditLogs,
7
+ Interaction,
8
+ InteractionType,
9
+ MessageContextMenuCommandInteraction,
10
+ Snowflake,
11
+ UserContextMenuCommandInteraction,
12
+ } from 'discord.js'
13
+ import { ApplicationCommandComponent } from '.'
14
+ import { ApplicationCommandOption } from './ApplicationCommandOption'
15
+ import { moduleHook } from '../core/hooks'
16
+ import { listener } from '../core/listener'
17
+ import { CommandClient } from '../core/structures'
18
+ import { Extension } from '../core/extensions/Extension'
19
+ import { argConverter } from '../core/converter'
20
+
21
+ export type ApplicationCommandExtensionConfig = {
22
+ guilds?: Snowflake[]
23
+ }
24
+
25
+ export class ApplicationCommandExtension extends Extension {
26
+ constructor(public config: ApplicationCommandExtensionConfig) {
27
+ super()
28
+ }
29
+
30
+ @listener({ event: 'interactionCreate' })
31
+ async interactionCreate(i: Interaction) {
32
+ if (i.type !== InteractionType.ApplicationCommand) return
33
+
34
+ let cmd: ApplicationCommandComponent | null = null
35
+ let ext: object | null = null
36
+
37
+ const extensions = this.commandClient.registry.extensions
38
+
39
+ for (const extension of extensions) {
40
+ const components = this.commandClient.registry.getComponentsWithType(extension, ApplicationCommandComponent)
41
+
42
+ for (const command of components) {
43
+ if (command.options.name === i.commandName) {
44
+ ext = extension
45
+ cmd = command
46
+ }
47
+ }
48
+ }
49
+
50
+ if (cmd && ext) {
51
+ const argList: unknown[] = []
52
+
53
+ await this.convertArguments(ApplicationCommandComponent, argList, cmd.argTypes, () => [i])
54
+
55
+ for (const [idx, arg] of cmd.argTypes) {
56
+ let value: unknown = null
57
+
58
+ for (const decorator of arg.decorators) {
59
+ if (decorator instanceof ApplicationCommandOption) {
60
+ value = i.options.get(decorator.options.name, false)?.value
61
+ break
62
+ }
63
+ }
64
+
65
+ if (value) {
66
+ argList[idx] = value
67
+ }
68
+ }
69
+
70
+ try {
71
+ await cmd.execute(ext, argList)
72
+ } catch (e) {
73
+ this.logger.error(e)
74
+ this.commandClient.emit('applicationCommandInvokeError', e, i)
75
+ }
76
+ }
77
+ }
78
+
79
+ @moduleHook('load')
80
+ async load() {}
81
+
82
+ async sync() {
83
+ const client = CommandClient.getFromModule(this)
84
+
85
+ this.logger.info('Trying to sync commands...')
86
+
87
+ const commands: ApplicationCommandData[] = []
88
+
89
+ for (const command of client.registry.getComponentsWithTypeGlobal(ApplicationCommandComponent)) {
90
+ const cmd: ApplicationCommandData = { ...command.options }
91
+
92
+ if (cmd.type === ApplicationCommandType.ChatInput) {
93
+ cmd.options = []
94
+
95
+ for (const [, arg] of command.argTypes) {
96
+ const option = arg.decorators.find((x) => x.constructor === ApplicationCommandOption) as ApplicationCommandOption
97
+
98
+ if (option) {
99
+ cmd.options.push(option.options)
100
+ }
101
+ }
102
+ }
103
+
104
+ commands.push(cmd)
105
+ }
106
+
107
+ this.logger.info(`Processing ${chalk.green(commands.length)} commands(${commands.map((x) => chalk.blue(x.name)).join(', ')})`)
108
+
109
+ if (this.config.guilds) {
110
+ for (const guild of this.config.guilds) {
111
+ try {
112
+ const g = await this.client.guilds.fetch(guild)
113
+ await g.fetch()
114
+ this.logger.info(`Registering commands for guild ${chalk.green(g.name)}(${chalk.blue(g.id)})`)
115
+
116
+ await g.commands.set(commands)
117
+
118
+ this.logger.info(`Successfully registered commands for guild ${chalk.green(g.name)}(${chalk.blue(g.id)})`)
119
+ } catch (e) {
120
+ this.logger.error(`Failed to register commands to guild ${chalk.green(guild)}: ${(e as Error).message}`)
121
+ }
122
+ }
123
+ } else {
124
+ try {
125
+ this.logger.info(`Registering commands globally...`)
126
+
127
+ await this.client.application!.commands.set(commands)
128
+
129
+ this.logger.info('Successfully registered commands.')
130
+ } catch (e) {
131
+ this.logger.error(`Failed to register commands to global: ${(e as Error).message}`)
132
+ }
133
+ }
134
+ }
135
+
136
+ @argConverter({
137
+ component: ApplicationCommandComponent,
138
+ parameterless: true,
139
+ type: ChatInputCommandInteraction,
140
+ })
141
+ async chatInteraction(i: ChatInputCommandInteraction) {
142
+ return i
143
+ }
144
+
145
+ @argConverter({
146
+ component: ApplicationCommandComponent,
147
+ parameterless: true,
148
+ type: MessageContextMenuCommandInteraction,
149
+ })
150
+ async messageInteraction(i: MessageContextMenuCommandInteraction) {
151
+ return i
152
+ }
153
+
154
+ @argConverter({
155
+ component: ApplicationCommandComponent,
156
+ parameterless: true,
157
+ type: UserContextMenuCommandInteraction,
158
+ })
159
+ async userInteraction(i: UserContextMenuCommandInteraction) {
160
+ return i
161
+ }
162
+ }
@@ -1,2 +1,2 @@
1
- export { applicationCommand } from './ApplicationCommand'
1
+ export * from './ApplicationCommand'
2
2
  export { option } from './ApplicationCommandOption'
@@ -2,19 +2,16 @@ import { Collection } from 'discord.js'
2
2
  import _ from 'lodash'
3
3
  import { ComponentArgument } from './ComponentArgument'
4
4
 
5
- export class BaseComponent<Options = unknown> {
5
+ export class BaseComponent<Options = unknown, OptionsArg = Options> {
6
6
  options: Options
7
7
 
8
8
  method: Function
9
9
 
10
10
  argTypes: Collection<number, ComponentArgument> = new Collection()
11
11
 
12
- constructor(options: Partial<Options>, method: Function, argTypes: unknown[]) {
13
- if (typeof options === 'object') {
14
- this.options = _.merge(this.defaultOptions(), options)
15
- } else {
16
- this.options = options
17
- }
12
+ constructor(options: OptionsArg, method: Function, argTypes: unknown[]) {
13
+ this.options = this.convertOptions(options)
14
+
18
15
  this.method = method
19
16
  for (let i = 0; i < argTypes.length; i++) {
20
17
  const element = argTypes[i]
@@ -22,11 +19,11 @@ export class BaseComponent<Options = unknown> {
22
19
  }
23
20
  }
24
21
 
25
- defaultOptions(): Options {
26
- return ({} as unknown) as Options
22
+ convertOptions(options: OptionsArg): Options {
23
+ return options as unknown as Options
27
24
  }
28
25
 
29
26
  execute(target: object, args: unknown[]) {
30
- return this.method.apply(target, args)
27
+ return this.method.call(target, ...args)
31
28
  }
32
29
  }
@@ -12,6 +12,6 @@ export class ComponentArgumentDecorator<Options = unknown> {
12
12
  }
13
13
 
14
14
  defaultOptions(): Options {
15
- return ({} as unknown) as Options
15
+ return {} as unknown as Options
16
16
  }
17
17
  }
@@ -3,11 +3,11 @@ import { ComponentStoreSymbol } from '../symbols'
3
3
  import { BaseComponent } from './BaseComponent'
4
4
  import { ComponentArgumentDecorator } from './ComponentArgumentDecorator'
5
5
 
6
- type ComponentStore = Collection<string|symbol, BaseComponent>
6
+ type ComponentStore = Collection<string | symbol, BaseComponent>
7
7
  type ComponentArgumentStore = Collection<number, ComponentArgumentDecorator>
8
8
 
9
9
  export const getComponentStore = (target: object): ComponentStore => {
10
- let result: ComponentStore|null = Reflect.getMetadata(ComponentStoreSymbol, target)
10
+ let result: ComponentStore | null = Reflect.getMetadata(ComponentStoreSymbol, target)
11
11
 
12
12
  if (!result) {
13
13
  result = new Collection()
@@ -18,22 +18,22 @@ export const getComponentStore = (target: object): ComponentStore => {
18
18
  return result
19
19
  }
20
20
 
21
- export const getComponent = (target: object, key: string|symbol) => {
21
+ export const getComponent = (target: object, key: string | symbol) => {
22
22
  const store = getComponentStore(target)
23
23
 
24
24
  return store.get(key)
25
25
  }
26
26
 
27
- export const createComponentDecorator = <Options>(type: typeof BaseComponent<Options>) => {
28
- return (options: Options): MethodDecorator => {
27
+ export const createComponentDecorator = <Options, OptionArgs>(type: typeof BaseComponent<Options, OptionArgs>) => {
28
+ return (options: OptionArgs): MethodDecorator => {
29
29
  return (target, key) => {
30
- var component: BaseComponent<Options> = new type(options, Reflect.get(target, key), Reflect.getMetadata('design:paramtypes', target, key))
30
+ var component: BaseComponent<Options, OptionArgs> = new type(options, Reflect.get(target, key), Reflect.getMetadata('design:paramtypes', target, key))
31
31
 
32
32
  const store = getComponentStore(target)
33
33
 
34
34
  const decorators = getComponentArgumentStore(target, key)
35
35
 
36
- decorators.forEach((x, i)=> {
36
+ decorators.forEach((x, i) => {
37
37
  component.argTypes.get(i)?.decorators.push(x)
38
38
  })
39
39
 
@@ -42,8 +42,8 @@ export const createComponentDecorator = <Options>(type: typeof BaseComponent<Opt
42
42
  }
43
43
  }
44
44
 
45
- export const getComponentArgumentStore = (target: object, key: string|symbol): ComponentArgumentStore => {
46
- let result: ComponentArgumentStore|null = Reflect.getMetadata(ComponentStoreSymbol, target, key)
45
+ export const getComponentArgumentStore = (target: object, key: string | symbol): ComponentArgumentStore => {
46
+ let result: ComponentArgumentStore | null = Reflect.getMetadata(ComponentStoreSymbol, target, key)
47
47
 
48
48
  if (!result) {
49
49
  result = new Collection()
@@ -65,4 +65,3 @@ export const createArgumentDecorator = <Options>(type: typeof ComponentArgumentD
65
65
  }
66
66
  }
67
67
  }
68
-
@@ -0,0 +1,7 @@
1
+ import { BaseComponent, createComponentDecorator } from '../components'
2
+
3
+ type Options = { component: typeof BaseComponent<unknown>; type: Function; parameterless: boolean }
4
+
5
+ export class ConverterComponent extends BaseComponent<Options, Options & { parameterless?: boolean }> {}
6
+
7
+ export const argConverter = createComponentDecorator(ConverterComponent)
@@ -0,0 +1,54 @@
1
+ import chalk from 'chalk'
2
+ import { Collection } from 'discord.js'
3
+ import { Logger } from 'tslog'
4
+ import { BaseComponent } from '../components'
5
+ import { ComponentArgument } from '../components/ComponentArgument'
6
+ import { ConverterComponent } from '../converter'
7
+ import { CommandClient } from '../structures'
8
+
9
+ export class Extension {
10
+ protected get commandClient() {
11
+ return CommandClient.getFromModule(this)
12
+ }
13
+
14
+ protected get client() {
15
+ return this.commandClient.discord
16
+ }
17
+
18
+ private _logger?: Logger
19
+
20
+ protected get logger() {
21
+ if (!this._logger) this._logger = this.commandClient.logger.getChildLogger({ prefix: [chalk.green(`[${this.constructor.name}]`)], displayFunctionName: false })
22
+ return this._logger
23
+ }
24
+
25
+ protected async convertArguments(
26
+ component: typeof BaseComponent<unknown>,
27
+ argList: unknown[],
28
+ args: Collection<number, ComponentArgument>,
29
+ getConverterArgs: (arg: ComponentArgument, index: number) => unknown[] | Promise<unknown[]>,
30
+ ) {
31
+ const items = new Collection<unknown, { ext: object; component: ConverterComponent }>()
32
+
33
+ for (const extension of this.commandClient.registry.extensions) {
34
+ for (const converter of this.commandClient.registry.getComponentsWithType(extension, ConverterComponent)) {
35
+ if (converter.options.component != component) continue
36
+
37
+ items.set(converter.options.type, { component: converter, ext: extension })
38
+ }
39
+ }
40
+
41
+ for (const [index, arg] of args) {
42
+ const converter = items.get(arg.type)
43
+
44
+ if (!converter) {
45
+ argList[index] = undefined
46
+ continue
47
+ }
48
+
49
+ const converterArgs = await getConverterArgs(arg, index)
50
+
51
+ argList[index] = await converter.component.execute(converter.ext, converterArgs)
52
+ }
53
+ }
54
+ }
@@ -0,0 +1 @@
1
+ export * from './Extension'
@@ -0,0 +1 @@
1
+ export * from './moduleHook'
@@ -0,0 +1,31 @@
1
+ import { Collection } from 'discord.js'
2
+ import { ModuleHookStoreSymbol } from '../symbols'
3
+
4
+ type ModuleHookStore = Collection<string | symbol, Function[]>
5
+
6
+ export const getModuleHookStore = (target: object) => {
7
+ let result: ModuleHookStore | null = Reflect.getMetadata(ModuleHookStoreSymbol, target)
8
+
9
+ if (!result) {
10
+ result = new Collection()
11
+
12
+ Reflect.defineMetadata(ModuleHookStoreSymbol, result, target)
13
+ }
14
+
15
+ return result
16
+ }
17
+
18
+ export const moduleHook = (name: string): MethodDecorator => {
19
+ return (target, key) => {
20
+ const store = getModuleHookStore(target)
21
+
22
+ let v = store.get(key)
23
+
24
+ if (!v) {
25
+ v = []
26
+ store.set(key, v)
27
+ }
28
+
29
+ v.push(Reflect.get(target, key))
30
+ }
31
+ }
package/src/core/index.ts CHANGED
@@ -1 +1,4 @@
1
1
  export * from './components'
2
+ export * from './structures'
3
+ export * from './hooks'
4
+ export * from './converter'
@@ -0,0 +1,20 @@
1
+ import { BaseComponent, createComponentDecorator } from '../components'
2
+
3
+ export class ListenerComponent extends BaseComponent<{ emitter: string; event: string }, { emitter?: string; event: string }> {
4
+ defaultOptions() {
5
+ return { emitter: 'discord' }
6
+ }
7
+
8
+ constructor(options: ListenerComponent['options'], method: Function, argTypes: unknown[]) {
9
+ super(
10
+ {
11
+ event: options.event,
12
+ emitter: options.emitter ?? 'discord',
13
+ },
14
+ method,
15
+ argTypes,
16
+ )
17
+ }
18
+ }
19
+
20
+ export const listener = createComponentDecorator(ListenerComponent)
@@ -0,0 +1,36 @@
1
+ import chalk from 'chalk'
2
+ import { Client } from 'discord.js'
3
+ import EventEmitter from 'events'
4
+ import { Logger } from 'tslog'
5
+ import { ApplicationCommandExtension, ApplicationCommandExtensionConfig } from '../../applicationCommand/ApplicationCommandExtension'
6
+ import { CommandClientSymbol } from '../symbols'
7
+ import { Registry } from './Registry'
8
+
9
+ export class CommandClient extends EventEmitter {
10
+ ctsLogger: Logger
11
+ registry: Registry
12
+
13
+ constructor(public discord: Client, public logger: Logger = new Logger({ dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone })) {
14
+ super()
15
+
16
+ this.ctsLogger = logger.getChildLogger({ prefix: [chalk.blue('[command.ts]')], displayFilePath: 'hidden', displayFunctionName: false })
17
+
18
+ this.registry = new Registry(this.ctsLogger, this)
19
+
20
+ this.registry.registerEventEmitter('cts', this)
21
+ this.registry.registerEventEmitter('discord', this.discord)
22
+ }
23
+
24
+ async enableApplicationCommandsExtension(config: ApplicationCommandExtensionConfig) {
25
+ await this.registry.registerModule(new ApplicationCommandExtension(config))
26
+ this.ctsLogger.info('Application command extension enabled.')
27
+ }
28
+
29
+ getApplicationCommandsExtension() {
30
+ return this.registry.extensions.find((x) => x.constructor === ApplicationCommandExtension) as ApplicationCommandExtension | undefined
31
+ }
32
+
33
+ static getFromModule(ext: object): CommandClient {
34
+ return Reflect.getMetadata(CommandClientSymbol, ext)
35
+ }
36
+ }
@@ -0,0 +1,101 @@
1
+ import chalk from 'chalk'
2
+ import { Collection } from 'discord.js'
3
+ import EventEmitter from 'events'
4
+ import _ from 'lodash'
5
+ import { Logger } from 'tslog'
6
+ import { BaseComponent, getComponentStore } from '../components'
7
+ import { getModuleHookStore } from '../hooks'
8
+ import { ListenerComponent } from '../listener'
9
+ import { CommandClientSymbol } from '../symbols'
10
+ import { CommandClient } from './CommandClient'
11
+
12
+ export class Registry {
13
+ extensions: object[] = []
14
+
15
+ emitters: Collection<string, EventEmitter> = new Collection()
16
+
17
+ logger: Logger
18
+
19
+ constructor(logger: Logger, public client: CommandClient) {
20
+ this.logger = logger.getChildLogger({
21
+ prefix: [chalk.green('[Registry]')],
22
+ })
23
+ }
24
+
25
+ getComponentsWithTypeGlobal<T extends typeof BaseComponent<Config>, Config>(type: T): InstanceType<T>[] {
26
+ const result: InstanceType<T>[] = []
27
+
28
+ for (const ext of this.extensions) {
29
+ result.push(...this.getComponentsWithType(ext, type))
30
+ }
31
+
32
+ return result
33
+ }
34
+
35
+ getComponentsWithType<T extends typeof BaseComponent<Config>, Config>(ext: object, type: T): InstanceType<T>[] {
36
+ const componentStore = getComponentStore(ext)
37
+
38
+ return Array.from(componentStore.filter((x) => (x.constructor as unknown) === type).values() as Iterable<InstanceType<T>>)
39
+ }
40
+
41
+ registerEventListeners(ext: object) {
42
+ const listeners = this.getComponentsWithType(ext, ListenerComponent)
43
+
44
+ for (const listener of listeners) {
45
+ const emitter = this.emitters.get(listener.options.emitter)
46
+
47
+ if (emitter) {
48
+ const bound = listener.method.bind(ext)
49
+
50
+ Reflect.defineMetadata('bound', bound, listener)
51
+
52
+ emitter.addListener(listener.options.event, bound)
53
+ }
54
+ }
55
+ }
56
+
57
+ unregisterEventListeners(ext: object) {
58
+ const listeners = this.getComponentsWithType(ext, ListenerComponent)
59
+
60
+ for (const listener of listeners) {
61
+ const emitter = this.emitters.get(listener.options.emitter)
62
+ const bound = Reflect.getMetadata('bound', listener)
63
+
64
+ if (emitter && bound) {
65
+ emitter.removeListener(listener.options.event, bound)
66
+ }
67
+ }
68
+ }
69
+
70
+ async registerModule(ext: object) {
71
+ Reflect.defineMetadata(CommandClientSymbol, this.client, ext)
72
+
73
+ this.registerEventListeners(ext)
74
+ await this.runModuleHook(ext, 'load')
75
+ this.extensions.push(ext)
76
+ this.logger.info(`Module registered: ${chalk.green(ext.constructor.name)}`)
77
+ }
78
+
79
+ async unregisterModule(ext: object) {
80
+ this.unregisterEventListeners(ext)
81
+ await this.runModuleHook(ext, 'unload')
82
+ _.remove(this.extensions, (x) => x === ext)
83
+ this.logger.info(`Module unregistered: ${chalk.green(ext.constructor.name)}`)
84
+ }
85
+
86
+ runModuleHook(ext: object, hookName: string, ...args: unknown[]) {
87
+ const hooks = getModuleHookStore(ext)
88
+
89
+ const functions = hooks.get(hookName)
90
+
91
+ if (functions) {
92
+ for (const fn of functions) {
93
+ fn.call(ext, ...args)
94
+ }
95
+ }
96
+ }
97
+
98
+ registerEventEmitter(name: string, emitter: EventEmitter) {
99
+ this.emitters.set(name, emitter)
100
+ }
101
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Registry'
2
+ export * from './CommandClient'
@@ -1,2 +1,4 @@
1
1
  export const ComponentStoreSymbol = Symbol()
2
2
  export const ComponentArgStoreSymbol = Symbol()
3
+ export const ModuleHookStoreSymbol = Symbol()
4
+ export const CommandClientSymbol = Symbol()
package/src/index.ts CHANGED
@@ -1,10 +1,10 @@
1
- /*
2
- * File: index.ts
3
- *
4
- * Copyright (c) 2022-2022 pikokr
5
- *
6
- * Licensed under MIT License. Please see more defails in LICENSE file.
7
- */
8
-
9
- export * from './core'
10
- export * from './applicationCommand'
1
+ /*
2
+ * File: index.ts
3
+ *
4
+ * Copyright (c) 2022-2022 pikokr
5
+ *
6
+ * Licensed under MIT License. Please see more defails in LICENSE file.
7
+ */
8
+
9
+ export * from './core'
10
+ export * from './applicationCommand'
package/test/index.ts CHANGED
@@ -1,22 +1,23 @@
1
- import { ApplicationCommandOptionType } from 'discord.js'
2
- import { applicationCommand, getComponentStore, option } from '../src'
1
+ import { ApplicationCommandOptionType, ApplicationCommandType, ChatInputCommandInteraction, Client } from 'discord.js'
2
+ import { applicationCommand, CommandClient, moduleHook, option, Registry } from '../src'
3
+ import { listener } from '../src/core/listener'
4
+ import 'dotenv/config'
5
+ import { Logger } from 'tslog'
6
+ import chalk from 'chalk'
7
+ import { Extension } from '../src/core/extensions'
3
8
 
4
- class Test {
9
+ class Test extends Extension {
5
10
  @applicationCommand({
11
+ type: ApplicationCommandType.ChatInput,
6
12
  name: 'test',
7
13
  description: 'wow this is test',
8
14
  })
9
- async testCommand(
10
- @option({
11
- name: 'hello',
12
- description: '와아',
13
- type: ApplicationCommandOptionType.String,
14
- })
15
- hello: string,
16
- world: string,
17
- ) {}
15
+ async testCommand(i: ChatInputCommandInteraction) {
16
+ i.reply('Wow')
17
+ }
18
18
 
19
19
  @applicationCommand({
20
+ type: ApplicationCommandType.ChatInput,
20
21
  name: 'test2',
21
22
  description: 'wow this is test wow',
22
23
  })
@@ -25,13 +26,50 @@ class Test {
25
26
  name: 'sans',
26
27
  description: '와',
27
28
  type: ApplicationCommandOptionType.String,
29
+ required: true,
28
30
  })
29
31
  wa: string,
30
- ) {}
32
+ i: ChatInputCommandInteraction,
33
+ ) {
34
+ i.reply(wa)
35
+ }
36
+
37
+ @moduleHook('load')
38
+ load() {
39
+ this.logger.info('Load')
40
+ }
41
+
42
+ @moduleHook('unload')
43
+ unload() {
44
+ this.logger.info('Unload')
45
+ }
46
+
47
+ @listener({ event: 'ready' })
48
+ testEvent() {
49
+ this.logger.info(`Login: ${chalk.green(client.user!.tag)}`)
50
+ }
31
51
  }
32
52
 
33
53
  const ext = new Test()
34
54
 
35
- const store = getComponentStore(ext)
55
+ const client = new Client({ intents: [] })
56
+
57
+ const logger = new Logger({ dateTimeTimezone: Intl.DateTimeFormat().resolvedOptions().timeZone })
58
+
59
+ const cc = new CommandClient(client, logger)
60
+
61
+ const registry = cc.registry
62
+
63
+ const run = async () => {
64
+ await cc.enableApplicationCommandsExtension({
65
+ guilds: ['832938554438844438'],
66
+ })
67
+
68
+ await registry.registerModule(ext)
69
+
70
+ await client.login(process.env.TOKEN)
71
+
72
+ await cc.getApplicationCommandsExtension()!.sync()
73
+ }
36
74
 
37
- console.log(store)
75
+ run()
package/tsconfig.json CHANGED
@@ -15,11 +15,10 @@
15
15
  "declaration": true,
16
16
  /* Generates corresponding '.d.ts' file. */
17
17
  // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
18
- "sourceMap": true, /* Generates corresponding '.map' file. */
18
+ "sourceMap": true /* Generates corresponding '.map' file. */,
19
19
  // "outFile": "./", /* Concatenate and emit output to single file. */
20
20
  "outDir": "./dist",
21
21
  /* Redirect output structure to the directory. */
22
- "rootDir": "./src",
23
22
  /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
24
23
  // "composite": true, /* Enable project compilation */
25
24
  // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
@@ -31,6 +30,7 @@
31
30
 
32
31
  /* Strict Type-Checking Options */
33
32
  "strict": true,
33
+
34
34
  /* Enable all strict type-checking options. */
35
35
  // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
36
36
  // "strictNullChecks": true, /* Enable strict null checks. */
@@ -1,4 +1,8 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
- "exclude": ["node_modules", "scripts", "test", "tsup.config.ts"]
4
- }
3
+ "exclude": ["node_modules", "scripts", "test", "tsup.config.ts"],
4
+ "include": ["src"],
5
+ "compilerOptions": {
6
+ "rootDir": "./src",
7
+ }
8
+ }
package/tsup.config.ts CHANGED
@@ -1,11 +1,11 @@
1
- /*
2
- * File: tsup.config.ts
3
- *
4
- * Copyright (c) 2022-2022 pikokr
5
- *
6
- * Licensed under MIT License. Please see more defails in LICENSE file.
7
- */
8
-
1
+ /*
2
+ * File: tsup.config.ts
3
+ *
4
+ * Copyright (c) 2022-2022 pikokr
5
+ *
6
+ * Licensed under MIT License. Please see more defails in LICENSE file.
7
+ */
8
+
9
9
  import { defineConfig } from 'tsup'
10
10
 
11
11
  export default defineConfig({
@@ -15,4 +15,5 @@ export default defineConfig({
15
15
  clean: true,
16
16
  dts: true,
17
17
  minify: true,
18
+ tsconfig: 'tsconfig.prod.json',
18
19
  })