Commit d3fb2095 authored by nanahira's avatar nanahira

infer option type

parent 5fddfa16
...@@ -60,11 +60,18 @@ export function UseCommand( ...@@ -60,11 +60,18 @@ export function UseCommand(
const putOptions: CommandPut.Config<keyof CommandPut.ConfigMap>[] = const putOptions: CommandPut.Config<keyof CommandPut.ConfigMap>[] =
Reflect.getMetadata(KoishiCommandPutDef, obj.constructor, key) || Reflect.getMetadata(KoishiCommandPutDef, obj.constructor, key) ||
undefined; undefined;
// eslint-disable-next-line @typescript-eslint/ban-types
const paramTypes: Function[] = Reflect.getMetadata(
'design:paramtypes',
obj,
key,
);
const metadataDec = DoRegister.command({ const metadataDec = DoRegister.command({
def, def,
desc, desc,
config, config,
putOptions, putOptions,
paramTypes,
}); });
return metadataDec(obj, key, des); return metadataDec(obj, key, des);
}; };
......
...@@ -103,6 +103,8 @@ export interface CommandRegisterConfig<D extends string = string> { ...@@ -103,6 +103,8 @@ export interface CommandRegisterConfig<D extends string = string> {
desc?: string; desc?: string;
config?: CommandConfigExtended; config?: CommandConfigExtended;
putOptions?: CommandPut.Config[]; putOptions?: CommandPut.Config[];
// eslint-disable-next-line @typescript-eslint/ban-types
paramTypes: Function[];
} }
export interface CommandConfigExtended extends Command.Config { export interface CommandConfigExtended extends Command.Config {
......
...@@ -32,6 +32,9 @@ export class MethodRegistry< ...@@ -32,6 +32,9 @@ export class MethodRegistry<
EXT extends any[] = [], EXT extends any[] = [],
> extends AbstractRegistry<MethodMap<M, R, EXT>> { > extends AbstractRegistry<MethodMap<M, R, EXT>> {
execute<K extends keyof M>(info: MappingStruct<M, K>, ...ext: EXT) { execute<K extends keyof M>(info: MappingStruct<M, K>, ...ext: EXT) {
if (!info) {
return;
}
const fun = this.get(info.type); const fun = this.get(info.type);
if (!fun) { if (!fun) {
return; return;
......
...@@ -32,11 +32,12 @@ export namespace CommandPut { ...@@ -32,11 +32,12 @@ export namespace CommandPut {
export const preRegistry = new MethodRegistry< export const preRegistry = new MethodRegistry<
ConfigMap, ConfigMap,
void, void,
[Command, Context] // eslint-disable-next-line @typescript-eslint/ban-types
[Command, Context, Function]
>(); >();
preRegistry.extend('option', (data, cmd, ctx) => preRegistry.extend('option', (data, cmd, ctx, nativeType) =>
applyOptionToCommand(ctx, cmd, data), applyOptionToCommand(ctx, cmd, data, nativeType),
); );
preRegistry.extend('user', (data, cmd) => { preRegistry.extend('user', (data, cmd) => {
...@@ -61,7 +62,12 @@ export namespace CommandPut { ...@@ -61,7 +62,12 @@ export namespace CommandPut {
registerTemplate(data, ctx, cmd), registerTemplate(data, ctx, cmd),
); );
export const registry = new MethodRegistry<ConfigMap, any, [Argv, any[]]>(); export const registry = new MethodRegistry<
ConfigMap,
any,
// eslint-disable-next-line @typescript-eslint/ban-types
[Argv, any[], Function]
>();
registry.extend('args', (data, argv, args) => args); registry.extend('args', (data, argv, args) => args);
registry.extend('arg', (data, argv, args) => args[data]); registry.extend('arg', (data, argv, args) => args[data]);
......
...@@ -133,12 +133,17 @@ export namespace DoRegister { ...@@ -133,12 +133,17 @@ export namespace DoRegister {
obj[key](argv, ...args), obj[key](argv, ...args),
); );
} else { } else {
for (const putOption of data.putOptions) { for (let i = 0; i < data.putOptions.length; i++) {
CommandPut.preRegistry.execute(putOption, command, ctx); const putOption = data.putOptions[i];
if (!putOption) {
continue;
}
const nativeType = data.paramTypes[i];
CommandPut.preRegistry.execute(putOption, command, ctx, nativeType);
} }
command.action((argv: Argv, ...args: any[]) => { command.action((argv: Argv, ...args: any[]) => {
const params = data.putOptions.map((o) => const params = data.putOptions.map((o, i) =>
CommandPut.registry.execute(o, argv, args), CommandPut.registry.execute(o, argv, args, data.paramTypes[i]),
); );
return obj[key](...params); return obj[key](...params);
}); });
......
import { Command, Context, Dict } from 'koishi'; import { Argv, Command, Context, Dict } from 'koishi';
import { import {
CommandOptionConfig, CommandOptionConfig,
ContextSelector, ContextSelector,
...@@ -55,12 +55,22 @@ export const registerTemplate = ( ...@@ -55,12 +55,22 @@ export const registerTemplate = (
} }
}; };
// eslint-disable-next-line @typescript-eslint/ban-types
const nativeTypeMapping = new Map<Function, Argv.Type>();
nativeTypeMapping.set(String, 'string');
nativeTypeMapping.set(Number, 'number');
nativeTypeMapping.set(Boolean, 'boolean');
nativeTypeMapping.set(Date, 'date');
export function applyOptionToCommand( export function applyOptionToCommand(
ctx: Context, ctx: Context,
cmd: Command, cmd: Command,
def: CommandOptionConfig, def: CommandOptionConfig,
// eslint-disable-next-line @typescript-eslint/ban-types
nativeType?: Function,
) { ) {
const { name, desc, config } = def; const { name, config } = def;
const { desc } = def;
if (config?.description) { if (config?.description) {
const desc = adaptLocaleDict(config.description); const desc = adaptLocaleDict(config.description);
for (const [locale, text] of Object.entries(desc)) { for (const [locale, text] of Object.entries(desc)) {
...@@ -69,5 +79,13 @@ export function applyOptionToCommand( ...@@ -69,5 +79,13 @@ export function applyOptionToCommand(
} }
const clonedConfig = { ...(config || {}) }; const clonedConfig = { ...(config || {}) };
delete clonedConfig.description; delete clonedConfig.description;
return cmd.option(name, desc, clonedConfig); cmd = cmd.option(name, desc, clonedConfig);
const option = cmd._options[name];
if (!option.type && nativeType) {
const inferredType = nativeTypeMapping.get(nativeType);
if (inferredType) {
option.type = inferredType;
}
}
return cmd;
} }
...@@ -27,7 +27,7 @@ class MyClass { ...@@ -27,7 +27,7 @@ class MyClass {
@UseCommand('echo', 'hi') @UseCommand('echo', 'hi')
@CommandUsage('foo') @CommandUsage('foo')
async onEcho(@PutOption('content', '-c <content:string>') content: string) { async onEcho(@PutOption('content', '-c <content>') content: string) {
return `bot: ${content}`; return `bot: ${content}`;
} }
} }
...@@ -60,6 +60,7 @@ describe('Register', () => { ...@@ -60,6 +60,7 @@ describe('Register', () => {
const command: Command = result.result; const command: Command = result.result;
expect(command._usage).toBe('foo'); expect(command._usage).toBe('foo');
expect(command._options.content.name).toBe('content'); expect(command._options.content.name).toBe('content');
expect(command._options.content.type).toBe('string');
expect(command.execute({ options: { content: 'hello' } })).resolves.toBe( expect(command.execute({ options: { content: 'hello' } })).resolves.toBe(
'bot: hello', 'bot: hello',
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment