koishi-utils
Version:
Utilities for Koishi
1,065 lines (1,053 loc) • 32.5 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
__markAsModule(target);
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== "default")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
// packages/koishi-utils/src/index.ts
__export(exports, {
Logger: () => Logger,
Random: () => Random,
Time: () => Time,
assertProperty: () => assertProperty,
camelCase: () => camelCase,
camelize: () => camelize,
capitalize: () => capitalize,
clone: () => clone,
coerce: () => coerce,
contain: () => contain,
deduplicate: () => deduplicate,
defineEnumProperty: () => defineEnumProperty,
defineProperty: () => defineProperty,
difference: () => difference,
enumKeys: () => enumKeys,
escapeRegExp: () => escapeRegExp,
hyphenate: () => hyphenate,
interpolate: () => interpolate,
intersection: () => intersection,
isInteger: () => isInteger,
makeArray: () => makeArray,
merge: () => merge,
noop: () => noop,
observe: () => observe,
omit: () => omit,
paramCase: () => paramCase,
pick: () => pick,
remove: () => remove,
renameProperty: () => renameProperty,
s: () => segment,
sanitize: () => sanitize,
segment: () => segment,
simplify: () => simplify,
sleep: () => sleep,
snakeCase: () => snakeCase,
t: () => template,
template: () => template,
traditionalize: () => traditionalize,
trimSlash: () => trimSlash,
union: () => union
});
// packages/koishi-utils/src/chinese.ts
var import_fs = __toModule(require("fs"));
var import_path = __toModule(require("path"));
var [simplified, traditional] = (0, import_fs.readFileSync)((0, import_path.resolve)(__dirname, "../chinese.txt"), "utf-8").split(/\r?\n/);
var stMap = new Map();
var tsMap = new Map();
simplified.split("").forEach((char, index) => {
stMap.set(char, traditional[index]);
tsMap.set(traditional[index], char);
});
function traditionalize(source) {
let result = "";
for (const char of source) {
result += stMap.get(char) || char;
}
return result;
}
function simplify(source) {
let result = "";
for (const char of source) {
result += tsMap.get(char) || char;
}
return result;
}
// packages/koishi-utils/src/logger.ts
var import_util = __toModule(require("util"));
var import_readline = __toModule(require("readline"));
var import_supports_color = __toModule(require("supports-color"));
// packages/koishi-utils/src/time.ts
var Time;
(function(Time2) {
Time2.millisecond = 1;
Time2.second = 1e3;
Time2.minute = Time2.second * 60;
Time2.hour = Time2.minute * 60;
Time2.day = Time2.hour * 24;
Time2.week = Time2.day * 7;
let timezoneOffset = new Date().getTimezoneOffset();
function setTimezoneOffset(offset) {
timezoneOffset = offset;
}
Time2.setTimezoneOffset = setTimezoneOffset;
function getTimezoneOffset() {
return timezoneOffset;
}
Time2.getTimezoneOffset = getTimezoneOffset;
function getDateNumber(date = new Date(), offset) {
if (typeof date === "number")
date = new Date(date);
if (offset === void 0)
offset = timezoneOffset;
return Math.floor((date.valueOf() / Time2.minute - offset) / 1440);
}
Time2.getDateNumber = getDateNumber;
function fromDateNumber(value, offset) {
const date = new Date(value * Time2.day);
if (offset === void 0)
offset = timezoneOffset;
return new Date(+date + offset * Time2.minute);
}
Time2.fromDateNumber = fromDateNumber;
const numeric = /\d+(?:\.\d+)?/.source;
const timeRegExp = new RegExp(`^${[
"w(?:eek(?:s)?)?",
"d(?:ay(?:s)?)?",
"h(?:our(?:s)?)?",
"m(?:in(?:ute)?(?:s)?)?",
"s(?:ec(?:ond)?(?:s)?)?"
].map((unit) => `(${numeric}${unit})?`).join("")}$`);
function parseTime(source) {
const capture = timeRegExp.exec(source);
if (!capture)
return 0;
return (parseFloat(capture[1]) * Time2.week || 0) + (parseFloat(capture[2]) * Time2.day || 0) + (parseFloat(capture[3]) * Time2.hour || 0) + (parseFloat(capture[4]) * Time2.minute || 0) + (parseFloat(capture[5]) * Time2.second || 0);
}
Time2.parseTime = parseTime;
function parseDate(date) {
const parsed = parseTime(date);
if (parsed) {
date = Date.now() + parsed;
} else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) {
date = `${new Date().toLocaleDateString()}-${date}`;
} else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) {
date = `${new Date().getFullYear()}-${date}`;
}
return date ? new Date(date) : new Date();
}
Time2.parseDate = parseDate;
function formatTimeShort(ms) {
const abs = Math.abs(ms);
if (abs >= Time2.day - Time2.hour / 2) {
return Math.round(ms / Time2.day) + "d";
} else if (abs >= Time2.hour - Time2.minute / 2) {
return Math.round(ms / Time2.hour) + "h";
} else if (abs >= Time2.minute - Time2.second / 2) {
return Math.round(ms / Time2.minute) + "m";
} else if (abs >= Time2.second) {
return Math.round(ms / Time2.second) + "s";
}
return ms + "ms";
}
Time2.formatTimeShort = formatTimeShort;
function formatTime(ms) {
let result;
if (ms >= Time2.day - Time2.hour / 2) {
ms += Time2.hour / 2;
result = Math.floor(ms / Time2.day) + " 天";
if (ms % Time2.day > Time2.hour) {
result += ` ${Math.floor(ms % Time2.day / Time2.hour)} 小时`;
}
} else if (ms >= Time2.hour - Time2.minute / 2) {
ms += Time2.minute / 2;
result = Math.floor(ms / Time2.hour) + " 小时";
if (ms % Time2.hour > Time2.minute) {
result += ` ${Math.floor(ms % Time2.hour / Time2.minute)} 分钟`;
}
} else if (ms >= Time2.minute - Time2.second / 2) {
ms += Time2.second / 2;
result = Math.floor(ms / Time2.minute) + " 分钟";
if (ms % Time2.minute > Time2.second) {
result += ` ${Math.floor(ms % Time2.minute / Time2.second)} 秒`;
}
} else {
result = Math.round(ms / Time2.second) + " 秒";
}
return result;
}
Time2.formatTime = formatTime;
const dayMap = ["日", "一", "二", "三", "四", "五", "六"];
function toDigits(source, length = 2) {
return source.toString().padStart(length, "0");
}
function template2(template3, time = new Date()) {
return template3.replace("yyyy", time.getFullYear().toString()).replace("yy", time.getFullYear().toString().slice(2)).replace("MM", toDigits(time.getMonth() + 1)).replace("dd", toDigits(time.getDate())).replace("hh", toDigits(time.getHours())).replace("mm", toDigits(time.getMinutes())).replace("ss", toDigits(time.getSeconds())).replace("SSS", toDigits(time.getMilliseconds(), 3));
}
Time2.template = template2;
function toHourMinute(time) {
return `${toDigits(time.getHours())}:${toDigits(time.getMinutes())}`;
}
function formatTimeInterval(time, interval) {
if (!interval) {
return template2("yyyy-MM-dd hh:mm:ss", time);
} else if (interval === Time2.day) {
return `每天 ${toHourMinute(time)}`;
} else if (interval === Time2.week) {
return `每周${dayMap[time.getDay()]} ${toHourMinute(time)}`;
} else {
return `${template2("yyyy-MM-dd hh:mm:ss", time)} 起每隔 ${formatTime(interval)}`;
}
}
Time2.formatTimeInterval = formatTimeInterval;
})(Time || (Time = {}));
// packages/koishi-utils/src/logger.ts
var colors = import_supports_color.stderr && import_supports_color.stderr.level >= 2 ? [
20,
21,
26,
27,
32,
33,
38,
39,
40,
41,
42,
43,
44,
45,
56,
57,
62,
63,
68,
69,
74,
75,
76,
77,
78,
79,
80,
81,
92,
93,
98,
99,
112,
113,
129,
134,
135,
148,
149,
160,
161,
162,
163,
164,
165,
166,
167,
168,
169,
170,
171,
172,
173,
178,
179,
184,
185,
196,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
214,
215,
220,
221
] : [6, 2, 3, 4, 5, 1];
var instances = {};
var _Logger = class {
constructor(name) {
this.name = name;
this.extend = (namespace) => {
return new _Logger(`${this.name}:${namespace}`);
};
if (name in instances)
return instances[name];
let hash = 0;
for (let i = 0; i < name.length; i++) {
hash = (hash << 3) - hash + name.charCodeAt(i);
hash |= 0;
}
instances[name] = this;
this.code = colors[Math.abs(hash) % colors.length];
this.displayName = this.color(name + " ", ";1");
this.createMethod("success", "[S] ", _Logger.SUCCESS);
this.createMethod("error", "[E] ", _Logger.ERROR);
this.createMethod("info", "[I] ", _Logger.INFO);
this.createMethod("warn", "[W] ", _Logger.WARN);
this.createMethod("debug", "[D] ", _Logger.DEBUG);
}
static color(code, value, decoration = "") {
if (!_Logger.options.colors)
return "" + value;
return `[3${code < 8 ? code : "8;5;" + code}${decoration}m${value}[0m`;
}
static clearScreen() {
if (!_Logger.stream["isTTY"] || process.env.CI)
return;
const blank = "\n".repeat(Math.max(_Logger.stream["rows"] - 2, 0));
console.log(blank);
(0, import_readline.cursorTo)(_Logger.stream, 0, 0);
(0, import_readline.clearScreenDown)(_Logger.stream);
}
color(value, decoration = "") {
return _Logger.color(this.code, value, decoration);
}
createMethod(name, prefix, minLevel) {
this[name] = (...args) => {
if (this.level < minLevel)
return;
let indent = 4, output = "";
if (_Logger.showTime) {
indent += _Logger.showTime.length + 1;
output += Time.template(_Logger.showTime + " ");
}
output += prefix + this.displayName + this.format(indent, ...args);
if (_Logger.showDiff) {
const now = Date.now();
const diff = _Logger.timestamp && now - _Logger.timestamp;
output += this.color(" +" + Time.formatTimeShort(diff));
_Logger.timestamp = now;
}
_Logger.stream.write(output + "\n");
};
}
get level() {
var _a;
const paths = this.name.split(":");
let config = _Logger.levels;
do {
config = (_a = config[paths.shift()]) != null ? _a : config["base"];
} while (paths.length && typeof config === "object");
return config;
}
set level(value) {
const paths = this.name.split(":");
let config = _Logger.levels;
while (paths.length > 1) {
const name = paths.shift();
const value2 = config[name];
if (typeof value2 === "object") {
config = value2;
} else {
config = config[name] = { base: value2 != null ? value2 : config.base };
}
}
config[paths[0]] = value;
}
format(indent, ...args) {
if (args[0] instanceof Error) {
args[0] = args[0].stack || args[0].message;
} else if (typeof args[0] !== "string") {
args.unshift("%O");
}
let index = 0;
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format2) => {
if (match === "%%")
return "%";
index += 1;
const formatter = _Logger.formatters[format2];
if (typeof formatter === "function") {
match = formatter.call(this, args[index]);
args.splice(index, 1);
index -= 1;
}
return match;
}).replace(/\n/g, "\n" + " ".repeat(indent));
return (0, import_util.format)(...args);
}
};
var Logger = _Logger;
Logger.SILENT = 0;
Logger.SUCCESS = 1;
Logger.ERROR = 1;
Logger.INFO = 2;
Logger.WARN = 2;
Logger.DEBUG = 3;
Logger.showDiff = false;
Logger.showTime = "";
Logger.timestamp = 0;
Logger.stream = process.stderr;
Logger.levels = {
base: 2
};
Logger.options = {
colors: import_supports_color.stderr && import_supports_color.stderr.hasBasic
};
Logger.formatters = {
c: _Logger.prototype.color,
C: (value) => _Logger.color(15, value, ";1"),
o: (value) => (0, import_util.inspect)(value, _Logger.options).replace(/\s*\n\s*/g, " ")
};
// packages/koishi-utils/src/misc.ts
var import_util2 = __toModule(require("util"));
function noop() {
}
function isInteger(source) {
return typeof source === "number" && Math.floor(source) === source;
}
async function sleep(ms) {
return new Promise((resolve2) => setTimeout(resolve2, ms));
}
function enumKeys(data) {
return Object.values(data).filter((value) => typeof value === "string");
}
function defineEnumProperty(object, key, value) {
object[key] = value;
object[value] = key;
}
var primitives = ["number", "string", "bigint", "boolean", "symbol"];
function clone(source) {
if (primitives.includes(typeof source))
return source;
if (!source)
return source;
if (Array.isArray(source))
return source.map(clone);
if (import_util2.types.isDate(source))
return new Date(source.valueOf());
if (import_util2.types.isRegExp(source))
return new RegExp(source.source, source.flags);
const entries = Object.entries(source).map(([key, value]) => [key, clone(value)]);
return Object.fromEntries(entries);
}
function merge(head, base) {
Object.entries(base).forEach(([key, value]) => {
if (typeof head[key] === "undefined")
return head[key] = base[key];
if (typeof value === "object" && typeof head[key] === "object") {
head[key] = merge(head[key], value);
}
});
return head;
}
function pick(source, keys) {
if (!keys)
return __spreadValues({}, source);
const result = {};
for (const key of keys) {
result[key] = source[key];
}
return result;
}
function omit(source, keys) {
if (!keys)
return __spreadValues({}, source);
const result = __spreadValues({}, source);
for (const key of keys) {
Reflect.deleteProperty(result, key);
}
return result;
}
function defineProperty(object, key, value) {
Object.defineProperty(object, key, { writable: true, value });
}
function assertProperty(config, key) {
if (!config[key])
throw new Error(`missing configuration "${key}"`);
return config[key];
}
function coerce(val) {
const { stack } = val instanceof Error ? val : new Error(val);
return stack;
}
function makeArray(source) {
return Array.isArray(source) ? source : source === null || source === void 0 ? [] : [source];
}
function renameProperty(config, key, oldKey) {
config[key] = Reflect.get(config, oldKey);
Reflect.deleteProperty(config, oldKey);
}
// packages/koishi-utils/src/observe.ts
var import_util3 = __toModule(require("util"));
var logger = new Logger("observer");
var staticTypes = ["number", "string", "bigint", "boolean", "symbol", "function"];
var builtinClasses = ["Date", "RegExp", "Set", "Map", "WeakSet", "WeakMap", "Array"];
function observeProperty(value, proxy, key, label, update) {
if (import_util3.types.isDate(value)) {
return proxy[key] = observeDate(value, update);
} else if (Array.isArray(value)) {
return proxy[key] = observeArray(value, label, update);
} else {
return proxy[key] = observeObject(value, label, update);
}
}
function observeObject(target, label, update) {
if (!target["__proxyGetters__"]) {
Object.defineProperty(target, "__proxyGetters__", { value: {} });
}
const diff = {};
const getters = target["__proxyGetters__"];
if (!update)
defineProperty(target, "_diff", diff);
const proxy = new Proxy(target, {
get(target2, key) {
if (key in getters)
return getters[key];
const value = target2[key];
if (!value || staticTypes.includes(typeof value) || typeof key === "string" && key.startsWith("_"))
return value;
const _update = update || (() => {
const hasKey = key in diff;
diff[key] = getters[key];
if (!hasKey && label) {
logger.debug(`[diff] ${label}: ${String(key)} (deep)`);
}
});
return observeProperty(value, getters, key, label, _update);
},
set(target2, key, value) {
if (target2[key] !== value && (typeof key !== "string" || !key.startsWith("_"))) {
if (update) {
update();
} else {
const hasKey = key in diff;
diff[key] = value;
delete getters[key];
if (!hasKey && label) {
logger.debug(`[diff] ${label}: ${String(key)}`);
}
}
}
return Reflect.set(target2, key, value);
},
deleteProperty(target2, key) {
if (update) {
update();
} else {
delete diff[key];
}
return Reflect.deleteProperty(target2, key);
}
});
return proxy;
}
var arrayProxyMethods = ["pop", "shift", "splice", "sort"];
function observeArray(target, label, update) {
const proxy = {};
for (const method of arrayProxyMethods) {
defineProperty(target, method, function(...args) {
update();
return Array.prototype[method].apply(this, args);
});
}
return new Proxy(target, {
get(target2, key) {
if (key in proxy)
return proxy[key];
const value = target2[key];
if (!value || staticTypes.includes(typeof value) || typeof key === "symbol" || isNaN(key))
return value;
return observeProperty(value, proxy, key, label, update);
},
set(target2, key, value) {
if (typeof key !== "symbol" && !isNaN(key) && target2[key] !== value)
update();
return Reflect.set(target2, key, value);
}
});
}
function observeDate(target, update) {
for (const method of Object.getOwnPropertyNames(Date.prototype)) {
if (method === "valueOf")
continue;
defineProperty(target, method, function(...args) {
const oldValue = target.valueOf();
const result = Date.prototype[method].apply(this, args);
if (target.valueOf() !== oldValue)
update();
return result;
});
}
return target;
}
function observe(target, ...args) {
if (staticTypes.includes(typeof target)) {
throw new Error(`cannot observe immutable type "${typeof target}"`);
} else if (!target) {
throw new Error("cannot observe null or undefined");
}
const type = Object.prototype.toString.call(target).slice(8, -1);
if (builtinClasses.includes(type)) {
throw new Error(`cannot observe instance of type "${type}"`);
}
let label = "", update = noop;
if (typeof args[0] === "function")
update = args.shift();
if (typeof args[0] === "string")
label = args[0];
const observer = observeObject(target, label, null);
defineProperty(observer, "_update", function _update() {
const diff = __spreadValues({}, this._diff);
const fields = Object.keys(diff);
if (fields.length) {
if (label)
logger.debug(`[update] ${label}: ${fields.join(", ")}`);
for (const key in this._diff) {
delete this._diff[key];
}
return update(diff);
}
});
defineProperty(observer, "_merge", function _merge(value) {
for (const key in value) {
if (key in this._diff) {
throw new Error(`unresolved diff key "${key}"`);
}
target[key] = value[key];
delete this["__proxyGetters__"][key];
}
return this;
});
return observer;
}
// packages/koishi-utils/src/random.ts
var import_crypto = __toModule(require("crypto"));
var Random = class {
constructor(value = Math.random()) {
this.value = value;
}
bool(probability) {
if (probability >= 1)
return true;
if (probability <= 0)
return false;
return this.value < probability;
}
real(...args) {
const start = args.length > 1 ? args[0] : 0;
const end = args[args.length - 1];
return this.value * (end - start) + start;
}
int(...args) {
return Math.floor(this.real(...args));
}
pick(source) {
return source[Math.floor(this.value * source.length)];
}
splice(source) {
return source.splice(Math.floor(this.value * source.length), 1)[0];
}
weightedPick(weights) {
const total = Object.entries(weights).reduce((prev, [, curr]) => prev + curr, 0);
const pointer = this.value * total;
let counter = 0;
for (const key in weights) {
counter += weights[key];
if (pointer < counter)
return key;
}
}
};
var hex = [];
for (let i = 0; i < 256; ++i) {
hex.push((i + 256).toString(16).substr(1));
}
(function(Random2) {
function uuid() {
const arr = (0, import_crypto.randomFillSync)(new Uint8Array(16));
arr[6] = arr[6] & 15 | 64;
arr[8] = arr[8] & 63 | 128;
return hex[arr[0]] + hex[arr[1]] + hex[arr[2]] + hex[arr[3]] + "-" + hex[arr[4]] + hex[arr[5]] + "-" + hex[arr[6]] + hex[arr[7]] + "-" + hex[arr[8]] + hex[arr[9]] + "-" + hex[arr[10]] + hex[arr[11]] + hex[arr[12]] + hex[arr[13]] + hex[arr[14]] + hex[arr[15]];
}
Random2.uuid = uuid;
function digits(length) {
let result = "";
for (let i = 0; i < length; ++i) {
result += Math.floor(Math.random() * 10);
}
return result;
}
Random2.digits = digits;
function real(...args) {
return new Random2().real(...args);
}
Random2.real = real;
function int(...args) {
return new Random2().int(...args);
}
Random2.int = int;
function pick2(source) {
return new Random2().pick(source);
}
Random2.pick = pick2;
function shuffle(source) {
const clone2 = source.slice();
const result = [];
for (let i = source.length; i > 0; --i) {
result.push(new Random2().splice(clone2));
}
return result;
}
Random2.shuffle = shuffle;
function multiPick(source, count) {
source = source.slice();
const result = [];
const length = Math.min(source.length, count);
for (let i = 0; i < length; i += 1) {
const index = Math.floor(Math.random() * source.length);
const [item] = source.splice(index, 1);
result.push(item);
}
return result;
}
Random2.multiPick = multiPick;
function weightedPick(weights) {
return new Random2().weightedPick(weights);
}
Random2.weightedPick = weightedPick;
function bool(probability) {
return new Random2().bool(probability);
}
Random2.bool = bool;
})(Random || (Random = {}));
// packages/koishi-utils/src/segment.ts
var import_util4 = __toModule(require("util"));
function segment(type, data = {}) {
if (type === "text")
return segment.escape(String(data.content));
let output = "[CQ:" + type;
for (const key in data) {
if (data[key])
output += `,${key}=${segment.escape(data[key], true)}`;
}
return output + "]";
}
(function(segment2) {
function escape(source, inline = false) {
const result = String(source).replace(/&/g, "&").replace(/\[/g, "[").replace(/\]/g, "]");
return inline ? result.replace(/,/g, ",").replace(/(\ud83c[\udf00-\udfff])|(\ud83d[\udc00-\ude4f\ude80-\udeff])|[\u2600-\u2B55]/g, " ") : result;
}
segment2.escape = escape;
function unescape(source) {
return String(source).replace(/[/g, "[").replace(/]/g, "]").replace(/,/g, ",").replace(/&/g, "&");
}
segment2.unescape = unescape;
function join(chain) {
return chain.map((node) => segment2(node.type, node.data)).join("");
}
segment2.join = join;
function from(source, options = {}) {
let regExpSource = `\\[CQ:(${options.type || "\\w+"})((,\\w+=[^,\\]]*)*)\\]`;
if (options.caret)
regExpSource = "^" + regExpSource;
const capture = new RegExp(regExpSource).exec(source);
if (!capture)
return null;
const [, type, attrs] = capture;
const data = {};
attrs && attrs.slice(1).split(",").forEach((str) => {
const index = str.indexOf("=");
data[str.slice(0, index)] = unescape(str.slice(index + 1));
});
return { type, data, capture };
}
segment2.from = from;
function parse(source) {
const chain = [];
let result;
while (result = from(source)) {
const { capture } = result;
if (capture.index) {
chain.push({ type: "text", data: { content: unescape(source.slice(0, capture.index)) } });
}
chain.push(result);
source = source.slice(capture.index + capture[0].length);
}
if (source)
chain.push({ type: "text", data: { content: unescape(source) } });
return chain;
}
segment2.parse = parse;
function transform(source, rules, dropOthers = false) {
return parse(source).map(({ type, data, capture }, index, chain) => {
const transformer = rules[type];
return typeof transformer === "string" ? transformer : typeof transformer === "function" ? transformer(data, index, chain) : dropOthers ? "" : type === "text" ? escape(data.content) : capture[0];
}).join("");
}
segment2.transform = transform;
async function transformAsync(source, rules) {
const chain = segment2.parse(source);
const cache = new Map();
await Promise.all(chain.map(async (node, index, chain2) => {
const transformer = rules[node.type];
if (!transformer)
return;
cache.set(node, typeof transformer === "string" ? transformer : await transformer(node.data, index, chain2));
}));
return chain.map((node) => cache.get(node) || segment2(node.type, node.data)).join("");
}
segment2.transformAsync = transformAsync;
function createFactory(type, key) {
return (value, data = {}) => segment2(type, __spreadProps(__spreadValues({}, data), { [key]: value }));
}
function createAssetFactory(type) {
return (value, data = {}) => {
if (Buffer.isBuffer(value)) {
value = "base64://" + value.toString("base64");
} else if (import_util4.types.isArrayBuffer(value)) {
value = "base64://" + Buffer.from(value).toString("base64");
}
return segment2(type, __spreadProps(__spreadValues({}, data), { url: value }));
};
}
segment2.at = createFactory("at", "id");
segment2.sharp = createFactory("sharp", "id");
segment2.quote = createFactory("quote", "id");
segment2.image = createAssetFactory("image");
segment2.video = createAssetFactory("video");
segment2.audio = createAssetFactory("audio");
segment2.file = createAssetFactory("file");
})(segment || (segment = {}));
// packages/koishi-utils/src/set.ts
function contain(array1, array2) {
return array2.every((item) => array1.includes(item));
}
function intersection(array1, array2) {
return array1.filter((item) => array2.includes(item));
}
function difference(array1, array2) {
return array1.filter((item) => !array2.includes(item));
}
function union(array1, array2) {
return Array.from(new Set([...array1, ...array2]));
}
function deduplicate(array) {
return [...new Set(array)];
}
function remove(list, item) {
const index = list.indexOf(item);
if (index >= 0) {
list.splice(index, 1);
return true;
}
}
// packages/koishi-utils/src/string.ts
function deepen(modifyString) {
function modifyObject(source) {
if (typeof source !== "object" || !source)
return source;
if (Array.isArray(source))
return source.map(modifyObject);
const result = {};
for (const key in source) {
result[modifyString(key)] = modifyObject(source[key]);
}
return result;
}
return function(source) {
if (typeof source === "string") {
return modifyString(source);
} else {
return modifyObject(source);
}
};
}
var camelCase = deepen((source) => source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase()));
var paramCase = deepen((source) => source.replace(/_/g, "-").replace(/(?<!^)[A-Z]/g, (str) => "-" + str.toLowerCase()));
var snakeCase = deepen((source) => source.replace(/-/g, "_").replace(/(?<!^)[A-Z]/g, (str) => "_" + str.toLowerCase()));
var camelize = camelCase;
var hyphenate = paramCase;
function capitalize(source) {
return source.charAt(0).toUpperCase() + source.slice(1);
}
var interpolate = new Function("template", "context", `
return template.replace(/\\{\\{[\\s\\S]+?\\}\\}/g, (sub) => {
const expr = sub.substring(2, sub.length - 2)
try {
with (context) {
return eval(expr)
}
} catch {
return ''
}
})
`);
function escapeRegExp(source) {
return source.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
}
function trimSlash(source) {
return source.replace(/\/$/, "");
}
function sanitize(source) {
if (!source.startsWith("/"))
source = "/" + source;
return trimSlash(source);
}
function template(path, ...params) {
if (!Array.isArray(path))
path = [path];
for (const item of path) {
const source = template.get(item);
if (typeof source === "string") {
return template.format(source, ...params);
}
}
return path[0];
}
function deepAssign(head, base) {
Object.entries(base).forEach(([key, value]) => {
if (typeof value === "object" && typeof head[key] === "object") {
head[key] = deepAssign(head[key], value);
} else {
head[key] = base[key];
}
});
return head;
}
(function(template2) {
const store = {};
function set(path, value) {
var _a;
const seg = path.split(".");
let node = store;
while (seg.length > 1) {
node = node[_a = seg.shift()] || (node[_a] = {});
}
deepAssign(node, { [seg[0]]: value });
}
template2.set = set;
function get(path) {
const seg = path.split(".");
let node = store;
do {
node = node[seg.shift()];
} while (seg.length && node);
if (typeof node === "string")
return node;
}
template2.get = get;
function format2(source, ...params) {
if (params[0] && typeof params[0] === "object") {
source = interpolate(source, params[0]);
}
let result = "";
let cap;
while (cap = /\{(\w+)\}/.exec(source)) {
result += source.slice(0, cap.index) + (cap[1] in params ? params[cap[1]] : "");
source = source.slice(cap.index + cap[0].length);
}
return result + source;
}
template2.format = format2;
function quote(content) {
return get("basic.left-quote") + content + get("basic.right-quote");
}
template2.quote = quote;
function brace(items) {
if (!items.length)
return "";
return get("basic.left-brace") + items.join(get("basic.comma")) + get("basic.right-brace");
}
template2.brace = brace;
})(template || (template = {}));
template.set("basic", {
"left-brace": "(",
"right-brace": ")",
"left-quote": "“",
"right-quote": "”",
"comma": ",",
"and": "和",
"or": "或"
});
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Logger,
Random,
Time,
assertProperty,
camelCase,
camelize,
capitalize,
clone,
coerce,
contain,
deduplicate,
defineEnumProperty,
defineProperty,
difference,
enumKeys,
escapeRegExp,
hyphenate,
interpolate,
intersection,
isInteger,
makeArray,
merge,
noop,
observe,
omit,
paramCase,
pick,
remove,
renameProperty,
s,
sanitize,
segment,
simplify,
sleep,
snakeCase,
t,
template,
traditionalize,
trimSlash,
union
});
//# sourceMappingURL=index.js.map