@pikokr/command.ts 3.0.0-dev.7170769 → 3.0.0-dev.85a29c3

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.
Files changed (83) hide show
  1. package/.prettierrc +2 -1
  2. package/README.md +3 -1
  3. package/dist/builtinModules/BuiltInModule.d.ts +4 -0
  4. package/dist/builtinModules/BuiltInModule.js +12 -0
  5. package/dist/builtinModules/BuiltinCommandConverters.d.ts +14 -0
  6. package/dist/builtinModules/BuiltinCommandConverters.js +89 -0
  7. package/dist/builtinModules/CommandHandler.d.ts +9 -0
  8. package/dist/builtinModules/CommandHandler.js +134 -0
  9. package/dist/builtinModules/index.d.ts +2 -0
  10. package/dist/builtinModules/index.js +14 -0
  11. package/dist/command/ArgumentConverter.d.ts +9 -0
  12. package/dist/command/ArgumentConverter.js +14 -0
  13. package/dist/command/Command.d.ts +14 -5
  14. package/dist/command/Command.js +9 -4
  15. package/dist/command/decorator.d.ts +11 -2
  16. package/dist/command/decorator.js +66 -10
  17. package/dist/command/index.d.ts +2 -0
  18. package/dist/command/index.js +2 -0
  19. package/dist/command/utils.d.ts +2 -0
  20. package/dist/command/utils.js +17 -0
  21. package/dist/constants.d.ts +7 -0
  22. package/dist/constants.js +9 -2
  23. package/dist/error/ArgumentConverterNotFound.d.ts +7 -0
  24. package/dist/error/ArgumentConverterNotFound.js +11 -0
  25. package/dist/error/ArgumentNotProvided.d.ts +8 -0
  26. package/dist/error/ArgumentNotProvided.js +12 -0
  27. package/dist/error/CommandCheckFailed.d.ts +7 -0
  28. package/dist/error/CommandCheckFailed.js +11 -0
  29. package/dist/error/CommandNotFound.d.ts +4 -0
  30. package/dist/error/CommandNotFound.js +10 -0
  31. package/dist/error/PermissionRequired.d.ts +10 -0
  32. package/dist/error/PermissionRequired.js +18 -0
  33. package/dist/error/index.d.ts +4 -0
  34. package/dist/error/index.js +4 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.js +3 -0
  37. package/dist/listener/Listener.d.ts +5 -0
  38. package/dist/listener/Listener.js +10 -0
  39. package/dist/listener/decorator.d.ts +2 -0
  40. package/dist/listener/decorator.js +21 -0
  41. package/dist/listener/index.d.ts +2 -0
  42. package/dist/listener/index.js +14 -0
  43. package/dist/structures/CommandClient.d.ts +0 -1
  44. package/dist/structures/CommandClient.js +15 -38
  45. package/dist/structures/Module.d.ts +7 -0
  46. package/dist/structures/Module.js +13 -0
  47. package/dist/structures/Registry.d.ts +16 -6
  48. package/dist/structures/Registry.js +113 -22
  49. package/dist/structures/index.d.ts +2 -1
  50. package/dist/structures/index.js +2 -1
  51. package/dist/typings.d.ts +11 -0
  52. package/dist/typings.js +2 -0
  53. package/dist/utils.d.ts +1 -0
  54. package/dist/utils.js +10 -0
  55. package/package.json +3 -2
  56. package/src/builtinModules/BuiltInModule.ts +9 -0
  57. package/src/builtinModules/BuiltinCommandConverters.ts +56 -0
  58. package/src/builtinModules/CommandHandler.ts +120 -0
  59. package/src/builtinModules/index.ts +2 -0
  60. package/src/command/ArgumentConverter.ts +10 -0
  61. package/src/command/Command.ts +20 -5
  62. package/src/command/decorator.ts +84 -12
  63. package/src/command/index.ts +2 -0
  64. package/src/command/utils.ts +15 -0
  65. package/src/constants.ts +15 -1
  66. package/src/error/ArgumentConverterNotFound.ts +8 -0
  67. package/src/error/ArgumentNotProvided.ts +8 -0
  68. package/src/error/CommandCheckFailed.ts +8 -0
  69. package/src/error/CommandNotFound.ts +5 -0
  70. package/src/error/PermissionRequired.ts +13 -0
  71. package/src/error/index.ts +4 -0
  72. package/src/index.ts +3 -0
  73. package/src/listener/Listener.ts +3 -0
  74. package/src/listener/decorator.ts +25 -0
  75. package/src/listener/index.ts +2 -0
  76. package/src/structures/CommandClient.ts +10 -48
  77. package/src/structures/Module.ts +21 -0
  78. package/src/structures/Registry.ts +108 -19
  79. package/src/structures/index.ts +2 -1
  80. package/src/typings.ts +12 -0
  81. package/src/utils.ts +6 -0
  82. package/test/index.ts +5 -2
  83. package/test/modules/test.ts +44 -0
