FUNC - 轻量类型化 CLI 框架

参数注入

参数装饰器可以把运行时上下文注入到构造函数和处理器方法中。未装饰的参数不会由 func 填充。

Args

@Args() 注入 FuncArgs,也就是当前命令执行的归一化上下文。

import { Args, Command, FuncArgs, Handler } from 'func'

@Command({ name: 'config' })
export class ConfigCommand {
  @Handler({ path: ['get'] })
  get(@Args() args: FuncArgs) {
    console.log(args.path)   // ['get']
    console.log(args.inputs) // remaining input after the path
    console.log(args.option) // normalized options
    console.log(args.native) // native arg parser output
  }
}

inputs 包含剩余位置输入。path 包含选中的处理器路径。option 包含归一化后的选项值,包括字段选项和子选项。

import { Args, Command, FuncArgs, Handler, Value } from 'func'

@Command({ name: 'serve' })
export class ServeCommand {
  @Value()
  port: number = 3000

  @Handler()
  run(@Args() args: FuncArgs) {
    console.log(this.port)
    console.log(args.option.port)
    console.log(args.command?.name)
    console.log(args.handler?.methodName)
  }
}

Regs

@Regs() 注入 CommandRegistry。它适用于帮助输出、命令列表和自定义建议。

import { CommandMajor, CommandRegistry, Handler, Regs } from 'func'

@CommandMajor()
export class Major {
  @Handler({ flag: 'help', alias: 'h' })
  help(@Regs() regs: CommandRegistry) {
    regs.commands.forEach(command => {
      console.log(command.name, command.description)
    })
  }
}

Exception

@Exception() 会在局部 catch 方法和全局错误处理器中注入 FuncException。它暴露 codeleveltypemessagedetailspreventDefaultPrint()

import { Catch, CommandMajor, Exception, FuncException, Handler } from 'func'

@CommandMajor()
export class Major {
  @Catch()
  onError(@Exception() exception: FuncException) {
    console.error(exception.code)
    console.error(exception.message)
    exception.preventDefaultPrint()
  }

  @Handler()
  run() {
    throw new Error('boom')
  }
}

构造函数注入

任何参数装饰器也可以用于命令构造函数。当多个处理器需要相同运行时上下文时,可以这样做。

import { Args, Command, FuncArgs, Handler, Regs, CommandRegistry } from 'func'

@Command({ name: 'inspect' })
export class InspectCommand {
  constructor(
    @Args() private args: FuncArgs,
    @Regs() private regs: CommandRegistry,
  ) {}

  @Handler()
  run() {
    console.log(this.args.inputs)
    console.log(this.regs.commands.length)
  }
}