tgsnake
Version:
Telegram MTProto framework for nodejs.
218 lines (217 loc) • 7.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Composer = exports.leaf = void 0;
exports.concat = concat;
exports.pass = pass;
exports.triggerFn = triggerFn;
exports.match = match;
exports.toArray = toArray;
exports.run = run;
const Filters_js_1 = require("./Filters.js");
function flatten(mw) {
return typeof mw === 'function' ? mw : (ctx, next) => mw.middleware()(ctx, next);
}
function concat(first, andThen) {
return async (ctx, next) => {
let nextCalled = false;
await first(ctx, async () => {
if (nextCalled)
throw new Error('`next` already called before!');
else
nextCalled = true;
await andThen(ctx, next);
});
};
}
function pass(_ctx, next) {
return next();
}
const leaf = () => Promise.resolve();
exports.leaf = leaf;
function triggerFn(trigger) {
return toArray(trigger).map((t) => typeof t === 'string' ? (txt) => (txt === t ? t : null) : (txt) => t.exec(txt));
}
function match(content, triggers) {
const match = [];
for (const t of triggers) {
const res = t(content);
if (res) {
match.push(t);
}
}
return Boolean(match.length);
}
function toArray(e) {
return Array.isArray(e) ? e : [e];
}
async function run(middleware, ctx) {
await middleware(ctx, exports.leaf);
}
class Composer {
handler;
context = {};
prefix = '.!/';
constructor(...middleware) {
this.handler = middleware.length === 0 ? pass : middleware.map(flatten).reduce(concat);
}
middleware() {
return this.handler;
}
use(...middleware) {
const composer = new Composer(...middleware);
this.handler = concat(this.handler, flatten(composer));
return composer;
}
on(filters, ...middleware) {
return this.filter((ctx) => (0, Filters_js_1.filter)(filters, ctx), ...middleware);
}
filter(predicate, ...middleware) {
const composer = new Composer(...middleware);
this.branch(predicate, composer, pass);
return composer;
}
drop(predicate, ...middleware) {
return this.filter(async (ctx) => !(await predicate(ctx)), ...middleware);
}
fork(...middleware) {
const composer = new Composer(...middleware);
const fork = flatten(composer);
this.use((ctx, next) => Promise.all([next(), run(fork, ctx)]));
return composer;
}
lazy(middlewareFactory) {
return this.use(async (context, next) => {
const middleware = await middlewareFactory(context);
const arr = toArray(middleware);
await flatten(new Composer(...arr))(Object.assign(context, this.context), next);
});
}
route(router, routeHandlers, fallback = pass) {
return this.lazy(async (ctx) => {
let _a;
const route = await router(ctx);
return route === undefined
? []
: (_a = routeHandlers[route]) !== null && _a !== void 0
? _a
: fallback;
});
}
branch(predicate, trueMiddleware, falseMiddleware) {
return this.lazy(async (ctx) => ((await predicate(ctx)) ? trueMiddleware : falseMiddleware));
}
[Symbol.for('nodejs.util.inspect.custom')]() {
const toPrint = {
_: this.constructor.name,
};
for (const key in this) {
if (this.hasOwnProperty(key)) {
const value = this[key];
if (!key.startsWith('_')) {
toPrint[key] = value;
}
}
}
return toPrint;
}
toJSON() {
const toPrint = {
_: this.constructor.name,
};
for (const key in this) {
if (this.hasOwnProperty(key)) {
const value = this[key];
if (!key.startsWith('_')) {
toPrint[key] = typeof value === 'bigint' ? String(value) : value;
}
}
}
return toPrint;
}
toString() {
return `[constructor of ${this.constructor.name}] ${JSON.stringify(this, null, 2)}`;
}
command(trigger, ...middleware) {
const key = toArray(trigger);
const filterCmd = (ctx) => {
const text = ctx.editedMessage ? ctx.editedMessage.text : ctx.message.text;
const { _me } = ctx;
const s = text.split(' ');
const passed = [];
for (const cmd of key) {
if (typeof cmd == 'string') {
cmd;
const r = new RegExp(`^[${this.prefix}](${cmd})${_me?.username ? `(@${_me?.username})?` : ``}$`, 'i');
if (r.test(String(s[0]))) {
passed.push(r.exec(String(s[0])));
}
}
if (cmd instanceof RegExp) {
cmd;
if (cmd.test(String(s[0]))) {
passed.push(cmd.exec(String(s[0])));
}
}
}
ctx.match = passed;
return Boolean(passed.length);
};
return this.on('msg.text').filter(filterCmd, ...middleware);
}
cmd(trigger, ...middleware) {
return this.command(trigger, ...middleware);
}
hears(trigger, ...middleware) {
const tgr = triggerFn(trigger);
return this.on('msg.text').filter((ctx) => {
const text = ctx.editedMessage ? ctx.editedMessage.text : ctx.message.text;
return match(String(text), tgr);
}, ...middleware);
}
hear(trigger, ...middleware) {
return this.hears(trigger, ...middleware);
}
action(trigger, ...middleware) {
const key = toArray(trigger);
const filterCmd = (ctx) => {
const { data } = ctx.callbackQuery;
const passed = [];
for (const cmd of key) {
if (typeof cmd == 'string') {
cmd;
if (cmd == data)
passed.push(cmd);
}
if (cmd instanceof RegExp) {
cmd;
if (cmd.test(String(data)))
passed.push(cmd);
}
}
return Boolean(passed.length);
};
return this.on('cb.data').filter(filterCmd, ...middleware);
}
inlineQuery(trigger, ...middleware) {
const key = toArray(trigger);
const filterCmd = (ctx) => {
const { query } = ctx.inlineQuery;
const passed = [];
for (const cmd of key) {
if (typeof cmd == 'string') {
cmd;
if (cmd == query)
passed.push(cmd);
}
if (cmd instanceof RegExp) {
cmd;
if (cmd.test(String(query)))
passed.push(cmd);
}
}
return Boolean(passed.length);
};
return this.on('inlineQuery.from').filter(filterCmd, ...middleware);
}
}
exports.Composer = Composer;