koishi-plugin-common
Advanced tools
Comparing version 3.0.0-beta.15 to 3.0.0-beta.16
@@ -1,15 +0,12 @@ | ||
import { Observed } from 'koishi-utils'; | ||
import { Context, Session, User, Group } from 'koishi-core'; | ||
declare type ActionCallback<T extends {}, K extends keyof T> = (this: Context, session: Session<'authority'>, target: Observed<Pick<T, K>>, ...args: string[]) => Promise<void | string>; | ||
export interface ActionItem<T extends {}> { | ||
callback: ActionCallback<T, keyof T>; | ||
fields: (keyof T)[]; | ||
import { Context, User, Group, ParsedArgv } from 'koishi-core'; | ||
declare type AdminAction<U extends User.Field, G extends Group.Field, O extends {}, T> = (argv: ParsedArgv<U | 'authority', G, O> & { | ||
target: T; | ||
}, ...args: string[]) => void | string | Promise<void | string>; | ||
declare module 'koishi-core/dist/command' { | ||
interface Command<U, G, O> { | ||
adminUser(callback: AdminAction<U, G, O, User.Observed<U | 'authority'>>): this; | ||
adminGruop(callback: AdminAction<U, G, O, Group.Observed<G>>): this; | ||
} | ||
} | ||
export declare class Action<T extends {}> { | ||
commands: Record<string, ActionItem<T>>; | ||
add<K extends keyof T = never>(name: string, callback: ActionCallback<T, K>, fields?: K[]): void; | ||
} | ||
export declare const UserAction: Action<User>; | ||
export declare const GroupAction: Action<Group>; | ||
export declare function apply(ctx: Context): void; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.apply = exports.GroupAction = exports.UserAction = exports.Action = void 0; | ||
exports.apply = void 0; | ||
const koishi_utils_1 = require("koishi-utils"); | ||
const koishi_core_1 = require("koishi-core"); | ||
class Action { | ||
constructor() { | ||
this.commands = {}; | ||
} | ||
add(name, callback, fields) { | ||
this.commands[koishi_utils_1.paramCase(name)] = { callback, fields }; | ||
} | ||
} | ||
exports.Action = Action; | ||
exports.UserAction = new Action(); | ||
exports.GroupAction = new Action(); | ||
exports.UserAction.add('setAuth', async (session, user, value) => { | ||
const authority = Number(value); | ||
if (!koishi_utils_1.isInteger(authority) || authority < 0) | ||
return '参数错误。'; | ||
if (authority >= session.$user.authority) | ||
return '权限不足。'; | ||
if (authority === user.authority) { | ||
return '用户权限未改动。'; | ||
} | ||
else { | ||
user.authority = authority; | ||
await user._update(); | ||
return '用户权限已修改。'; | ||
} | ||
}, ['authority']); | ||
exports.UserAction.add('setFlag', async (session, user, ...flags) => { | ||
const userFlags = koishi_utils_1.enumKeys(koishi_core_1.User.Flag); | ||
if (!flags.length) | ||
return `可用的标记有 ${userFlags.join(', ')}。`; | ||
const notFound = koishi_utils_1.difference(flags, userFlags); | ||
if (notFound.length) | ||
return `未找到标记 ${notFound.join(', ')}。`; | ||
for (const name of flags) { | ||
user.flag |= koishi_core_1.User.Flag[name]; | ||
} | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['flag']); | ||
exports.UserAction.add('unsetFlag', async (session, user, ...flags) => { | ||
const userFlags = koishi_utils_1.enumKeys(koishi_core_1.User.Flag); | ||
if (!flags.length) | ||
return `可用的标记有 ${userFlags.join(', ')}。`; | ||
const notFound = koishi_utils_1.difference(flags, userFlags); | ||
if (notFound.length) | ||
return `未找到标记 ${notFound.join(', ')}。`; | ||
for (const name of flags) { | ||
user.flag &= ~koishi_core_1.User.Flag[name]; | ||
} | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['flag']); | ||
exports.UserAction.add('setUsage', async (session, user, name, _count) => { | ||
const count = +_count; | ||
if (!koishi_utils_1.isInteger(count) || count < 0) | ||
return '参数错误。'; | ||
user.usage[name] = count; | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['usage']); | ||
exports.UserAction.add('clearUsage', async (session, user, ...commands) => { | ||
if (commands.length) { | ||
for (const command of commands) { | ||
delete user.usage[command]; | ||
function flagAction(map, { target, options }, ...flags) { | ||
if (options.set || options.unset) { | ||
const notFound = koishi_utils_1.difference(flags, koishi_utils_1.enumKeys(map)); | ||
if (notFound.length) | ||
return `未找到标记 ${notFound.join(', ')}。`; | ||
for (const name of flags) { | ||
options.set ? target.flag |= map[name] : target.flag &= ~map[name]; | ||
} | ||
return; | ||
} | ||
else { | ||
user.usage = {}; | ||
if (options.list) { | ||
return `全部标记为:${koishi_utils_1.enumKeys(map).join(', ')}。`; | ||
} | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['usage']); | ||
exports.UserAction.add('setTimer', async (session, user, name, offset) => { | ||
if (!name || !offset) | ||
return '参数不足。'; | ||
const timestamp = koishi_utils_1.Time.parseTime(offset); | ||
if (!timestamp) | ||
return '请输入合法的时间。'; | ||
user.timers[name] = Date.now() + timestamp; | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['timers']); | ||
exports.UserAction.add('clearTimer', async (session, user, ...commands) => { | ||
if (commands.length) { | ||
for (const command of commands) { | ||
delete user.timers[command]; | ||
} | ||
let flag = target.flag; | ||
const keys = []; | ||
while (flag) { | ||
const value = 2 ** Math.floor(Math.log2(flag)); | ||
flag -= value; | ||
keys.unshift(map[value]); | ||
} | ||
else { | ||
user.timers = {}; | ||
} | ||
await user._update(); | ||
return '用户信息已修改。'; | ||
}, ['timers']); | ||
exports.GroupAction.add('setFlag', async (session, group, ...flags) => { | ||
const groupFlags = koishi_utils_1.enumKeys(koishi_core_1.Group.Flag); | ||
if (!flags.length) | ||
return `可用的标记有 ${groupFlags.join(', ')}。`; | ||
const notFound = koishi_utils_1.difference(flags, groupFlags); | ||
if (notFound.length) | ||
return `未找到标记 ${notFound.join(', ')}。`; | ||
for (const name of flags) { | ||
group.flag |= koishi_core_1.Group.Flag[name]; | ||
} | ||
await group._update(); | ||
return '群信息已修改。'; | ||
}, ['flag']); | ||
exports.GroupAction.add('unsetFlag', async (session, group, ...flags) => { | ||
const groupFlags = koishi_utils_1.enumKeys(koishi_core_1.Group.Flag); | ||
if (!flags.length) | ||
return `可用的标记有 ${groupFlags.join(', ')}。`; | ||
const notFound = koishi_utils_1.difference(flags, groupFlags); | ||
if (notFound.length) | ||
return `未找到标记 ${notFound.join(', ')}。`; | ||
for (const name of flags) { | ||
group.flag &= ~koishi_core_1.Group.Flag[name]; | ||
} | ||
await group._update(); | ||
return '群信息已修改。'; | ||
}, ['flag']); | ||
exports.GroupAction.add('setAssignee', async (session, group, _assignee) => { | ||
const assignee = _assignee ? +_assignee : session.selfId; | ||
if (!koishi_utils_1.isInteger(assignee) || assignee < 0) | ||
return '参数错误。'; | ||
group.assignee = assignee; | ||
await group._update(); | ||
return '群信息已修改。'; | ||
}, ['assignee']); | ||
function apply(ctx) { | ||
ctx.command('admin <action> [...args]', '管理用户', { authority: 4 }) | ||
if (!keys.length) | ||
return '未设置任何标记。'; | ||
return `当前的标记为:${keys.join(', ')}。`; | ||
} | ||
koishi_core_1.Command.prototype.adminUser = function (callback) { | ||
const command = this | ||
.userFields(['authority']) | ||
.before(session => !session.$app.database) | ||
.option('user', '-u [user] 指定目标用户') | ||
.option('group', '-g [group] 指定目标群') | ||
.option('thisGroup', '-G, --this-group 指定目标群为本群') | ||
.action(async ({ session, options }, name, ...args) => { | ||
const isGroup = 'group' in options || 'thisGroup' in options; | ||
if ('user' in options && isGroup) | ||
return '不能同时目标为指定用户和群。'; | ||
const actionMap = isGroup ? exports.GroupAction.commands : exports.UserAction.commands; | ||
const actionList = Object.keys(actionMap).map(koishi_utils_1.paramCase).join(', '); | ||
if (!name) | ||
return `当前的可用指令有:${actionList}。`; | ||
const action = actionMap[koishi_utils_1.paramCase(name)]; | ||
if (!action) | ||
return `指令未找到。当前的可用指令有:${actionList}。`; | ||
if (isGroup) { | ||
const fields = action.fields ? action.fields.slice() : koishi_core_1.Group.fields; | ||
let group; | ||
if (options.thisGroup) { | ||
group = await session.$observeGroup(fields); | ||
.option('user', '-u [user] 指定目标用户', { authority: 3 }); | ||
command._action = async (argv) => { | ||
const { options, session, args } = argv; | ||
const fields = koishi_core_1.Command.collect(argv, 'user'); | ||
let target; | ||
if (options.user) { | ||
const qq = koishi_core_1.getTargetId(options.user); | ||
if (!qq) | ||
return '请指定正确的目标。'; | ||
const { database } = session.$app; | ||
const data = await database.getUser(qq, -1, [...fields]); | ||
if (!data) | ||
return '未找到指定的用户。'; | ||
if (qq === session.userId) { | ||
target = await session.$observeUser(fields); | ||
} | ||
else if (koishi_utils_1.isInteger(options.group) && options.group > 0) { | ||
const data = await ctx.database.getGroup(options.group, fields); | ||
if (!data) | ||
return '未找到指定的群。'; | ||
group = koishi_utils_1.observe(data, diff => ctx.database.setGroup(options.group, diff), `group ${options.group}`); | ||
else if (session.$user.authority <= data.authority) { | ||
return '权限不足。'; | ||
} | ||
return action.callback.call(ctx, session, group, ...args); | ||
} | ||
else { | ||
const fields = action.fields ? action.fields.slice() : koishi_core_1.User.fields; | ||
if (!fields.includes('authority')) | ||
fields.push('authority'); | ||
let user; | ||
if (options.user) { | ||
const qq = koishi_core_1.getTargetId(options.user); | ||
if (!qq) | ||
return '未指定目标。'; | ||
const data = await ctx.database.getUser(qq, -1, fields); | ||
if (!data) | ||
return '未找到指定的用户。'; | ||
if (qq === session.userId) { | ||
user = await session.$observeUser(fields); | ||
} | ||
else if (session.$user.authority <= data.authority) { | ||
return '权限不足。'; | ||
} | ||
else { | ||
user = koishi_utils_1.observe(data, diff => ctx.database.setUser(qq, diff), `user ${qq}`); | ||
} | ||
} | ||
else { | ||
user = await session.$observeUser(fields); | ||
target = koishi_utils_1.observe(data, diff => database.setUser(qq, diff), `user ${qq}`); | ||
} | ||
return action.callback.call(ctx, session, user, ...args); | ||
} | ||
else { | ||
target = await session.$observeUser(fields); | ||
} | ||
const diffKeys = Object.keys(target._diff); | ||
const result = await callback({ ...argv, target }, ...args); | ||
if (typeof result === 'string') | ||
return result; | ||
if (!koishi_utils_1.difference(Object.keys(target._diff), diffKeys).length) | ||
return '用户数据未改动。'; | ||
await target._update(); | ||
return '用户数据已修改。'; | ||
}; | ||
return command; | ||
}; | ||
koishi_core_1.Command.prototype.adminGruop = function (callback) { | ||
const command = this | ||
.userFields(['authority']) | ||
.option('group', '-g [group] 指定目标群', { authority: 3 }); | ||
command._action = async (argv) => { | ||
const { options, session, args } = argv; | ||
const fields = koishi_core_1.Command.collect(argv, 'group'); | ||
let target; | ||
if (options.group) { | ||
const { database } = session.$app; | ||
if (!koishi_utils_1.isInteger(options.group) || options.group <= 0) | ||
return '请指定正确的目标。'; | ||
const data = await database.getGroup(options.group, -1, [...fields]); | ||
if (!data) | ||
return '未找到指定的群。'; | ||
target = koishi_utils_1.observe(data, diff => database.setGroup(options.group, diff), `group ${options.group}`); | ||
} | ||
else if (session.messageType === 'group') { | ||
target = await session.$observeGroup(fields); | ||
} | ||
else { | ||
return '当前不在群上下文中,请使用 -g 参数指定目标群。'; | ||
} | ||
const result = await callback({ ...argv, target }, ...args); | ||
if (typeof result === 'string') | ||
return result; | ||
if (!Object.keys(target._diff).length) | ||
return '群数据未改动。'; | ||
await target._update(); | ||
return '群数据已修改。'; | ||
}; | ||
return command; | ||
}; | ||
function apply(ctx) { | ||
ctx.command('user', '用户管理', { authority: 3 }); | ||
ctx.command('group', '群管理', { authority: 3 }); | ||
ctx.command('user.auth <value>', '权限信息', { authority: 4 }) | ||
.adminUser(({ session, target }, value) => { | ||
const authority = Number(value); | ||
if (!koishi_utils_1.isInteger(authority) || authority < 0) | ||
return '参数错误。'; | ||
if (authority >= session.$user.authority) | ||
return '权限不足。'; | ||
target.authority = authority; | ||
}); | ||
ctx.command('user.flag [-s|-S] [...flags]', '标记信息', { authority: 3 }) | ||
.userFields(['flag']) | ||
.option('list', '-l 标记列表') | ||
.option('set', '-s 添加标记', { authority: 4 }) | ||
.option('unset', '-S 删除标记', { authority: 4 }) | ||
.adminUser(flagAction.bind(null, koishi_core_1.User.Flag)); | ||
ctx.command('usage [key]', '调用次数信息') | ||
.alias('usages') | ||
.userFields(['usage']) | ||
.option('set', '-s 设置调用次数', { authority: 4 }) | ||
.option('clear', '-c 清空调用次数', { authority: 4 }) | ||
.adminUser(({ target, options }, name, value) => { | ||
if (options.clear) { | ||
name ? delete target.usage[name] : target.usage = {}; | ||
return; | ||
} | ||
if (options.set) { | ||
if (value === undefined) | ||
return '参数不足。'; | ||
const count = +value; | ||
if (!koishi_utils_1.isInteger(count) || count < 0) | ||
return '参数错误。'; | ||
target.usage[name] = count; | ||
return; | ||
} | ||
if (name) | ||
return `今日 ${name} 功能的调用次数为:${target.usage[name] || 0}`; | ||
const output = []; | ||
for (const name of Object.keys(target.usage).sort()) { | ||
if (name.startsWith('$')) | ||
continue; | ||
output.push(`${name}:${target.usage[name]}`); | ||
} | ||
if (!output.length) | ||
return '今日没有调用过消耗次数的功能。'; | ||
output.unshift('今日各功能的调用次数为:'); | ||
return output.join('\n'); | ||
}); | ||
ctx.command('timer [key]', '定时器信息') | ||
.alias('timers') | ||
.userFields(['timers']) | ||
.option('set', '-s 设置定时器', { authority: 4 }) | ||
.option('clear', '-c 清空定时器', { authority: 4 }) | ||
.adminUser(({ target, options }, name, value) => { | ||
if (options.clear) { | ||
name ? delete target.timers[name] : target.timers = {}; | ||
return; | ||
} | ||
if (options.set) { | ||
if (value === undefined) | ||
return '参数不足。'; | ||
const timestamp = +koishi_utils_1.Time.parseDate(value); | ||
if (!timestamp) | ||
return '请输入合法的时间。'; | ||
target.timers[name] = timestamp; | ||
return; | ||
} | ||
const now = Date.now(); | ||
if (name) { | ||
const delta = target.timers[name] - now; | ||
if (delta > 0) | ||
return `定时器 ${name} 的生效时间为:剩余 ${koishi_utils_1.Time.formatTime(delta)}`; | ||
return `定时器 ${name} 当前并未生效。`; | ||
} | ||
const output = []; | ||
for (const name of Object.keys(target.timers).sort()) { | ||
if (name.startsWith('$')) | ||
continue; | ||
output.push(`${name}:剩余 ${koishi_utils_1.Time.formatTime(target.timers[name] - now)}`); | ||
} | ||
if (!output.length) | ||
return '当前没有生效的定时器。'; | ||
output.unshift('各定时器的生效时间为:'); | ||
return output.join('\n'); | ||
}); | ||
ctx.command('group.assign [bot]', '受理者账号', { authority: 4 }) | ||
.groupFields(['assignee']) | ||
.adminGruop(({ session, target }, value) => { | ||
const assignee = value ? +value : session.selfId; | ||
if (!koishi_utils_1.isInteger(assignee) || assignee < 0) | ||
return '参数错误。'; | ||
target.assignee = assignee; | ||
}); | ||
ctx.command('group.flag [-s|-S] [...flags]', '标记信息', { authority: 3 }) | ||
.groupFields(['flag']) | ||
.option('list', '-l 标记列表') | ||
.option('set', '-s 添加标记', { authority: 4 }) | ||
.option('unset', '-S 删除标记', { authority: 4 }) | ||
.adminGruop(flagAction.bind(null, koishi_core_1.Group.Flag)); | ||
} | ||
exports.apply = apply; | ||
//# sourceMappingURL=admin.js.map |
@@ -5,7 +5,7 @@ import { Context } from 'koishi-core'; | ||
import { HandlerOptions } from './handler'; | ||
import { SenderConfig } from './sender'; | ||
export * from './admin'; | ||
export * from './broadcast'; | ||
export * from './info'; | ||
export * from './repeater'; | ||
export interface Options extends HandlerOptions, RepeaterOptions { | ||
export interface Config extends HandlerOptions, RepeaterOptions, SenderConfig { | ||
admin?: false; | ||
@@ -16,6 +16,5 @@ broadcast?: false; | ||
info?: false; | ||
usage?: false; | ||
debug?: DebugOptions; | ||
} | ||
export declare const name = "common"; | ||
export declare function apply(ctx: Context, options?: Options): void; | ||
export declare function apply(ctx: Context, config?: Config): void; |
@@ -19,26 +19,21 @@ "use strict"; | ||
const handler_1 = __importDefault(require("./handler")); | ||
const sender_1 = __importDefault(require("./sender")); | ||
__exportStar(require("./admin"), exports); | ||
__exportStar(require("./broadcast"), exports); | ||
__exportStar(require("./info"), exports); | ||
__exportStar(require("./repeater"), exports); | ||
exports.name = 'common'; | ||
function apply(ctx, options = {}) { | ||
ctx.plugin(handler_1.default, options); | ||
ctx.plugin(repeater_1.default, options); | ||
if (options.echo !== false) | ||
ctx.plugin(require('./echo')); | ||
if (options.admin !== false) | ||
function apply(ctx, config = {}) { | ||
ctx.plugin(handler_1.default, config); | ||
ctx.plugin(repeater_1.default, config); | ||
ctx.plugin(sender_1.default, config); | ||
if (config.admin !== false) | ||
ctx.plugin(require('./admin')); | ||
if (options.contextify !== false) | ||
if (config.contextify !== false) | ||
ctx.plugin(require('./contextify')); | ||
if (options.broadcast !== false) | ||
ctx.plugin(require('./broadcast')); | ||
if (options.debug) | ||
ctx.plugin(require('./debug'), options.debug); | ||
if (options.info !== false) | ||
if (config.debug) | ||
ctx.plugin(require('./debug'), config.debug); | ||
if (config.info !== false) | ||
ctx.plugin(require('./info')); | ||
if (options.usage !== false) | ||
ctx.plugin(require('./usage')); | ||
} | ||
exports.apply = apply; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "koishi-plugin-common", | ||
"description": "Common plugins for Koishi", | ||
"version": "3.0.0-beta.15", | ||
"version": "3.0.0-beta.16", | ||
"main": "dist/index.js", | ||
@@ -34,10 +34,10 @@ "typings": "dist/index.d.ts", | ||
"peerDependencies": { | ||
"koishi-core": "^2.0.0" | ||
"koishi-core": "^2.2.0" | ||
}, | ||
"devDependencies": { | ||
"koishi-test-utils": "^4.0.0-beta.9" | ||
"koishi-test-utils": "^5.0.0" | ||
}, | ||
"dependencies": { | ||
"koishi-utils": "^3.1.0" | ||
"koishi-utils": "^3.1.4" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
57175
29
738
Updatedkoishi-utils@^3.1.4