Skip to content

Commit

Permalink
eval-addons: support field traps
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Aug 26, 2020
1 parent f4e41d9 commit 9193e94
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions packages/plugin-eval-addons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ declare module 'koishi-plugin-eval' {
interface MainConfig extends AddonConfig {}
}

const proxyFields: Record<string, FieldTrap<any, any>> = {}

export function defineFieldTrap<T, K extends User.Field = never>(key: string, trap: FieldTrap<T, K>) {
proxyFields[key] = trap
}

export interface FieldTrap<T = any, K extends User.Field = never> {
fields: Iterable<K>
get(data: Pick<User, K>): T
}

interface OptionManifest extends OptionConfig {
name: string
desc: string
Expand Down Expand Up @@ -93,23 +104,36 @@ export function apply(ctx: Context, config: Config) {
const { commands = [] } = manifest
commands.forEach((config) => {
const { name: rawName, desc, options = [], userFields = [] } = config
const { read = [] } = Array.isArray(userFields) ? { read: userFields } : userFields

const [name] = rawName.split(' ', 1)
if (!response.commands.includes(name)) {
return logger.warn('unregistered command manifest: %c', name)
}
const { read = [] } = Array.isArray(userFields) ? { read: userFields } : userFields

const cmd = addon
.subcommand(rawName, desc, config)
.userFields(read)
.action(async ({ session, command: { name }, options }, ...args) => {
.action(async ({ session, command, options }, ...args) => {
const { $app, $user, $uuid } = session
const result = await $app.evalRemote.addon($uuid, $user, { name, args, options })
const { name } = command
const user: Partial<User> = {}
for (const key of read) {
const trap = proxyFields[key]
Reflect.set(user, key, trap ? trap.get($user) : $user[key])
}
const result = await $app.evalRemote.addon($uuid, user, { name, args, options })
return result
})

options.forEach((config) => {
const { name, desc } = config
cmd.option(name, desc, config)
})

for (const key of read) {
const trap = proxyFields[key]
cmd.userFields(trap ? trap.fields : [key])
}
})
})
})
Expand Down

0 comments on commit 9193e94

Please sign in to comment.