New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@kotori-bot/core

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@kotori-bot/core - npm Package Compare versions

Comparing version 1.5.0 to 1.5.1

47

lib/components/config.js
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -41,4 +41,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/config.ts
var config_exports = {};

@@ -51,35 +49,6 @@ __export(config_exports, {

var import_tsukiko = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_node_path = require("node:path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko.default.Object({
var import_global = require("../global");
const packageInfoSchema = import_tsukiko.default.Object({
name: import_tsukiko.default.String(),

@@ -92,6 +61,6 @@ version: import_tsukiko.default.String(),

});
var Config = class {
class Config {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
constructor(config = import_global.DEFAULT_CORE_CONFIG) {
this.config = config;

@@ -112,3 +81,3 @@ const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));

}
};
}
var config_default = Config;

@@ -115,0 +84,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -32,3 +32,2 @@

};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(

@@ -43,4 +42,2 @@ // If the importer is in node compatibility mode or this is not an ESM

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/core.ts
var core_exports = {};

@@ -52,792 +49,25 @@ __export(core_exports, {

module.exports = __toCommonJS(core_exports);
var import_tools8 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko.default.Object({
name: import_tsukiko.default.String(),
version: import_tsukiko.default.String(),
description: import_tsukiko.default.String(),
main: import_tsukiko.default.String(),
license: import_tsukiko.default.Literal("GPL-3.0"),
author: import_tsukiko.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools7 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/factory.ts
var import_tools6 = require("@kotori-bot/tools");
// src/types/message.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko2.default.Union([
import_tsukiko2.default.Union([import_tsukiko2.default.Literal("string"), import_tsukiko2.default.Literal("number")]),
import_tsukiko2.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko2.default.Union([import_tsukiko2.default.Number(), import_tsukiko2.default.String()]);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/service/elements.ts
var import_tools2 = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools2.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools3 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools3.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools3.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools3.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools3.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools3.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools3.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools3.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools3.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools3.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools3.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools3.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_i18n = __toESM(require("@kotori-bot/i18n"));
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/utils/command.ts
var import_tools4 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools4.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/utils/container.ts
var import_tools5 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools5.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools6.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools7.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
var import_config = __toESM(require("./config"));
var import_message = __toESM(require("./message"));
var import_service = require("../service");
var import_global = require("../global");
class Core extends import_fluoro.Context {
[import_global.Symbols.adapter] = /* @__PURE__ */ new Map();
[import_global.Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.provide("config", new import_config.default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.provide("message", new import_message.default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools8.Http({ validateStatus: () => true }));
this.provide("http", new import_tools.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.provide("i18n", new import_i18n.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
this.service("cache", new import_service.Cache(this.extends()));
}
};
}
var core_default = Core;

@@ -844,0 +74,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,16 +9,10 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {

@@ -33,829 +27,11 @@ if (from && typeof from === "object" || typeof from === "function") {

var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/index.ts
var components_exports = {};
__export(components_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols
});
module.exports = __toCommonJS(components_exports);
// src/components/core.ts
var import_tools8 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko.default.Object({
name: import_tsukiko.default.String(),
version: import_tsukiko.default.String(),
description: import_tsukiko.default.String(),
main: import_tsukiko.default.String(),
license: import_tsukiko.default.Literal("GPL-3.0"),
author: import_tsukiko.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools7 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/factory.ts
var import_tools6 = require("@kotori-bot/tools");
// src/types/message.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko2.default.Union([
import_tsukiko2.default.Union([import_tsukiko2.default.Literal("string"), import_tsukiko2.default.Literal("number")]),
import_tsukiko2.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko2.default.Union([import_tsukiko2.default.Number(), import_tsukiko2.default.String()]);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/service/elements.ts
var import_tools2 = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools2.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools3 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools3.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools3.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools3.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools3.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools3.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools3.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools3.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools3.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools3.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools3.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools3.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/utils/command.ts
var import_tools4 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools4.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/utils/container.ts
var import_tools5 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools5.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools6.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools7.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools8.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
__reExport(components_exports, require("./core"), module.exports);
__reExport(components_exports, require("../global"), module.exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ADAPTER_PREFIX,
CUSTOM_PREFIX,
Core,
DATABASE_PREFIX,
DEFAULT_CORE_CONFIG,
DEFAULT_PORT,
OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX,
Symbols
...require("./core"),
...require("../global")
});
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -32,3 +32,2 @@

};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(

@@ -43,4 +42,2 @@ // If the importer is in node compatibility mode or this is not an ESM

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/message.ts
var message_exports = {};

@@ -52,656 +49,12 @@ __export(message_exports, {

module.exports = __toCommonJS(message_exports);
var import_tools8 = require("@kotori-bot/tools");
var import_tools = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/factory.ts
var import_tools7 = require("@kotori-bot/tools");
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/components/core.ts
var import_tools4 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko2.default.Object({
name: import_tsukiko2.default.String(),
version: import_tsukiko2.default.String(),
description: import_tsukiko2.default.String(),
main: import_tsukiko2.default.String(),
license: import_tsukiko2.default.Literal("GPL-3.0"),
author: import_tsukiko2.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/service/elements.ts
var import_tools2 = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools2.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools3 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools3.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools3.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools3.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools3.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools3.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools3.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools3.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools3.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools3.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools3.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools3.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools4.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
// src/utils/command.ts
var import_tools5 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools5.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/utils/container.ts
var import_tools6 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools6.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools7.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
var import_factory = require("../utils/factory");
var import_command = require("../utils/command");
var import_commandError = __toESM(require("../utils/commandError"));
var import_global = require("../global");
class Message {
[import_global.Symbols.midware] = /* @__PURE__ */ new Set();
[import_global.Symbols.command] = /* @__PURE__ */ new Set();
[import_global.Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {

@@ -712,3 +65,3 @@ const { api } = session;

api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
this[import_global.Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);

@@ -729,3 +82,3 @@ let lastMidwareNum = -1;

if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
this[import_global.Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);

@@ -743,19 +96,19 @@ if (!result) return;

session,
raw: (0, import_tools8.stringRightSplit)(session.message, prefix)
raw: (0, import_tools.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
const cancel = (0, import_factory.cancelFactory)();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
this[import_global.Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
const result = import_command.Command.run(params.raw, cmd.meta);
if (result instanceof import_commandError.default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
if (cancel.value || result instanceof import_commandError.default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
if (executed instanceof import_commandError.default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });

@@ -767,9 +120,9 @@ return;

command: cmd,
result: executed instanceof commandError_default ? result : executed,
result: executed instanceof import_commandError.default ? result : executed,
...params
});
} catch (error2) {
} catch (error) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
result: new import_commandError.default({ type: "error", error }),
...params

@@ -781,4 +134,4 @@ });

this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
command: new import_command.Command(""),
result: new import_commandError.default({ type: "unknown", input: params.raw }),
...params,

@@ -801,12 +154,12 @@ cancel: cancel.get()

const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
this[import_global.Symbols.midware].add(data);
const dispose = () => this[import_global.Symbols.midware].delete(data);
(0, import_factory.disposeFactory)(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
const command = new import_command.Command(template, config);
this[import_global.Symbols.command].add(command);
const dispose = () => this[import_global.Symbols.command].delete(command);
(0, import_factory.disposeFactory)(this.ctx, dispose);
return command;

@@ -816,5 +169,5 @@ }

const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
this[import_global.Symbols.regexp].add(data);
const dispose = () => this[import_global.Symbols.regexp].delete(data);
(0, import_factory.disposeFactory)(this.ctx, dispose);
return dispose;

@@ -834,7 +187,7 @@ }

const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
this.ctx[import_global.Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
(0, import_factory.quickFactory)(
(0, import_factory.sendMessageFactory)(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)

@@ -849,3 +202,3 @@ )(message);

}
};
}
var message_default = Message;

@@ -852,0 +205,0 @@ // Annotate the CommonJS export names for ESM import in node:

20

lib/global/constants.js
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/global/constants.ts
var constants_exports = {};

@@ -46,9 +44,9 @@ __export(constants_exports, {

var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
const OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
const PLUGIN_PREFIX = "kotori-plugin-";
const DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
const ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
const CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
const DEFAULT_PORT = 720;
const DEFAULT_CORE_CONFIG = {
global: {

@@ -55,0 +53,0 @@ lang: import_i18n.DEFAULT_LANG,

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -18,6 +18,2 @@

var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {

@@ -31,56 +27,12 @@ if (from && typeof from === "object" || typeof from === "function") {

};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/global/index.ts
var global_exports = {};
__export(global_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols
});
module.exports = __toCommonJS(global_exports);
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
__reExport(global_exports, require("./constants"), module.exports);
__reExport(global_exports, require("./symbols"), module.exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ADAPTER_PREFIX,
CUSTOM_PREFIX,
DATABASE_PREFIX,
DEFAULT_CORE_CONFIG,
DEFAULT_PORT,
OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX,
Symbols
...require("./constants"),
...require("./symbols")
});
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/global/symbols.ts
var symbols_exports = {};

@@ -40,3 +38,3 @@ __export(symbols_exports, {

module.exports = __toCommonJS(symbols_exports);
var Symbols = class {
class Symbols {
static adapter = Symbol.for("kotori.core.adapter");

@@ -49,3 +47,3 @@ static bot = Symbol.for("kotori.core.bot");

static job = Symbol.for("kotori.loader.job");
};
}
var symbols_default = Symbols;

@@ -52,0 +50,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,16 +9,10 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {

@@ -33,803 +27,15 @@ if (from && typeof from === "object" || typeof from === "function") {

var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
module.exports = __toCommonJS(src_exports);
__reExport(src_exports, require("fluoro"), module.exports);
// src/components/core.ts
var import_tools7 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko.default.Object({
name: import_tsukiko.default.String(),
version: import_tsukiko.default.String(),
description: import_tsukiko.default.String(),
main: import_tsukiko.default.String(),
license: import_tsukiko.default.Literal("GPL-3.0"),
author: import_tsukiko.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools4 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/factory.ts
var import_tools2 = require("@kotori-bot/tools");
// src/types/message.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko2.default.Union([
import_tsukiko2.default.Union([import_tsukiko2.default.Literal("string"), import_tsukiko2.default.Literal("number")]),
import_tsukiko2.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko2.default.Union([import_tsukiko2.default.Number(), import_tsukiko2.default.String()]);
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools2.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/utils/command.ts
var import_tools3 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/utils/command.ts
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools3.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools4.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/service/elements.ts
var import_tools5 = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools5.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools6 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools6.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools6.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools6.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools6.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools6.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools6.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools6.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools6.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools6.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools6.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools6.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools7.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
// src/utils/container.ts
var import_tools8 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools8.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("./components"), module.exports);
__reExport(src_exports, require("./service"), module.exports);
__reExport(src_exports, require("./utils/command"), module.exports);
__reExport(src_exports, require("./utils/error"), module.exports);
__reExport(src_exports, require("./utils/commandError"), module.exports);
__reExport(src_exports, require("./utils/container"), module.exports);
__reExport(src_exports, require("./utils/factory"), module.exports);
__reExport(src_exports, require("./global"), module.exports);
__reExport(src_exports, require("./types"), module.exports);
__reExport(src_exports, require("@kotori-bot/tools"), module.exports);

@@ -840,33 +46,12 @@ __reExport(src_exports, require("@kotori-bot/i18n"), module.exports);

0 && (module.exports = {
ADAPTER_PREFIX,
Adapter,
Api,
CUSTOM_PREFIX,
Cache,
Command,
CommandAccess,
CommandError,
Container,
Core,
DATABASE_PREFIX,
DEFAULT_CORE_CONFIG,
DEFAULT_PORT,
DevError,
Elements,
KotoriError,
MessageScope,
ModuleError,
OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX,
Symbols,
cancelFactory,
commandArgTypeSignSchema,
confirmFactory,
disposeFactory,
eventDataTargetIdSchema,
formatFactory,
promptFactory,
quickFactory,
sendMessageFactory,
...require("fluoro"),
...require("./components"),
...require("./service"),
...require("./utils/command"),
...require("./utils/error"),
...require("./utils/commandError"),
...require("./utils/container"),
...require("./utils/factory"),
...require("./global"),
...require("./types"),
...require("@kotori-bot/tools"),

@@ -873,0 +58,0 @@ ...require("@kotori-bot/i18n"),

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -32,3 +32,2 @@

};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(

@@ -43,4 +42,2 @@ // If the importer is in node compatibility mode or this is not an ESM

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/service/adapter.ts
var adapter_exports = {};

@@ -52,720 +49,7 @@ __export(adapter_exports, {

module.exports = __toCommonJS(adapter_exports);
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// src/service/elements.ts
var import_tools = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/utils/factory.ts
var import_tools8 = require("@kotori-bot/tools");
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/components/core.ts
var import_tools6 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools2 = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko2.default.Object({
name: import_tsukiko2.default.String(),
version: import_tsukiko2.default.String(),
description: import_tsukiko2.default.String(),
main: import_tsukiko2.default.String(),
license: import_tsukiko2.default.Literal("GPL-3.0"),
author: import_tsukiko2.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools2.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools4 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/command.ts
var import_tools3 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/utils/command.ts
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools3.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools4.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/service/api.ts
var import_tools5 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools5.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools5.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools5.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools5.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools5.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools5.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools5.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools5.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools5.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools5.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools5.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools6.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
// src/utils/container.ts
var import_tools7 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools7.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools8.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/service/adapter.ts
var import_types = require("../types");
var import_elements = __toESM(require("./elements"));
var import_factory = require("../utils/factory");
var import_commandError = __toESM(require("../utils/commandError"));
var import_global = require("../global");
function setProxy(api, ctx) {

@@ -776,4 +60,4 @@ const proxy = Object.create(api);

const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
const cancel = (0, import_factory.cancelFactory)();
ctx.emit("before_send", { api, message, messageType: import_types.MessageScope.PRIVATE, targetId, cancel: cancel.get() });
if (cancel.value) return;

@@ -786,4 +70,4 @@ api.sendPrivateMsg(message, targetId, argArray[2]);

const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
const cancel = (0, import_factory.cancelFactory)();
ctx.emit("before_send", { api, message, messageType: import_types.MessageScope.PRIVATE, targetId, cancel: cancel.get() });
if (cancel.value) return;

@@ -796,6 +80,6 @@ api.sendGroupMsg(message, targetId, argArray[2]);

function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
return new import_commandError.default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
class Adapter {
constructor(ctx, config, identity, Api, el = new import_elements.default()) {
this.ctx = ctx;

@@ -805,6 +89,6 @@ this.config = config;

this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.api = setProxy(new Api(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
if (!this.ctx[import_global.Symbols.bot].get(this.platform)) this.ctx[import_global.Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[import_global.Symbols.bot].get(this.platform).add(this.api);
}

@@ -824,7 +108,7 @@ online() {

const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const send = (0, import_factory.sendMessageFactory)(this, type, data);
const format = (0, import_factory.formatFactory)(i18n);
const quick = (0, import_factory.quickFactory)(send, i18n);
const prompt = (0, import_factory.promptFactory)(quick, this, data);
const confirm = (0, import_factory.confirmFactory)(quick, this, data);
const { api, elements: el } = this;

@@ -851,3 +135,3 @@ this.ctx.emit(

selfId = -1;
};
}
var adapter_default = Adapter;

@@ -854,0 +138,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/service/api.ts
var api_exports = {};

@@ -41,3 +39,3 @@ __export(api_exports, {

var import_tools = require("@kotori-bot/tools");
var Api = class {
class Api {
adapter;

@@ -80,3 +78,3 @@ constructor(adapter) {

}
};
}
var api_default = Api;

@@ -83,0 +81,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/service/cache.ts
var cache_exports = {};

@@ -41,3 +39,3 @@ __export(cache_exports, {

var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
class Cache extends import_fluoro.Service {
cache;

@@ -67,3 +65,3 @@ constructor(ctx) {

}
};
}
var cache_default = Cache;

@@ -70,0 +68,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/service/elements.ts
var elements_exports = {};

@@ -41,3 +39,3 @@ __export(elements_exports, {

var import_tools = require("@kotori-bot/tools");
var Elements = class _Elements {
class Elements {
default(...args) {

@@ -69,7 +67,7 @@ (0, import_tools.none)(this, args);

keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
if (this[key] !== new Elements()[key]) supports.push(key);
});
return supports;
}
};
}
var elements_default = Elements;

@@ -76,0 +74,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,16 +9,10 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {

@@ -33,821 +27,15 @@ if (from && typeof from === "object" || typeof from === "function") {

var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/service/index.ts
var service_exports = {};
__export(service_exports, {
Adapter: () => Adapter,
Api: () => Api,
Cache: () => Cache,
Elements: () => Elements
});
module.exports = __toCommonJS(service_exports);
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// src/service/elements.ts
var import_tools = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/utils/factory.ts
var import_tools7 = require("@kotori-bot/tools");
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/components/core.ts
var import_tools5 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro = require("fluoro");
// src/components/config.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools2 = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko2.default.Object({
name: import_tsukiko2.default.String(),
version: import_tsukiko2.default.String(),
description: import_tsukiko2.default.String(),
main: import_tsukiko2.default.String(),
license: import_tsukiko2.default.Literal("GPL-3.0"),
author: import_tsukiko2.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools2.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools4 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/command.ts
var import_tools3 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/utils/command.ts
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools3.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools4.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/components/core.ts
var Core = class extends import_fluoro.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools5.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
// src/utils/container.ts
var import_tools6 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools6.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
function disposeFactory(ctx, dispose) {
ctx.once("dispose_module", (data) => {
if ((typeof data.instance === "object" ? data.instance.name : data.instance) !== ctx.identity) {
disposeFactory(ctx, dispose);
return;
}
dispose();
});
}
function cancelFactory() {
return {
get() {
return () => this.fn();
},
fn() {
this.value = true;
},
value: false
};
}
function formatFactory(i18n) {
return (template, data) => {
const params = data;
if (Array.isArray(params)) {
let str = i18n.locale(template);
params.forEach((value, index) => {
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));
});
return str;
}
Object.keys(params).forEach((key) => {
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools7.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
return (message) => {
adapter.api.sendGroupMsg(message, data.groupId, data.extra);
};
}
return (message) => {
adapter.api.sendPrivateMsg(message, data.userId, data.extra);
};
}
function quickFactory(send, i18n) {
return async (message) => {
const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (typeof msg === "string") {
send(i18n.locale(msg));
return;
}
send(formatFactory(i18n)(...msg));
};
}
function isSameSender(adapter, data, session) {
return session.api.adapter.identity === adapter.identity && session.api.adapter.platform === adapter.platform && session.type === data.type && session.groupId === data.groupId && session.userId === data.userId && "messageId" in data && session.messageId !== data.messageId;
}
function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
return;
}
adapter.ctx.once("on_message", handle);
};
quick(message ?? "corei18n.template.prompt").then(() => adapter.ctx.once("on_message", handle));
});
}
function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;
}
adapter.ctx.once("on_message", handle);
};
quick(options?.message ?? "corei18n.template.confirm").then(() => adapter.ctx.once("on_message", handle));
});
}
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools8 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools8.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools8.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools8.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools8.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools8.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools8.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools8.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools8.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools8.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools8.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools8.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro2 = require("fluoro");
var Cache = class extends import_fluoro2.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
__reExport(service_exports, require("./adapter"), module.exports);
__reExport(service_exports, require("./api"), module.exports);
__reExport(service_exports, require("./elements"), module.exports);
__reExport(service_exports, require("./cache"), module.exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Adapter,
Api,
Cache,
Elements
...require("./adapter"),
...require("./api"),
...require("./elements"),
...require("./cache")
});
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -27,5 +27,3 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/types/adapter.ts
var adapter_exports = {};
module.exports = __toCommonJS(adapter_exports);
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -27,5 +27,3 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/types/config.ts
var config_exports = {};
module.exports = __toCommonJS(config_exports);
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,16 +9,10 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {

@@ -32,46 +26,14 @@ if (from && typeof from === "object" || typeof from === "function") {

};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/types/index.ts
var types_exports = {};
__export(types_exports, {
CommandAccess: () => CommandAccess,
MessageScope: () => MessageScope,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
eventDataTargetIdSchema: () => eventDataTargetIdSchema
});
module.exports = __toCommonJS(types_exports);
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
__reExport(types_exports, require("./config"), module.exports);
__reExport(types_exports, require("./message"), module.exports);
__reExport(types_exports, require("./adapter"), module.exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CommandAccess,
MessageScope,
commandArgTypeSignSchema,
eventDataTargetIdSchema
...require("./config"),
...require("./message"),
...require("./adapter")
});
/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -41,4 +41,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/types/message.ts
var message_exports = {};

@@ -59,3 +57,3 @@ __export(message_exports, {

})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
const commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),

@@ -69,3 +67,3 @@ import_tsukiko.default.Literal("boolean")

})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
const eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// Annotate the CommonJS export names for ESM import in node:

@@ -72,0 +70,0 @@ 0 && (module.exports = {

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -41,4 +41,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/command.ts
var command_exports = {};

@@ -52,49 +50,7 @@ __export(command_exports, {

var import_minimist = __toESM(require("minimist"));
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
// src/utils/command.ts
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
var import_types = require("../types");
var import_commandError = require("./commandError");
const requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
const optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
const defaultType = "string";
function handleDefaultValue(value, type) {

@@ -112,3 +68,3 @@ if (type === "boolean") return value !== "false" && !!value;

}
var Command = class {
class Command {
static run(input, data) {

@@ -120,3 +76,3 @@ let starts = "";

});
if (!starts) return new CommandError({ type: "unknown", input });
if (!starts) return new import_commandError.CommandError({ type: "unknown", input });
const opts = {

@@ -136,3 +92,3 @@ string: [],

const arr = (0, import_tools.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
if (!Array.isArray(arr)) return new import_commandError.CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);

@@ -144,6 +100,6 @@ const args = result._;

};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
if (count.reality < count.expected) return new import_commandError.CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
return new import_commandError.CommandError({ type: "arg_many", ...count });
let error;

@@ -159,3 +115,3 @@ data.args.forEach((val, index) => {

if (!Number.isNaN(args[index])) return;
error = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
error = new import_commandError.CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});

@@ -169,3 +125,3 @@ if (error) return error;

if (Number.isNaN(options[val.realname]))
error = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
error = new import_commandError.CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});

@@ -183,3 +139,3 @@ if (error) return error;

scope: "all",
access: 0 /* MEMBER */,
access: import_types.CommandAccess.MEMBER,
args: [],

@@ -214,3 +170,3 @@ options: []

if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
const type = import_types.commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({

@@ -229,3 +185,3 @@ name: result[2],

name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
type: import_types.commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],

@@ -255,3 +211,3 @@ optional: false

description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
type: import_types.commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)

@@ -269,3 +225,3 @@ });

}
};
}
var command_default = Command;

@@ -272,0 +228,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/commandError.ts
var commandError_exports = {};

@@ -40,30 +38,4 @@ __export(commandError_exports, {

module.exports = __toCommonJS(commandError_exports);
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
var import_error = require("./error");
class CommandError extends import_error.KotoriError {
value;

@@ -74,3 +46,3 @@ constructor(value) {

}
};
}
var commandError_default = CommandError;

@@ -77,0 +49,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/container.ts
var container_exports = {};

@@ -41,3 +39,3 @@ __export(container_exports, {

var import_tools = require("@kotori-bot/tools");
var Container = class _Container {
class Container {
constructor() {

@@ -55,7 +53,7 @@ (0, import_tools.none)();

return Object.assign(
_Container.getInstance()
Container.getInstance()
/* , Context */
);
}
};
}
var container_default = Container;

@@ -62,0 +60,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -31,4 +31,2 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/error.ts
var error_exports = {};

@@ -42,3 +40,3 @@ __export(error_exports, {

module.exports = __toCommonJS(error_exports);
var KotoriError = class _KotoriError extends Error {
class KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {

@@ -53,3 +51,3 @@ super(message);

const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
return new Proxy(KotoriError, {
construct(Class, params) {

@@ -64,5 +62,5 @@ const args = params;

}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
}
const ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
const DevError = new KotoriError(void 0, void 0, "DevError").extend();
var error_default = KotoriError;

@@ -69,0 +67,0 @@ // Annotate the CommonJS export names for ESM import in node:

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,11 +9,9 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;

@@ -32,14 +30,3 @@ var __export = (target, all) => {

};
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/factory.ts
var factory_exports = {};

@@ -56,709 +43,5 @@ __export(factory_exports, {

module.exports = __toCommonJS(factory_exports);
var import_tools8 = require("@kotori-bot/tools");
// src/types/message.ts
var import_tsukiko = __toESM(require("tsukiko"));
var CommandAccess = /* @__PURE__ */ ((CommandAccess2) => {
CommandAccess2[CommandAccess2["MEMBER"] = 0] = "MEMBER";
CommandAccess2[CommandAccess2["MANGER"] = 1] = "MANGER";
CommandAccess2[CommandAccess2["ADMIN"] = 2] = "ADMIN";
return CommandAccess2;
})(CommandAccess || {});
var commandArgTypeSignSchema = import_tsukiko.default.Union([
import_tsukiko.default.Union([import_tsukiko.default.Literal("string"), import_tsukiko.default.Literal("number")]),
import_tsukiko.default.Literal("boolean")
]);
var MessageScope = /* @__PURE__ */ ((MessageScope2) => {
MessageScope2[MessageScope2["PRIVATE"] = 0] = "PRIVATE";
MessageScope2[MessageScope2["GROUP"] = 1] = "GROUP";
return MessageScope2;
})(MessageScope || {});
var eventDataTargetIdSchema = import_tsukiko.default.Union([import_tsukiko.default.Number(), import_tsukiko.default.String()]);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ADAPTER_PREFIX: () => ADAPTER_PREFIX,
Adapter: () => Adapter,
Api: () => Api,
CUSTOM_PREFIX: () => CUSTOM_PREFIX,
Cache: () => Cache,
Command: () => Command,
CommandAccess: () => CommandAccess,
CommandError: () => CommandError,
Container: () => Container,
Core: () => Core,
DATABASE_PREFIX: () => DATABASE_PREFIX,
DEFAULT_CORE_CONFIG: () => DEFAULT_CORE_CONFIG,
DEFAULT_PORT: () => DEFAULT_PORT,
DevError: () => DevError,
Elements: () => Elements,
KotoriError: () => KotoriError,
MessageScope: () => MessageScope,
ModuleError: () => ModuleError,
OFFICIAL_MODULES_SCOPE: () => OFFICIAL_MODULES_SCOPE,
PLUGIN_PREFIX: () => PLUGIN_PREFIX,
Symbols: () => Symbols,
cancelFactory: () => cancelFactory,
commandArgTypeSignSchema: () => commandArgTypeSignSchema,
confirmFactory: () => confirmFactory,
disposeFactory: () => disposeFactory,
eventDataTargetIdSchema: () => eventDataTargetIdSchema,
formatFactory: () => formatFactory,
promptFactory: () => promptFactory,
quickFactory: () => quickFactory,
sendMessageFactory: () => sendMessageFactory
});
__reExport(src_exports, require("fluoro"));
// src/components/core.ts
var import_tools6 = require("@kotori-bot/tools");
var import_i18n2 = __toESM(require("@kotori-bot/i18n"));
var import_fluoro2 = require("fluoro");
// src/components/config.ts
var import_tsukiko2 = __toESM(require("tsukiko"));
var import_node_path = require("path");
var import_tools = require("@kotori-bot/tools");
// src/global/constants.ts
var import_i18n = require("@kotori-bot/i18n");
var OFFICIAL_MODULES_SCOPE = "@kotori-bot/";
var PLUGIN_PREFIX = "kotori-plugin-";
var DATABASE_PREFIX = `${PLUGIN_PREFIX}database-`;
var ADAPTER_PREFIX = `${PLUGIN_PREFIX}adapter-`;
var CUSTOM_PREFIX = `${PLUGIN_PREFIX}custom-`;
var DEFAULT_PORT = 720;
var DEFAULT_CORE_CONFIG = {
global: {
lang: import_i18n.DEFAULT_LANG,
"command-prefix": "/",
port: DEFAULT_PORT
},
adapter: {},
plugin: {}
};
// src/global/symbols.ts
var Symbols = class {
static adapter = Symbol.for("kotori.core.adapter");
static bot = Symbol.for("kotori.core.bot");
static midware = Symbol.for("kotori.core.midware");
static command = Symbol.for("kotori.core.command");
static regexp = Symbol.for("kotori.core.regexp");
static modules = Symbol.for("kotori.loader.module");
static job = Symbol.for("kotori.loader.job");
};
// src/components/config.ts
var packageInfoSchema = import_tsukiko2.default.Object({
name: import_tsukiko2.default.String(),
version: import_tsukiko2.default.String(),
description: import_tsukiko2.default.String(),
main: import_tsukiko2.default.String(),
license: import_tsukiko2.default.Literal("GPL-3.0"),
author: import_tsukiko2.default.String()
});
var Config = class {
config;
pkg;
constructor(config = DEFAULT_CORE_CONFIG) {
this.config = config;
const info = (0, import_tools.loadConfig)((0, import_node_path.resolve)(__dirname, "../../package.json"));
if (!info || Object.values(info).length === 0) {
process.stderr.write(`Cannot find kotori-bot package.json
`);
process.exit();
}
const result = packageInfoSchema.parseSafe(info);
if (!result.value) {
process.stderr.write(`File package.json format error: ${result.error.message}
`);
process.exit();
}
this.pkg = result.data;
}
};
var config_default = Config;
// src/components/message.ts
var import_tools3 = require("@kotori-bot/tools");
var import_cron = require("cron");
// src/utils/command.ts
var import_tools2 = require("@kotori-bot/tools");
var import_minimist = __toESM(require("minimist"));
// src/utils/error.ts
var KotoriError = class _KotoriError extends Error {
constructor(message, extra, type = "UnknownError") {
super(message);
this.name = type;
this.extra = extra;
}
extra;
name;
extend() {
const { message: fatherMessage, name: fatherType, extra: fatherExtra } = this;
return new Proxy(_KotoriError, {
construct(Class, params) {
const args = params;
args[0] = `${fatherMessage} ${args[0]}`;
args[1] = args[1] ?? fatherExtra;
args[2] = args[2] ?? fatherType;
return new Class(...args);
}
});
}
};
var ModuleError = new KotoriError(void 0, void 0, "ModuleError").extend();
var DevError = new KotoriError(void 0, void 0, "DevError").extend();
// src/utils/commandError.ts
var CommandError = class extends KotoriError {
value;
constructor(value) {
super();
this.value = value;
}
};
var commandError_default = CommandError;
// src/utils/command.ts
var requiredParamMatch = /<(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?>/;
var optionalParamMatch = /\[(\.\.\.)?(.*?)(:(.*?))?(=(.*?))?\]/;
var defaultType = "string";
function handleDefaultValue(value, type) {
if (type === "boolean") return value !== "false" && !!value;
if (type === "number") {
if (typeof value === "number") return value;
if (value === true) return 1;
if (value === false) return 0;
const float = parseFloat(value);
const int = parseInt(value, 10);
return float === int ? int : float;
}
return value.toString();
}
var Command = class {
static run(input, data) {
let starts = "";
[data.root, ...data.alias].forEach((el) => {
if (starts) return;
if (input.startsWith(`${el} `) || input === el) starts = el;
});
if (!starts) return new CommandError({ type: "unknown", input });
const opts = {
string: [],
boolean: [],
alias: {}
};
data.options.forEach((option) => {
if (option.type === "string") {
opts.string.push(option.realname);
} else if (option.type === "boolean") {
opts.boolean.push(option.realname);
}
opts.alias[option.realname] = option.name;
});
const arr = (0, import_tools2.parseArgs)(input.slice(starts.length).trim());
if (!Array.isArray(arr)) return new CommandError({ type: "syntax", ...arr });
const result = (0, import_minimist.default)(arr, opts);
const args = result._;
const count = {
expected: data.args.filter((el) => !el.optional).length,
reality: args.length
};
if (count.reality < count.expected) return new CommandError({ type: "arg_few", ...count });
count.expected = data.args.length;
if ((data.args.length <= 0 || !data.args[data.args.length - 1].rest) && count.reality > count.expected)
return new CommandError({ type: "arg_many", ...count });
let error2;
data.args.forEach((val, index) => {
if (error2 || index > 0 && !args[index - 1]) return;
if (!args[index] && val.default) {
args[index] = val.default;
return;
}
if (val.rest || !args[index]) return;
args[index] = handleDefaultValue(args[index], val.type);
if (!Number.isNaN(args[index])) return;
error2 = new CommandError({ type: "arg_error", expected: "number", reality: "string", index });
});
if (error2) return error2;
const options = {};
data.options.forEach((val) => {
if (!(val.realname in result)) return;
options[val.realname] = Array.isArray(result[val.realname]) ? result[val.realname][0] : result[val.realname];
options[val.realname] = handleDefaultValue(options[val.realname], val.type);
if (Number.isNaN(options[val.realname]))
error2 = new CommandError({ type: "option_error", expected: "number", reality: "string", target: val.realname });
});
if (error2) return error2;
return {
args: data.args.length > 0 && data.args[data.args.length - 1].rest ? args : args.slice(0, data.args.length),
options
};
}
template;
meta = {
root: "",
alias: [],
scope: "all",
access: 0 /* MEMBER */,
args: [],
options: []
};
constructor(template, config) {
this.template = template;
this.meta = Object.assign(this.meta, config);
this.parse();
}
parse() {
const [str, description] = this.template.trim().split(" - ");
this.meta.description = description;
const requiredIndex = str.indexOf(" <");
const optionalIndex = str.indexOf(" [");
if (requiredIndex === -1 && optionalIndex === -1) {
this.meta.root = str.trim();
return;
}
if (requiredIndex !== -1 && (optionalIndex === -1 || requiredIndex < optionalIndex)) {
this.meta.root = str.substring(0, requiredIndex).trim();
} else {
this.meta.root = str.substring(0, optionalIndex).trim();
}
const args = (0, import_minimist.default)(str.split(" "))._;
args.forEach((arg) => {
const current = this.meta.args[this.meta.args.length - 1];
if (current && current.rest) return;
let result = optionalParamMatch.exec(arg);
if (result) {
if (!result[2]) return;
const type = commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType;
this.meta.args.push({
name: result[2],
type,
rest: !!result[1],
optional: true,
default: result[6] ? handleDefaultValue(result[6], type) : void 0
});
}
result = requiredParamMatch.exec(arg);
if (!result || !result[2]) return;
if (!result[6] && current && current.optional) return;
this.meta.args.push({
name: result[2],
type: commandArgTypeSignSchema.parseSafe(result[4]).value ? result[4] : defaultType,
rest: !!result[1],
optional: false
});
});
}
alias(alias) {
if (typeof alias === "string") this.meta.alias.push(alias);
else this.meta.alias.push(...alias);
return this;
}
scope(scope) {
this.meta.scope = scope;
return this;
}
access(access) {
this.meta.access = access;
return this;
}
option(name, template) {
const [str, description] = template.trim().split(" ");
const [realname, type] = str.split(":");
this.meta.options.push({
realname,
description,
type: commandArgTypeSignSchema.parseSafe(type).value ? type : defaultType,
name: name.charAt(0)
});
return this;
}
action(callback) {
this.meta.action = callback;
return this;
}
help(text) {
this.meta.help = text;
return this;
}
};
// src/components/message.ts
var Message = class {
[Symbols.midware] = /* @__PURE__ */ new Set();
[Symbols.command] = /* @__PURE__ */ new Set();
[Symbols.regexp] = /* @__PURE__ */ new Set();
handleMidware(session) {
const { api } = session;
let isPass = true;
let midwares = [];
api.adapter.status.receivedMsg += 1;
this[Symbols.midware].forEach((val) => midwares.push(val));
midwares = midwares.sort((first, second) => first.priority - second.priority);
let lastMidwareNum = -1;
while (midwares.length > 0) {
if (lastMidwareNum === midwares.length) {
isPass = false;
break;
}
lastMidwareNum = midwares.length;
session.quick(midwares[0].callback(() => midwares.shift(), session));
}
this.ctx.emit("midwares", { isPass, session });
}
async handleRegexp(data) {
const { session } = data;
if (!data.isPass) return;
this[Symbols.regexp].forEach((data2) => {
const result = session.message.match(data2.match);
if (!result) return;
session.quick(data2.callback(result, session));
this.ctx.emit("regexp", { result, session, regexp: data2.match, raw: session.message });
});
}
handleCommand(data) {
const { session } = data;
const prefix = session.api.adapter.config["command-prefix"] ?? this.ctx.config.global["command-prefix"];
if (!session.message.startsWith(prefix)) return;
const params = {
session,
raw: (0, import_tools3.stringRightSplit)(session.message, prefix)
};
this.ctx.emit("before_parse", params);
const cancel = cancelFactory();
this.ctx.emit("before_command", { cancel: cancel.get(), ...params });
if (cancel.value) return;
let matched;
this[Symbols.command].forEach(async (cmd) => {
if (matched || !cmd.meta.action) return;
const result = Command.run(params.raw, cmd.meta);
if (result instanceof commandError_default && result.value.type === "unknown") return;
matched = cmd;
this.ctx.emit("parse", { command: cmd, result, ...params, cancel: cancel.get() });
if (cancel.value || result instanceof commandError_default) return;
try {
const executed = await cmd.meta.action({ args: result.args, options: result.options }, session);
if (executed instanceof commandError_default) {
this.ctx.emit("command", { command: cmd, result: executed, ...params });
return;
}
if (executed !== void 0) session.quick(executed);
this.ctx.emit("command", {
command: cmd,
result: executed instanceof commandError_default ? result : executed,
...params
});
} catch (error2) {
this.ctx.emit("command", {
command: matched,
result: new commandError_default({ type: "error", error: error2 }),
...params
});
}
});
if (matched) return;
this.ctx.emit("parse", {
command: new Command(""),
result: new commandError_default({ type: "unknown", input: params.raw }),
...params,
cancel: cancel.get()
});
}
ctx;
constructor(ctx) {
this.ctx = ctx;
this.ctx.on("on_message", (session) => this.handleMidware(session));
this.ctx.on("midwares", (data) => this.handleCommand(data));
this.ctx.on("midwares", (data) => this.handleRegexp(data));
this.ctx.on("before_send", (data) => {
const { api } = data;
api.adapter.status.sentMsg += 1;
});
}
midware(callback, priority = 100) {
const data = { callback, priority };
this[Symbols.midware].add(data);
const dispose = () => this[Symbols.midware].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
command(template, config) {
const command = new Command(template, config);
this[Symbols.command].add(command);
const dispose = () => this[Symbols.command].delete(command);
disposeFactory(this.ctx, dispose);
return command;
}
regexp(match, callback) {
const data = { match, callback };
this[Symbols.regexp].add(data);
const dispose = () => this[Symbols.regexp].delete(data);
disposeFactory(this.ctx, dispose);
return dispose;
}
// boardcast(type: MessageScope, message: MessageRaw) {
// const send =
// type === 'private'
// ? (api: Api) => api.send_on_message(message, 1)
// : (api: Api) => api.send_on_message(message, 1);
// /* this need support of database... */
// Object.values(this.botStack).forEach((apis) => {
// apis.forEach((api) => send(api));
// });
// }
notify(message) {
const mainAdapterIdentity = Object.keys(this.ctx.config.adapter)[0];
this.ctx[Symbols.bot].forEach(
(apis) => apis.forEach((api) => {
if (api.adapter.identity !== mainAdapterIdentity) return;
quickFactory(
sendMessageFactory(api.adapter, "on_message", { userId: api.adapter.config.master }),
this.ctx.i18n.extends(api.adapter.config.lang)
)(message);
})
);
}
task(options, callback) {
const [cron, extraOptions] = typeof options === "string" ? [options, {}] : [options.cron, options];
return new import_cron.CronJob(cron, () => callback(this.ctx), null, extraOptions.start ?? true, extraOptions.timeZone);
}
};
var message_default = Message;
// src/service/elements.ts
var import_tools4 = require("@kotori-bot/tools");
var Elements = class _Elements {
default(...args) {
(0, import_tools4.none)(this, args);
return "";
}
at(target, ...extra) {
return this.default(target, extra);
}
image(url, ...extra) {
return this.default(url, extra);
}
voice(url, ...extra) {
return this.default(url, extra);
}
video(url, ...extra) {
return this.default(url, extra);
}
face(id, ...extra) {
return this.default(id, extra);
}
file(data, ...extra) {
return this.default(data, extra);
}
supports() {
const supports = [];
const keys = ["at", "image", "voice", "video", "face", "file"];
keys.forEach((key) => {
if (this[key] !== new _Elements()[key]) supports.push(key);
});
return supports;
}
};
var elements_default = Elements;
// src/service/adapter.ts
function setProxy(api, ctx) {
const proxy = Object.create(api);
proxy.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendPrivateMsg(message, targetId, argArray[2]);
}
});
proxy.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray;
const cancel = cancelFactory();
ctx.emit("before_send", { api, message, messageType: 0 /* PRIVATE */, targetId, cancel: cancel.get() });
if (cancel.value) return;
api.sendGroupMsg(message, targetId, argArray[2]);
}
});
return proxy;
}
function error(type, data) {
return new commandError_default(Object.assign(data ?? {}, { type }));
}
var Adapter = class {
constructor(ctx, config, identity, Api2, el = new elements_default()) {
this.ctx = ctx;
this.config = config;
this.identity = identity;
this.platform = config.extends;
this.api = setProxy(new Api2(this), this.ctx);
this.elements = el;
if (!this.ctx[Symbols.bot].get(this.platform)) this.ctx[Symbols.bot].set(this.platform, /* @__PURE__ */ new Set());
this.ctx[Symbols.bot].get(this.platform).add(this.api);
}
online() {
if (this.status.value !== "offline") return;
this.status.value = "online";
this.ctx.emit("status", { adapter: this, status: "online" });
}
offline() {
if (this.status.value !== "online") return;
this.status.value = "offline";
this.status.offlineTimes += 1;
this.ctx.emit("status", { adapter: this, status: "offline" });
}
session(type, data) {
const i18n = this.ctx.i18n.extends(this.config.lang);
const send = sendMessageFactory(this, type, data);
const format = formatFactory(i18n);
const quick = quickFactory(send, i18n);
const prompt = promptFactory(quick, this, data);
const confirm = confirmFactory(quick, this, data);
const { api, elements: el } = this;
this.ctx.emit(
type,
...[{ ...data, api, el, send, i18n, format, quick, prompt, confirm, error }]
);
}
ctx;
config;
identity;
platform;
api;
elements;
status = {
value: "offline",
createTime: /* @__PURE__ */ new Date(),
lastMsgTime: null,
receivedMsg: 0,
sentMsg: 0,
offlineTimes: 0
};
selfId = -1;
};
// src/service/api.ts
var import_tools5 = require("@kotori-bot/tools");
var Api = class {
adapter;
constructor(adapter) {
this.adapter = adapter;
}
sendPrivateMsg(message, userId, ...extra) {
(0, import_tools5.none)(this, message, userId, extra);
}
sendGroupMsg(message, groupId, ...extra) {
(0, import_tools5.none)(this, message, groupId, extra, extra);
}
deleteMsg(messageId, ...extra) {
(0, import_tools5.none)(this, messageId, extra);
}
setGroupName(groupId, groupName, ...extra) {
(0, import_tools5.none)(this, groupId, groupName, extra);
}
setGroupAvatar(groupId, image, ...extra) {
(0, import_tools5.none)(this, groupId, image, extra);
}
setGroupAdmin(groupId, userId, enable, ...extra) {
(0, import_tools5.none)(this, groupId, userId, enable, extra);
}
setGroupCard(groupId, userId, card, ...extra) {
(0, import_tools5.none)(this, groupId, userId, card, extra);
}
setGroupBan(groupId, userId, time, ...extra) {
(0, import_tools5.none)(this, groupId, userId, time, extra);
}
sendGroupNotice(groupId, content, image, ...extra) {
(0, import_tools5.none)(this, groupId, content, image, extra);
}
setGroupKick(groupId, userId, ...extra) {
(0, import_tools5.none)(this, groupId, userId, extra);
}
setGroupLeave(groupId, ...extra) {
(0, import_tools5.none)(this, groupId, groupId, extra);
}
};
// src/service/cache.ts
var import_fluoro = require("fluoro");
var Cache = class extends import_fluoro.Service {
cache;
constructor(ctx) {
super(ctx, {}, "cache");
}
start() {
if (this.cache) return;
this.cache = /* @__PURE__ */ new Map();
}
stop() {
this.cache?.forEach((el) => el.clear());
this.cache?.clear();
delete this.cache;
}
getContainer() {
const key = this.ctx.identity ?? "root";
if (!this.cache.has(key)) this.cache.set(key, /* @__PURE__ */ new Map());
return this.cache.get(key);
}
get(prop) {
return this.getContainer().get(prop);
}
set(prop, value) {
this.getContainer().set(prop, value);
}
};
// src/components/core.ts
var Core = class extends import_fluoro2.Context {
[Symbols.adapter] = /* @__PURE__ */ new Map();
[Symbols.bot] = /* @__PURE__ */ new Map();
constructor(config) {
super();
this.provide("config", new config_default(config));
this.mixin("config", ["config", "pkg"]);
this.provide("message", new message_default(this));
this.mixin("message", ["midware", "command", "regexp", "notify", "task"]);
this.provide("http", new import_tools6.Http({ validateStatus: () => true }));
this.inject("http");
this.provide("i18n", new import_i18n2.default({ lang: this.config.global.lang }));
this.inject("i18n");
this.service("cache", new Cache(this.extends()));
}
};
// src/utils/container.ts
var import_tools7 = require("@kotori-bot/tools");
var Container = class _Container {
constructor() {
(0, import_tools7.none)();
}
static instance = {};
static setInstance(ctx) {
this.instance = ctx;
}
static getInstance() {
return this.instance;
}
static getMixin() {
return Object.assign(
_Container.getInstance()
/* , Context */
);
}
};
// src/index.ts
__reExport(src_exports, require("@kotori-bot/tools"));
__reExport(src_exports, require("@kotori-bot/i18n"));
__reExport(src_exports, require("tsukiko"));
// src/utils/factory.ts
var import_types = require("../types");
var import__ = require("..");
function disposeFactory(ctx, dispose) {

@@ -790,2 +73,3 @@ ctx.once("dispose_module", (data) => {

params.forEach((value, index) => {
if (value === void 0 || value === null) return;
str = str.replaceAll(`{${index}}`, i18n.locale(typeof value === "string" ? value : String(value)));

@@ -796,10 +80,11 @@ });

Object.keys(params).forEach((key) => {
if (params[key] === void 0 || params[key] === null) return;
if (typeof params[key] !== "string") params[key] = String(params[key]);
params[key] = i18n.locale(params[key]);
});
return (0, import_tools8.stringTemp)(i18n.locale(template), params);
return (0, import_tools.stringTemp)(i18n.locale(template), params);
};
}
function sendMessageFactory(adapter, type, data) {
if ((data.type === 1 /* GROUP */ || type.includes("group")) && "groupId" in data) {
if ((data.type === import_types.MessageScope.GROUP || type.includes("group")) && "groupId" in data) {
return (message) => {

@@ -816,3 +101,3 @@ adapter.api.sendGroupMsg(message, data.groupId, data.extra);

const msg = await message;
if (!msg || msg instanceof CommandError) return;
if (!msg || msg instanceof import__.CommandError) return;
if (typeof msg === "string") {

@@ -829,6 +114,6 @@ send(i18n.locale(msg));

function promptFactory(quick, adapter, data) {
return (message) => new Promise((resolve2) => {
return (message) => new Promise((resolve) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message);
resolve(session.message);
return;

@@ -842,6 +127,6 @@ }

function confirmFactory(quick, adapter, data) {
return (options) => new Promise((resolve2) => {
return (options) => new Promise((resolve) => {
const handle = (session) => {
if (isSameSender(adapter, data, session)) {
resolve2(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
resolve(session.message === (options?.sure ?? "corei18n.template.confirm.sure"));
return;

@@ -848,0 +133,0 @@ }

/**
* @Package @kotori-bot/core
* @Version 1.4.2-beta.1
* @Version 1.5.0
* @Author Hotaru <biyuehuya@gmail.com>

@@ -9,3 +9,3 @@ * @Copyright 2024 Hotaru. All rights reserved.

* @Link https://github.com/kotorijs/kotori
* @Date 2024/6/6 21:03:53
* @Date 2024/6/7 11:22:22
*/

@@ -27,5 +27,3 @@

var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/utils/jsxFactory.tsx
var jsxFactory_exports = {};
module.exports = __toCommonJS(jsxFactory_exports);
{
"name": "@kotori-bot/core",
"version": "1.5.0",
"version": "1.5.1",
"description": "Kotori Core",

@@ -32,5 +32,5 @@ "main": "lib/index.js",

"tsukiko": "^1.2.5",
"@kotori-bot/i18n": "^1.3.0",
"@kotori-bot/tools": "^1.4.0"
"@kotori-bot/i18n": "^1.3.1",
"@kotori-bot/tools": "^1.4.1"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc