代码拉取完成,页面将自动刷新
//========================================
// This miniplug has a standalone version available in the plugin market.
// https://www.npmjs.com/package/koishi-plugin-microcommands
//========================================
import { Command, SessionError, h, union } from "koishi"
export const name = "microcommands"
export const inject = ["database"]
export function apply(ctx) {
ctx.model.extend("microcommand", {
name: "string",
code: "text",
}, {
primary: "name",
})
const cmd = ctx.command("microcommand")
const forks = Object.create(null)
function load(name, code) {
unload(name)
new Function(code)
forks[name] = ctx.plugin(ctx => {
let inject = []
let signature = ""
let properties = []
let options = []
let aliases = []
let usage = ""
let examples = []
let userFields = []
let channelFields = []
let checkers = []
let actions = []
const vars = {
name,
ctx,
require,
...require("koishi"),
inject(v) {
inject = v
},
signature(sig, ...rest) {
if (typeof sig !== "string") throw new TypeError("usage must be a string")
signature = sig
properties = rest
},
option(...args) {
options.push(args)
},
alias(...args) {
aliases.push(args)
},
usage(v) {
if (typeof v !== "string" && typeof v !== "function") throw new TypeError("usage must be a string or a function")
usage = v
},
example(v) {
if (typeof v !== "string") throw new TypeError("usage must be a string")
examples.push(v)
},
userFields(v) {
userFields = union(userFields, v)
},
channelFields(v) {
channelFields = union(channelFields, v)
},
before(v, append) {
if (typeof v !== "function") throw new TypeError("checker must be a function")
if (append) checkers.push(v)
else checkers.unshift(v)
},
action(v, prepend) {
if (typeof v !== "function") throw new TypeError("action must be a function")
if (prepend) actions.unshift(v)
else actions.push(v)
},
locale(id, value) {
ctx.i18n.define(id, "commands." + name.replace(/.*\//, ""), value)
},
}
const { ctx: _ctx, setCtx } = (0, eval)(/*js*/ `
(function ({ ${Object.keys(vars).join(", ")} }) {
____;
return {
ctx,
setCtx(v) {
ctx = v
},
}
})
`.replace(/\s+/g, " ").replace(/\B[ ]|[ ]\B/g, "").replace("____", code))(vars)
_ctx.plugin({
name: "microcommands:" + name,
inject,
apply(ctx) {
setCtx(ctx)
const fullName = name.includes(".") ? name : `microcommand/${name}`
const subCmd = ctx.command(`${fullName} ${signature}`, ...properties)
for (const o of options) subCmd.option(...o)
for (const a of aliases) subCmd.alias(...a)
if (usage) subCmd.usage(usage)
for (const e of examples) subCmd.example(e)
if (userFields.length) subCmd.userFields(userFields)
if (channelFields.length) subCmd.channelFields(channelFields)
for (const c of checkers) subCmd.before(c, true)
for (const a of actions) subCmd.action(a)
},
})
})
}
function unload(name) {
forks[name]?.dispose()
delete forks[name]
}
const logger = ctx.logger(name)
ctx.on("ready", async () => {
const d = await ctx.database.get("microcommand", {}, { sort: { name: "asc" } })
let successCount = 0
for (const { name, code } of d) {
try {
load(name, code)
successCount++
} catch (err) {
logger.error("load %o", name, err)
}
}
logger.info("successfully loaded %d of %d commands", successCount, d.length)
})
cmd.subcommand(".define <name:string> <code:rawtext>", { authority: 4, strictOptions: true })
.action(async ({ session }, name, code) => {
if (name == null || code == null) return session.i18n("internal.insufficient-arguments")
if (!name || name.match(/[\s\x00-\x1f"#%&'()/<>?\x7f-\x9f]|^\.|\.$/)) throw new SessionError(".invalid-name")
name = Command.normalize(name)
try {
load(name, code)
} catch (err) {
return h.text(String(err))
}
await ctx.database.upsert("microcommand", [{ name, code }])
return session.i18n(".saved", [name])
})
cmd.subcommand(".list")
.action(async ({ session }) => {
const l = Object.keys(forks)
if (!l.length) return session.i18n(".none")
return [...session.i18n(".header"), ...l.map(n => h("p", n.startsWith("-") ? `"${n}"` : n))]
})
cmd.subcommand(".show <name:string>", { strictOptions: true })
.action(async ({ session }, name) => {
if (name == null) return session.i18n("internal.insufficient-arguments")
name = Command.normalize(name)
const [o] = await ctx.database.get("microcommand", { name })
if (!o) throw new SessionError(".not-found", [name])
return h.text(o.code)
})
cmd.subcommand(".remove <name:string>", { authority: 4, strictOptions: true })
.action(async ({ session }, name) => {
name = Command.normalize(name)
unload(name)
await ctx.database.remove("microcommand", { name })
return session.i18n(".deleted", [name])
})
ctx.i18n.define("zh-CN", "commands.microcommand", {
description: "微指令…",
define: {
description: "定义微指令",
messages: {
"invalid-name": "指令名无效…",
saved: "已保存微指令 {0}。",
},
},
list: {
description: "显示当前注册的微指令列表",
messages: {
none: "当前未注册任何微指令。",
header: "当前注册的微指令有:",
},
},
show: {
description: "查询指定微指令的源代码",
messages: {
"not-found": "微指令 {0} 不存在…",
},
},
remove: {
description: "删除微指令",
messages: {
deleted: "已删除微指令 {0}。",
},
},
})
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。