@@ -0,0 +1,120 @@
1
+ import { BuiltInModule } from './BuiltInModule'
2
+ import { Registry } from '../structures'
3
+ import { listener } from '../listener'
4
+ import { Message } from 'discord.js'
5
+ import { CommandClient } from '../structures'
6
+ import { Command } from '../command'
7
+ import { ArgumentConverterNotFound, ArgumentNotProvided, CommandCheckFailed } from '../error'
8
+ import { CommandNotFound } from '../error/CommandNotFound'
9
+
10
+ export class CommandHandler extends BuiltInModule {
11
+ private client: CommandClient
12
+
13
+ constructor(private registry: Registry) {
14
+ super()
15
+ this.client = registry.client
16
+ }
17
+
18
+ @listener('messageCreate')
19
+ async message(msg: Message) {
20
+ const error = (error: Error) => this.client.client.emit('commandError', error, msg)
21
+
22
+ try {
23
+ const prefixList: string[] | string =
24
+ typeof this.client.options.command.prefix === 'string'
25
+ ? this.client.options.command.prefix
26
+ : typeof this.client.options.command.prefix === 'function'
27
+ ? await this.client.options.command.prefix(msg)
28
+ : this.client.options.command.prefix
29
+ let prefix: string
30
+ if (typeof prefixList === 'object') {
31
+ const res = prefixList.find((x) => msg.content.includes(x))
32
+
33
+ if (!res) return
34
+
35
+ prefix = res
36
+ } else {
37
+ if (!msg.content.includes(prefixList)) return
38
+ prefix = prefixList
39
+ }
40
+
41
+ if (!msg.content.startsWith(prefix)) return
42
+
43
+ const args = msg.content.slice(prefix.length).split(' ')
44
+
45
+ const command = args.shift()
46
+
47
+ if (!command) return
48
+
49
+ let cmd: Command | null = null
50
+
51
+ for (const c of this.registry.commands) {
52
+ if (c.name === command) {
53
+ cmd = c
54
+ break
55
+ }
56
+ if ((typeof c.aliases === 'function' ? await c.aliases(msg) : c.aliases).includes(command)) {
57
+ cmd = c
58
+ break
59
+ }
60
+ }
61
+
62
+ if (!cmd) return error(new CommandNotFound(command))
63
+
64
+ msg.data = {
65
+ cts: this.client,
66
+ command: cmd,
67
+ prefix: prefix,
68
+ }
69
+
70
+ const module = this.registry.modules.find((x) => x.commands.includes(cmd!))
71
+
72
+ if (!module) return
73
+
74
+ const argList: any[] = []
75
+
76
+ for (const check of cmd.checks) {
77
+ if (!(await check(msg))) return error(new CommandCheckFailed(msg, cmd))
78
+ }
79
+
80
+ for (let i = 0; i < cmd.argTypes.length; i++) {
81
+ const argType = cmd.argTypes[i]
82
+ const converter = this.registry.argumentConverters.find((x) => x.type === argType.type)
83
+
84
+ if (argType.rest) {
85
+ const i = args.join(' ')
86
+ if (!i) break
87
+ argList.push(i)
88
+ break
89
+ }
90
+
91
+ if (!converter) return error(new ArgumentConverterNotFound(argType, msg))
92
+
93
+ if (converter.withoutParameter) {
94
+ argList.push(await converter.execute(module, msg))
95
+ continue
96
+ }
97
+ const arg = args.shift()
98
+ if (argType.optional && !arg) {
99
+ break
100
+ }
101
+ if (!arg) {
102
+ return error(new ArgumentNotProvided(i, cmd, msg))
103
+ }
104
+ const executed = await converter.execute(module, msg, arg)
105
+ if (!executed === undefined) {
106
+ return error(new ArgumentNotProvided(i, cmd, msg))
107
+ }
108
+ argList.push(executed)
109
+ }
110
+
111
+ try {
112
+ cmd.execute(module, argList)
113
+ } catch (e: any) {
114
+ return error(e)
115
+ }
116
+ } catch (e) {
117
+ return error(e)
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,2 @@
1
+ export * from './CommandHandler'
2
+ export * from './BuiltinCommandConverters'
@@ -0,0 +1,10 @@
1
+ import { Module } from '../structures'
2
+ import { Message } from 'discord.js'
3
+
4
+ export class ArgumentConverter {
5
+ execute(module: Module, msg: Message, arg?: string) {
6
+ return this.run.apply(module, [msg, arg])
7
+ }
8
+
9
+ constructor(public type: object, private run: Function, public withoutParameter: boolean) {}
10
+ }
@@ -1,15 +1,30 @@
1
1
  import { Module } from '../structures'
2
+ import { Message } from 'discord.js'
3
+ import { KCommandChecks } from '../constants'
4
+
5
+ export type Argument = {
6
+ optional: boolean
7
+ type: any
8
+ rest: boolean
9
+ }
10
+
11
+ export type CheckFunction = (msg: Message) => boolean | Promise<boolean>
2
12
 
3
13
  export class Command {
4
- execute(args: string[]) {
5
- return this.run.call(this.module, args)
14
+ execute(module: Module, args: any[]) {
15
+ return this.run.apply(module, args)
16
+ }
17
+
18
+ get checks(): CheckFunction[] {
19
+ return Reflect.getMetadata(KCommandChecks, this.module, this.key) || []
6
20
  }
7
21
 
8
22
  constructor(
9
- public module: Module,
10
23
  private run: Function,
11
- public argTypes: any[],
24
+ public argTypes: Argument[],
12
25
  public name: string,
13
- public aliases: string[],
26
+ public aliases: string[] | ((msg: Message) => string[]),
27
+ public module: Module,
28
+ public key: symbol | string,
14
29
  ) {}
15
30
  }
@@ -1,18 +1,18 @@
1
- import { KCommands } from '../constants'
2
- import { Module } from '../structures'
3
- import { InvalidTargetError } from '../error'
1
+ import { KArgumentConverters, KCommands, KOptionals, KRest } from '../constants'
4
2
  import { Command } from './Command'
3
+ import { checkTarget } from '../utils'
4
+ import { ArgumentConverter } from './ArgumentConverter'
5
+ import { Module } from '../structures'
6
+ import { createCheckDecorator } from './utils'
7
+ import { Message, PermissionResolvable, Permissions, TextChannel } from 'discord.js'
8
+ import { ClientPermissionRequired, UserPermissionRequired } from '../error'
5
9
 
6
10
  type CommandOptions = {
7
11
  name: string
8
- aliases: string[]
12
+ aliases: string[] | ((msg: Message) => string[])
9
13
  }
10
14
 
11
- const checkTarget = (target: Object) => {
12
- if (!(target instanceof Module)) throw new InvalidTargetError()
13
- }
14
-
15
- export const command = (options: Partial<CommandOptions>) => {
15
+ export const command = (options: Partial<CommandOptions> = {}) => {
16
16
  return (
17
17
  target: Object,
18
18
  propertyKey: string,
@@ -22,14 +22,23 @@ export const command = (options: Partial<CommandOptions>) => {
22
22
 
23
23
  let properties: Command[] = Reflect.getMetadata(KCommands, target)
24
24
 
25
- const params = Reflect.getMetadata('design:paramtypes', target, propertyKey)
25
+ const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
26
+
27
+ const optionals: number = Reflect.getMetadata(KOptionals, target, propertyKey) || -1
28
+
29
+ const rest = Reflect.getMetadata(KRest, target, propertyKey) || -1
26
30
 
27
31
  const command = new Command(
28
- target as Module,
29
32
  Reflect.get(target, propertyKey),
30
- params,
33
+ params.map((x, i) => ({
34
+ type: x,
35
+ optional: optionals === -1 ? false : optionals <= i,
36
+ rest: rest === -1 ? false : rest === i,
37
+ })),
31
38
  options.name || propertyKey,
32
39
  options.aliases || [],
40
+ target as Module,
41
+ propertyKey,
33
42
  )
34
43
 
35
44
  if (properties) {
@@ -40,3 +49,66 @@ export const command = (options: Partial<CommandOptions>) => {
40
49
  }
41
50
  }
42
51
  }
52
+
53
+ export const argumentConverter = (type: object, requireParameter = true) => {
54
+ return (
55
+ target: Object,
56
+ propertyKey: string,
57
+ // descriptor: TypedPropertyDescriptor<any>,
58
+ ) => {
59
+ checkTarget(target)
60
+
61
+ let properties: ArgumentConverter[] = Reflect.getMetadata(KArgumentConverters, target)
62
+
63
+ const converter = new ArgumentConverter(type, Reflect.get(target, propertyKey), !requireParameter)
64
+
65
+ if (properties) {
66
+ properties.push(converter)
67
+ } else {
68
+ properties = [converter]
69
+ Reflect.defineMetadata(KArgumentConverters, properties, target)
70
+ }
71
+ }
72
+ }
73
+
74
+ export const optional: ParameterDecorator = (target, propertyKey, parameterIndex) => {
75
+ checkTarget(target)
76
+
77
+ Reflect.defineMetadata(KOptionals, parameterIndex, target, propertyKey)
78
+ }
79
+
80
+ export const rest: ParameterDecorator = (target, propertyKey, parameterIndex) => {
81
+ checkTarget(target)
82
+
83
+ const params: any[] = Reflect.getMetadata('design:paramtypes', target, propertyKey)
84
+
85
+ if (params.length - 1 !== parameterIndex) throw new Error('Rest decorator must be used at last argument.')
86
+
87
+ if (params[parameterIndex] !== String) throw new Error('Rest argument type must be "String"')
88
+
89
+ Reflect.defineMetadata(KRest, parameterIndex, target, propertyKey)
90
+ }
91
+
92
+ export const ownerOnly = createCheckDecorator((msg) => msg.data.cts.owners.includes(msg.author.id))
93
+
94
+ export const guildOnly = createCheckDecorator((msg) => !!msg.guild)
95
+
96
+ export const dmOnly = createCheckDecorator((msg) => !msg.guild)
97
+
98
+ export const requireUserPermissions = (permission: PermissionResolvable) =>
99
+ createCheckDecorator((msg) => {
100
+ if (!msg.guild || !msg.member) throw new Error('This command must be used in serer.')
101
+ if (msg.member.permissionsIn(msg.channel as TextChannel).has(permission)) {
102
+ return true
103
+ }
104
+ throw new UserPermissionRequired(msg.member, new Permissions(permission))
105
+ })
106
+
107
+ export const requireClientPermissions = (permission: PermissionResolvable) =>
108
+ createCheckDecorator((msg) => {
109
+ if (!msg.guild) throw new Error('This command must be used in serer.')
110
+ if (msg.guild.me!.permissionsIn(msg.channel as TextChannel).has(permission)) {
111
+ return true
112
+ }
113
+ throw new ClientPermissionRequired(new Permissions(permission))
114
+ })
@@ -1,2 +1,4 @@
1
1
  export * from './Command'
2
2
  export * from './decorator'
3
+ export * from './ArgumentConverter'
4
+ export * from './utils'
@@ -0,0 +1,15 @@
1
+ import { Message } from 'discord.js'
2
+ import type { CheckFunction } from './Command'
3
+ import { KCommandChecks } from '../constants'
4
+
5
+ export const createCheckDecorator = (execute: (msg: Message) => boolean | Promise<boolean>): MethodDecorator => {
6
+ return (target, propertyKey) => {
7
+ let properties: CheckFunction[] = Reflect.getMetadata(KCommandChecks, target, propertyKey)
8
+ if (properties) {
9
+ properties.push(execute)
10
+ } else {
11
+ properties = [execute]
12
+ Reflect.defineMetadata(KCommandChecks, properties, target, propertyKey)
13
+ }
14
+ }
15
+ }
package/src/constants.ts CHANGED
@@ -1,3 +1,17 @@
1
- export const KCommands = Symbol('Command.TS Command')
1
+ export const KCommands = Symbol('Command.TS Commands')
2
+
3
+ export const KListeners = Symbol('Command.TS Listeners')
2
4
 
3
5
  export const KModulePath = Symbol('Command.TS Module Path')
6
+
7
+ export const KListenerExecuteCache = Symbol('Command.TS Module Identifier')
8
+
9
+ export const KBuiltInModule = Symbol('Command.TS Built-In Module')
10
+
11
+ export const KOptionals = Symbol('Command.TS Optional Parameters')
12
+
13
+ export const KRest = Symbol('Command.TS Rest Parameter')
14
+
15
+ export const KArgumentConverters = Symbol('Command.TS Argument Converter')
16
+
17
+ export const KCommandChecks = Symbol('Command.TS Command Checks')
@@ -0,0 +1,8 @@
1
+ import { Message } from 'discord.js'
2
+ import type { Argument } from '../command'
3
+
4
+ export class ArgumentConverterNotFound extends Error {
5
+ constructor(public type: Argument, public msg: Message) {
6
+ super(`Argument converter ${type.type.name} not found.`)
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ import { Message } from 'discord.js'
2
+ import { Command } from '../command'
3
+
4
+ export class ArgumentNotProvided extends Error {
5
+ constructor(public index: number, public command: Command, public msg: Message) {
6
+ super(`Required argument #${index} not provided.`)
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ import { Message } from 'discord.js'
2
+ import { Command } from '../command'
3
+
4
+ export class CommandCheckFailed extends Error {
5
+ constructor(public msg: Message, public command: Command) {
6
+ super()
7
+ }
8
+ }
@@ -0,0 +1,5 @@
1
+ export class CommandNotFound extends Error {
2
+ constructor(public commandName: string) {
3
+ super(`Command ${commandName} not found.`)
4
+ }
5
+ }
@@ -0,0 +1,13 @@
1
+ import { GuildMember, Permissions } from 'discord.js'
2
+
3
+ export class UserPermissionRequired extends Error {
4
+ constructor(public user: GuildMember, public permissions: Permissions) {
5
+ super()
6
+ }
7
+ }
8
+
9
+ export class ClientPermissionRequired extends Error {
10
+ constructor(public permissions: Permissions) {
11
+ super()
12
+ }
13
+ }
@@ -1,2 +1,6 @@
1
1
  export * from './InvalidTargetError'
2
2
  export * from './ModuleError'
3
+ export * from './ArgumentNotProvided'
4
+ export * from './ArgumentConverterNotFound'
5
+ export * from './CommandCheckFailed'
6
+ export * from './PermissionRequired'
package/src/index.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import 'reflect-metadata'
2
+ import './typings'
2
3
 
3
4
  export * from './interface'
4
5
  export * from './structures'
5
6
  export * from './error'
6
7
  export * from './command'
8
+ export * from './listener'
9
+ export * from './builtinModules/BuiltInModule'
@@ -0,0 +1,3 @@
1
+ export class Listener {
2
+ constructor(public name: string, public execute: Function) {}
3
+ }
@@ -0,0 +1,25 @@
1
+ import { checkTarget } from '../utils'
2
+ import { KListeners } from '../constants'
3
+ import { Listener } from './Listener'
4
+ import { Module } from '../structures'
5
+
6
+ export const listener = (event: string) => {
7
+ return (
8
+ target: Module,
9
+ propertyKey: string,
10
+ // descriptor: TypedPropertyDescriptor<any>,
11
+ ) => {
12
+ checkTarget(target)
13
+
14
+ let properties: Listener[] = Reflect.getMetadata(KListeners, target)
15
+
16
+ const listener = new Listener(event, Reflect.get(target, propertyKey))
17
+
18
+ if (properties) {
19
+ properties.push(listener)
20
+ } else {
21
+ properties = [listener]
22
+ Reflect.defineMetadata(KListeners, properties, target)
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,2 @@
1
+ export * from './Listener'
2
+ export * from './decorator'
@@ -1,12 +1,10 @@
1
1
  import _ from 'lodash'
2
2
  import { Registry } from './Registry'
3
3
  import { Client, Message, User } from 'discord.js'
4
+ import { BuiltinCommandConverters, CommandHandler } from '../builtinModules'
4
5
 
5
6
  export interface CommandOptions {
6
- prefix:
7
- | string
8
- | ((msg: any) => string | Promise<string | string[]> | string[])
9
- | string[]
7
+ prefix: string | ((msg: any) => string | Promise<string | string[]> | string[]) | string[]
10
8
  }
11
9
 
12
10
  export interface CommandClientOptions {
@@ -25,40 +23,10 @@ export class CommandClient {
25
23
  registry = new Registry(this)
26
24
  client: Client
27
25
 
28
- private async handle(msg: Message) {
29
- const prefixList: string[] | string =
30
- typeof this.options.command.prefix === 'string'
31
- ? this.options.command.prefix
32
- : typeof this.options.command.prefix === 'function'
33
- ? await this.options.command.prefix(msg)
34
- : this.options.command.prefix
35
- let prefix: string
36
- if (typeof prefixList === 'object') {
37
- const res = prefixList.find((x) => msg.content.includes(x))
38
-
39
- if (!res) return
40
-
41
- prefix = res
42
- } else {
43
- if (!msg.content.includes(prefixList)) return
44
- prefix = prefixList
45
- }
46
-
47
- const args = msg.content.slice(prefix.length).split(' ')
48
-
49
- const command = args.shift()
50
-
51
- if (!command) return
52
-
53
- this.registry.commands
54
-
55
- console.log(command)
56
- console.log(args)
57
- }
58
-
59
26
  private _isReady = false
60
27
 
61
- private fetchOwners(): string[] {
28
+ private async fetchOwners(): Promise<string[]> {
29
+ await this.client.application?.fetch()
62
30
  const o = this.client.application?.owner
63
31
  if (!o) return []
64
32
  if (o instanceof User) return [o.id]
@@ -69,27 +37,21 @@ export class CommandClient {
69
37
  if (this._isReady) return
70
38
  this._isReady = true
71
39
  if (this.options.owners === 'auto') {
72
- const owners = this.fetchOwners()
40
+ const owners = await this.fetchOwners()
73
41
  this.owners.push(...owners)
74
42
  }
75
43
  }
76
44
 
77
- constructor({
78
- client,
79
- ...options
80
- }: Partial<CommandClientOptionsParam> & { client: Client }) {
45
+ constructor({ client, ...options }: Partial<CommandClientOptionsParam> & { client: Client }) {
81
46
  this.client = client
82
- this.options = _.merge<
83
- Partial<CommandClientOptionsParam>,
84
- CommandClientOptions
85
- >(options, {
47
+ this.options = _.merge<Partial<CommandClientOptionsParam>, CommandClientOptions>(options, {
86
48
  command: {
87
49
  prefix: '!',
88
50
  },
89
51
  owners: 'auto',
90
52
  })
91
-
92
- this.client.on('messageCreate', (msg) => this.handle(msg))
93
- this.client.once('ready', this.ready)
53
+ this.client.once('ready', () => this.ready())
54
+ this.registry.registerModule(new CommandHandler(this.registry))
55
+ this.registry.registerModule(new BuiltinCommandConverters(this))
94
56
  }
95
57
  }
@@ -1,4 +1,25 @@
1
+ import { KArgumentConverters, KCommands, KListeners, KModulePath } from '../constants'
2
+ import type { Command } from '../command'
3
+ import { Listener } from '../listener'
4
+ import { ArgumentConverter } from '../command'
5
+
1
6
  export abstract class Module {
7
+ get commands(): Command[] {
8
+ return Reflect.getMetadata(KCommands, this) || []
9
+ }
10
+
11
+ get listeners(): Listener[] {
12
+ return Reflect.getMetadata(KListeners, this) || []
13
+ }
14
+
15
+ get argumentConverters(): ArgumentConverter[] {
16
+ return Reflect.getMetadata(KArgumentConverters, this) || []
17
+ }
18
+
19
+ get path(): string | undefined {
20
+ return Reflect.getMetadata(KModulePath, this)
21
+ }
22
+
2
23
  load() {}
3
24
  unload() {}
4
25
  beforeReload() {}