@xbibzlibrary/telebibz 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/APPROVAL_FEATURE.md +73 -0
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +171 -0
- package/SECURITY.md +15 -0
- package/bin/telebibz.mjs +3 -0
- package/dist/generated/api.d.ts +13 -0
- package/dist/generated/api.d.ts.map +1 -0
- package/dist/generated/api.js +192 -0
- package/dist/generated/api.js.map +1 -0
- package/dist/src/api/client.d.ts +32 -0
- package/dist/src/api/client.d.ts.map +1 -0
- package/dist/src/api/client.js +50 -0
- package/dist/src/api/client.js.map +1 -0
- package/dist/src/api/errors.d.ts +45 -0
- package/dist/src/api/errors.d.ts.map +1 -0
- package/dist/src/api/errors.js +65 -0
- package/dist/src/api/errors.js.map +1 -0
- package/dist/src/api/index.d.ts +5 -0
- package/dist/src/api/index.d.ts.map +1 -0
- package/dist/src/api/index.js +5 -0
- package/dist/src/api/index.js.map +1 -0
- package/dist/src/api/transport.d.ts +37 -0
- package/dist/src/api/transport.d.ts.map +1 -0
- package/dist/src/api/transport.js +134 -0
- package/dist/src/api/transport.js.map +1 -0
- package/dist/src/api/types.d.ts +441 -0
- package/dist/src/api/types.d.ts.map +1 -0
- package/dist/src/api/types.js +2 -0
- package/dist/src/api/types.js.map +1 -0
- package/dist/src/approval/approval.d.ts +63 -0
- package/dist/src/approval/approval.d.ts.map +1 -0
- package/dist/src/approval/approval.js +90 -0
- package/dist/src/approval/approval.js.map +1 -0
- package/dist/src/cache/cache.d.ts +33 -0
- package/dist/src/cache/cache.d.ts.map +1 -0
- package/dist/src/cache/cache.js +37 -0
- package/dist/src/cache/cache.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +55 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/context/context.d.ts +46 -0
- package/dist/src/context/context.d.ts.map +1 -0
- package/dist/src/context/context.js +63 -0
- package/dist/src/context/context.js.map +1 -0
- package/dist/src/core/bot.d.ts +76 -0
- package/dist/src/core/bot.d.ts.map +1 -0
- package/dist/src/core/bot.js +160 -0
- package/dist/src/core/bot.js.map +1 -0
- package/dist/src/core/events.d.ts +71 -0
- package/dist/src/core/events.d.ts.map +1 -0
- package/dist/src/core/events.js +24 -0
- package/dist/src/core/events.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/keyboard/index.d.ts +34 -0
- package/dist/src/keyboard/index.d.ts.map +1 -0
- package/dist/src/keyboard/index.js +43 -0
- package/dist/src/keyboard/index.js.map +1 -0
- package/dist/src/middleware/compose.d.ts +5 -0
- package/dist/src/middleware/compose.d.ts.map +1 -0
- package/dist/src/middleware/compose.js +17 -0
- package/dist/src/middleware/compose.js.map +1 -0
- package/dist/src/plugins/plugin.d.ts +36 -0
- package/dist/src/plugins/plugin.d.ts.map +1 -0
- package/dist/src/plugins/plugin.js +31 -0
- package/dist/src/plugins/plugin.js.map +1 -0
- package/dist/src/queue/queue.d.ts +52 -0
- package/dist/src/queue/queue.d.ts.map +1 -0
- package/dist/src/queue/queue.js +82 -0
- package/dist/src/queue/queue.js.map +1 -0
- package/dist/src/router/router.d.ts +35 -0
- package/dist/src/router/router.d.ts.map +1 -0
- package/dist/src/router/router.js +23 -0
- package/dist/src/router/router.js.map +1 -0
- package/dist/src/state/conversation.d.ts +40 -0
- package/dist/src/state/conversation.d.ts.map +1 -0
- package/dist/src/state/conversation.js +38 -0
- package/dist/src/state/conversation.js.map +1 -0
- package/dist/src/state/forms.d.ts +35 -0
- package/dist/src/state/forms.d.ts.map +1 -0
- package/dist/src/state/forms.js +41 -0
- package/dist/src/state/forms.js.map +1 -0
- package/dist/src/state/menu.d.ts +30 -0
- package/dist/src/state/menu.d.ts.map +1 -0
- package/dist/src/state/menu.js +28 -0
- package/dist/src/state/menu.js.map +1 -0
- package/dist/src/storage/storage.d.ts +33 -0
- package/dist/src/storage/storage.d.ts.map +1 -0
- package/dist/src/storage/storage.js +51 -0
- package/dist/src/storage/storage.js.map +1 -0
- package/dist/src/testing.d.ts +17 -0
- package/dist/src/testing.d.ts.map +1 -0
- package/dist/src/testing.js +12 -0
- package/dist/src/testing.js.map +1 -0
- package/dist/src/utils/text.d.ts +17 -0
- package/dist/src/utils/text.d.ts.map +1 -0
- package/dist/src/utils/text.js +0 -0
- package/dist/src/utils/text.js.map +1 -0
- package/dist/src/webhook/handler.d.ts +8 -0
- package/dist/src/webhook/handler.d.ts.map +1 -0
- package/dist/src/webhook/handler.js +27 -0
- package/dist/src/webhook/handler.js.map +1 -0
- package/dist-cjs/generated/api.js +194 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/src/api/client.js +53 -0
- package/dist-cjs/src/api/errors.js +74 -0
- package/dist-cjs/src/api/index.js +20 -0
- package/dist-cjs/src/api/transport.js +137 -0
- package/dist-cjs/src/api/types.js +2 -0
- package/dist-cjs/src/approval/approval.js +94 -0
- package/dist-cjs/src/cache/cache.js +41 -0
- package/dist-cjs/src/cli.js +57 -0
- package/dist-cjs/src/context/context.js +66 -0
- package/dist-cjs/src/core/bot.js +163 -0
- package/dist-cjs/src/core/events.js +27 -0
- package/dist-cjs/src/index.js +33 -0
- package/dist-cjs/src/keyboard/index.js +49 -0
- package/dist-cjs/src/middleware/compose.js +20 -0
- package/dist-cjs/src/plugins/plugin.js +35 -0
- package/dist-cjs/src/queue/queue.js +86 -0
- package/dist-cjs/src/router/router.js +26 -0
- package/dist-cjs/src/state/conversation.js +43 -0
- package/dist-cjs/src/state/forms.js +44 -0
- package/dist-cjs/src/state/menu.js +33 -0
- package/dist-cjs/src/storage/storage.js +54 -0
- package/dist-cjs/src/testing.js +18 -0
- package/dist-cjs/src/utils/text.js +0 -0
- package/dist-cjs/src/webhook/handler.js +29 -0
- package/docs/README.md +21 -0
- package/package.json +78 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "./core/bot.js";
|
|
2
|
+
export * from "./core/events.js";
|
|
3
|
+
export * from "./api/index.js";
|
|
4
|
+
export * from "./context/context.js";
|
|
5
|
+
export * from "./middleware/compose.js";
|
|
6
|
+
export * from "./router/router.js";
|
|
7
|
+
export * from "./keyboard/index.js";
|
|
8
|
+
export * from "./storage/storage.js";
|
|
9
|
+
export * from "./cache/cache.js";
|
|
10
|
+
export * from "./queue/queue.js";
|
|
11
|
+
export * from "./plugins/plugin.js";
|
|
12
|
+
export * from "./webhook/handler.js";
|
|
13
|
+
export * from "./utils/text.js";
|
|
14
|
+
export * from "./state/conversation.js";
|
|
15
|
+
export * from "./state/forms.js";
|
|
16
|
+
export * from "./state/menu.js";
|
|
17
|
+
export * from "./approval/approval.js";
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "./core/bot.js";
|
|
2
|
+
export * from "./core/events.js";
|
|
3
|
+
export * from "./api/index.js";
|
|
4
|
+
export * from "./context/context.js";
|
|
5
|
+
export * from "./middleware/compose.js";
|
|
6
|
+
export * from "./router/router.js";
|
|
7
|
+
export * from "./keyboard/index.js";
|
|
8
|
+
export * from "./storage/storage.js";
|
|
9
|
+
export * from "./cache/cache.js";
|
|
10
|
+
export * from "./queue/queue.js";
|
|
11
|
+
export * from "./plugins/plugin.js";
|
|
12
|
+
export * from "./webhook/handler.js";
|
|
13
|
+
export * from "./utils/text.js";
|
|
14
|
+
export * from "./state/conversation.js";
|
|
15
|
+
export * from "./state/forms.js";
|
|
16
|
+
export * from "./state/menu.js";
|
|
17
|
+
export * from "./approval/approval.js";
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyMarkup } from "../api/types.js";
|
|
2
|
+
export declare class InlineKeyboard {
|
|
3
|
+
private readonly rows;
|
|
4
|
+
static from(rows: InlineKeyboardButton[][]): InlineKeyboard;
|
|
5
|
+
text(text: string, callbackData: string): this;
|
|
6
|
+
url(text: string, url: string): this;
|
|
7
|
+
webApp(text: string, url: string): this;
|
|
8
|
+
pay(text?: string): this;
|
|
9
|
+
copy(text: string, copiedText: string): this;
|
|
10
|
+
button(button: InlineKeyboardButton): this;
|
|
11
|
+
row(...buttons: InlineKeyboardButton[]): this;
|
|
12
|
+
conditional(condition: boolean, factory: (keyboard: this) => this): this;
|
|
13
|
+
grid(buttons: InlineKeyboardButton[], columns: number): this;
|
|
14
|
+
build(): InlineKeyboardMarkup;
|
|
15
|
+
asReplyMarkup(): InlineKeyboardMarkup;
|
|
16
|
+
private ensureRow;
|
|
17
|
+
}
|
|
18
|
+
export declare class ReplyKeyboard {
|
|
19
|
+
private readonly rows;
|
|
20
|
+
text(text: string): this;
|
|
21
|
+
contact(text: string): this;
|
|
22
|
+
location(text: string): this;
|
|
23
|
+
poll(text: string, type?: "quiz" | "regular"): this;
|
|
24
|
+
webApp(text: string, url: string): this;
|
|
25
|
+
button(button: KeyboardButton): this;
|
|
26
|
+
row(...buttons: KeyboardButton[]): this;
|
|
27
|
+
grid(buttons: KeyboardButton[], columns: number): this;
|
|
28
|
+
build(options?: Omit<ReplyKeyboardMarkup, "keyboard">): ReplyKeyboardMarkup;
|
|
29
|
+
asReplyMarkup(): ReplyKeyboardMarkup;
|
|
30
|
+
private ensureRow;
|
|
31
|
+
}
|
|
32
|
+
export declare function removeKeyboard(selective?: boolean): ReplyMarkup;
|
|
33
|
+
export declare function forceReply(placeholder?: string, selective?: boolean): ReplyMarkup;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/keyboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEpI,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IACrD,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,EAAE,EAAE,GAAG,cAAc;IAC3D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAC9C,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IACpC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IACvC,GAAG,CAAC,IAAI,SAAQ,GAAG,IAAI;IACvB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAC5C,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAC1C,GAAG,CAAC,GAAG,OAAO,EAAE,oBAAoB,EAAE,GAAG,IAAI;IAC7C,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IACxE,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAC5D,KAAK,IAAI,oBAAoB;IAC7B,aAAa,IAAI,oBAAoB;IACrC,OAAO,CAAC,SAAS;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IACnD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IACvC,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IACpC,GAAG,CAAC,GAAG,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IACvC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IACtD,KAAK,CAAC,OAAO,GAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAM,GAAG,mBAAmB;IAC/E,aAAa,IAAI,mBAAmB;IACpC,OAAO,CAAC,SAAS;CAClB;AAED,wBAAgB,cAAc,CAAC,SAAS,UAAQ,GAAG,WAAW,CAAiF;AAC/I,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,WAAW,CAA+I"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class InlineKeyboard {
|
|
2
|
+
rows = [];
|
|
3
|
+
static from(rows) { const keyboard = new InlineKeyboard(); keyboard.rows.push(...rows.map((row) => [...row])); return keyboard; }
|
|
4
|
+
text(text, callbackData) { return this.button({ text, callback_data: callbackData }); }
|
|
5
|
+
url(text, url) { return this.button({ text, url }); }
|
|
6
|
+
webApp(text, url) { return this.button({ text, web_app: { url } }); }
|
|
7
|
+
pay(text = "Pay") { return this.button({ text, pay: true }); }
|
|
8
|
+
copy(text, copiedText) { return this.button({ text, copy_text: { text: copiedText } }); }
|
|
9
|
+
button(button) { this.ensureRow().push(validateInlineButton(button)); return this; }
|
|
10
|
+
row(...buttons) { this.rows.push(buttons.map(validateInlineButton)); return this; }
|
|
11
|
+
conditional(condition, factory) { return condition ? factory(this) : this; }
|
|
12
|
+
grid(buttons, columns) { if (!Number.isInteger(columns) || columns < 1)
|
|
13
|
+
throw new RangeError("columns must be a positive integer"); for (let index = 0; index < buttons.length; index += columns)
|
|
14
|
+
this.rows.push(buttons.slice(index, index + columns).map(validateInlineButton)); return this; }
|
|
15
|
+
build() { return { inline_keyboard: this.rows.map((row) => [...row]) }; }
|
|
16
|
+
asReplyMarkup() { return this.build(); }
|
|
17
|
+
ensureRow() { const row = this.rows.at(-1); if (row)
|
|
18
|
+
return row; const next = []; this.rows.push(next); return next; }
|
|
19
|
+
}
|
|
20
|
+
export class ReplyKeyboard {
|
|
21
|
+
rows = [];
|
|
22
|
+
text(text) { return this.button({ text }); }
|
|
23
|
+
contact(text) { return this.button({ text, request_contact: true }); }
|
|
24
|
+
location(text) { return this.button({ text, request_location: true }); }
|
|
25
|
+
poll(text, type) { return this.button({ text, request_poll: type ? { type } : {} }); }
|
|
26
|
+
webApp(text, url) { return this.button({ text, web_app: { url } }); }
|
|
27
|
+
button(button) { this.ensureRow().push(button); return this; }
|
|
28
|
+
row(...buttons) { this.rows.push([...buttons]); return this; }
|
|
29
|
+
grid(buttons, columns) { if (!Number.isInteger(columns) || columns < 1)
|
|
30
|
+
throw new RangeError("columns must be a positive integer"); for (let index = 0; index < buttons.length; index += columns)
|
|
31
|
+
this.rows.push(buttons.slice(index, index + columns)); return this; }
|
|
32
|
+
build(options = {}) { return { keyboard: this.rows.map((row) => [...row]), ...options }; }
|
|
33
|
+
asReplyMarkup() { return this.build(); }
|
|
34
|
+
ensureRow() { const row = this.rows.at(-1); if (row)
|
|
35
|
+
return row; const next = []; this.rows.push(next); return next; }
|
|
36
|
+
}
|
|
37
|
+
export function removeKeyboard(selective = false) { return { remove_keyboard: true, ...(selective ? { selective: true } : {}) }; }
|
|
38
|
+
export function forceReply(placeholder, selective = false) { return { force_reply: true, ...(placeholder ? { input_field_placeholder: placeholder } : {}), ...(selective ? { selective: true } : {}) }; }
|
|
39
|
+
function validateInlineButton(button) { if (!button.text)
|
|
40
|
+
throw new Error("Inline keyboard button text is required."); const actions = [button.url, button.callback_data, button.web_app, button.login_url, button.switch_inline_query, button.switch_inline_query_current_chat, button.callback_game, button.pay, button.copy_text].filter((value) => value !== undefined); if (actions.length !== 1)
|
|
41
|
+
throw new Error(`Inline button ${button.text} must contain exactly one action.`); if (button.callback_data && new TextEncoder().encode(button.callback_data).length > 64)
|
|
42
|
+
throw new RangeError("callback_data must be at most 64 bytes."); return { ...button }; }
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/keyboard/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type Next = () => Promise<void>;
|
|
2
|
+
export type Middleware<Context> = (ctx: Context, next: Next) => void | Promise<void>;
|
|
3
|
+
export declare function compose<Context>(middleware: readonly Middleware<Context>[]): (ctx: Context) => Promise<void>;
|
|
4
|
+
export declare function middleware<Context>(handler: Middleware<Context>): Middleware<Context>;
|
|
5
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../../src/middleware/compose.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AACvC,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErF,wBAAgB,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAY5G;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,CAAoB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function compose(middleware) {
|
|
2
|
+
return async function run(ctx) {
|
|
3
|
+
let index = -1;
|
|
4
|
+
const dispatch = async (position) => {
|
|
5
|
+
if (position <= index)
|
|
6
|
+
throw new Error("next() called multiple times");
|
|
7
|
+
index = position;
|
|
8
|
+
const handler = middleware[position];
|
|
9
|
+
if (!handler)
|
|
10
|
+
return;
|
|
11
|
+
await handler(ctx, () => dispatch(position + 1));
|
|
12
|
+
};
|
|
13
|
+
await dispatch(0);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function middleware(handler) { return handler; }
|
|
17
|
+
//# sourceMappingURL=compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../../../src/middleware/compose.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,OAAO,CAAU,UAA0C;IACzE,OAAO,KAAK,UAAU,GAAG,CAAC,GAAY;QACpC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QACf,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAgB,EAAiB,EAAE;YACzD,IAAI,QAAQ,IAAI,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;YACvE,KAAK,GAAG,QAAQ,CAAC;YACjB,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC,CAAC;QACF,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAU,OAA4B,IAAyB,OAAO,OAAO,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface Plugin<Context = unknown> {
|
|
2
|
+
name: string;
|
|
3
|
+
version?: string;
|
|
4
|
+
install?: (api: PluginApi<Context>) => void | Promise<void>;
|
|
5
|
+
setup?: (api: PluginApi<Context>) => void | Promise<void>;
|
|
6
|
+
onStart?: (api: PluginApi<Context>) => void | Promise<void>;
|
|
7
|
+
onUpdate?: (context: Context) => void | Promise<void>;
|
|
8
|
+
onStop?: (api: PluginApi<Context>) => void | Promise<void>;
|
|
9
|
+
dispose?: (api: PluginApi<Context>) => void | Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export interface PluginApi<Context> {
|
|
12
|
+
bot: unknown;
|
|
13
|
+
services: ServiceContainer;
|
|
14
|
+
registerMiddleware: (middleware: unknown) => void;
|
|
15
|
+
registerRoute: (route: unknown) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare class ServiceContainer {
|
|
18
|
+
private readonly values;
|
|
19
|
+
register<T>(name: string | symbol, value: T): this;
|
|
20
|
+
get<T>(name: string | symbol): T;
|
|
21
|
+
has(name: string | symbol): boolean;
|
|
22
|
+
delete(name: string | symbol): boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare class PluginManager<Context> {
|
|
25
|
+
private readonly plugins;
|
|
26
|
+
private readonly api;
|
|
27
|
+
constructor(bot: unknown);
|
|
28
|
+
use(plugin: Plugin<Context>): this;
|
|
29
|
+
setup(): Promise<void>;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
update(context: Context): Promise<void>;
|
|
32
|
+
stop(): Promise<void>;
|
|
33
|
+
dispose(): Promise<void>;
|
|
34
|
+
list(): readonly Plugin<Context>[];
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM,CAAC,OAAO,GAAG,OAAO;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,SAAS,CAAC,OAAO;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,kBAAkB,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACzC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAClD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC;IAChC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IACnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;CACvC;AAED,qBAAa,aAAa,CAAC,OAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAC7B,GAAG,EAAE,OAAO;IAGxB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IACtB,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IACvC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,IAAI,IAAI,SAAS,MAAM,CAAC,OAAO,CAAC,EAAE;CACnC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class ServiceContainer {
|
|
2
|
+
values = new Map();
|
|
3
|
+
register(name, value) { this.values.set(name, value); return this; }
|
|
4
|
+
get(name) { if (!this.values.has(name))
|
|
5
|
+
throw new Error(`Service not registered: ${String(name)}`); return this.values.get(name); }
|
|
6
|
+
has(name) { return this.values.has(name); }
|
|
7
|
+
delete(name) { return this.values.delete(name); }
|
|
8
|
+
}
|
|
9
|
+
export class PluginManager {
|
|
10
|
+
plugins = [];
|
|
11
|
+
api;
|
|
12
|
+
constructor(bot) {
|
|
13
|
+
this.api = { bot, services: new ServiceContainer(), registerMiddleware: () => undefined, registerRoute: () => undefined };
|
|
14
|
+
}
|
|
15
|
+
use(plugin) { if (this.plugins.some((existing) => existing.name === plugin.name))
|
|
16
|
+
throw new Error(`Plugin already registered: ${plugin.name}`); this.plugins.push(plugin); return this; }
|
|
17
|
+
async setup() { for (const plugin of this.plugins) {
|
|
18
|
+
await plugin.install?.(this.api);
|
|
19
|
+
await plugin.setup?.(this.api);
|
|
20
|
+
} }
|
|
21
|
+
async start() { for (const plugin of this.plugins)
|
|
22
|
+
await plugin.onStart?.(this.api); }
|
|
23
|
+
async update(context) { for (const plugin of this.plugins)
|
|
24
|
+
await plugin.onUpdate?.(context); }
|
|
25
|
+
async stop() { for (const plugin of this.plugins)
|
|
26
|
+
await plugin.onStop?.(this.api); }
|
|
27
|
+
async dispose() { for (const plugin of [...this.plugins].reverse())
|
|
28
|
+
await plugin.dispose?.(this.api); }
|
|
29
|
+
list() { return this.plugins; }
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/plugins/plugin.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,gBAAgB;IACV,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC9D,QAAQ,CAAI,IAAqB,EAAE,KAAQ,IAAU,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IACjG,GAAG,CAAI,IAAqB,IAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAM,CAAC,CAAC,CAAC;IAC/J,GAAG,CAAC,IAAqB,IAAa,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,CAAC,IAAqB,IAAa,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CAC5E;AAED,MAAM,OAAO,aAAa;IACP,OAAO,GAAsB,EAAE,CAAC;IAChC,GAAG,CAAqB;IACzC,YAAY,GAAY;QACtB,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAC5H,CAAC;IACD,GAAG,CAAC,MAAuB,IAAU,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IAChN,KAAK,CAAC,KAAK,KAAoB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QAAC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC;IACzI,KAAK,CAAC,KAAK,KAAoB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrG,KAAK,CAAC,MAAM,CAAC,OAAgB,IAAmB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACtH,KAAK,CAAC,IAAI,KAAoB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO;QAAE,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACnG,KAAK,CAAC,OAAO,KAAoB,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE;QAAE,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtH,IAAI,KAAiC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;CAC5D"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface Job<T = unknown> {
|
|
2
|
+
id: string;
|
|
3
|
+
data: T;
|
|
4
|
+
attempts: number;
|
|
5
|
+
priority: number;
|
|
6
|
+
runAt: number;
|
|
7
|
+
status: "queued" | "running" | "completed" | "failed" | "cancelled";
|
|
8
|
+
error?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface QueueOptions {
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
retries?: number;
|
|
13
|
+
backoffMs?: number;
|
|
14
|
+
maxBackoffMs?: number;
|
|
15
|
+
}
|
|
16
|
+
type Worker<T> = (job: Job<T>, signal: AbortSignal) => Promise<void>;
|
|
17
|
+
export declare class TaskQueue<T = unknown> {
|
|
18
|
+
private readonly worker;
|
|
19
|
+
private readonly options;
|
|
20
|
+
private readonly pending;
|
|
21
|
+
private readonly jobs;
|
|
22
|
+
private readonly controllers;
|
|
23
|
+
private active;
|
|
24
|
+
private sequence;
|
|
25
|
+
private draining;
|
|
26
|
+
constructor(worker: Worker<T>, options?: QueueOptions);
|
|
27
|
+
add(data: T, options?: {
|
|
28
|
+
id?: string;
|
|
29
|
+
priority?: number;
|
|
30
|
+
delayMs?: number;
|
|
31
|
+
}): Job<T>;
|
|
32
|
+
get(id: string): Job<T> | undefined;
|
|
33
|
+
cancel(id: string): boolean;
|
|
34
|
+
onIdle(): Promise<void>;
|
|
35
|
+
close(): Promise<void>;
|
|
36
|
+
private drain;
|
|
37
|
+
private run;
|
|
38
|
+
}
|
|
39
|
+
export interface ScheduledJob {
|
|
40
|
+
id: string;
|
|
41
|
+
cancel: () => void;
|
|
42
|
+
}
|
|
43
|
+
export declare class Scheduler {
|
|
44
|
+
private readonly timers;
|
|
45
|
+
every(id: string, intervalMs: number, task: () => void | Promise<void>): ScheduledJob;
|
|
46
|
+
after(id: string, delayMs: number, task: () => void | Promise<void>): ScheduledJob;
|
|
47
|
+
cron(id: string, expression: string, task: () => void | Promise<void>): ScheduledJob;
|
|
48
|
+
cancel(id: string): boolean;
|
|
49
|
+
clear(): void;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/queue/queue.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,OAAO;IAAI,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE;AAClM,MAAM,WAAW,YAAY;IAAG,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE;AAEnH,KAAK,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACrE,qBAAa,SAAS,CAAC,CAAC,GAAG,OAAO;IAOpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAa,OAAO,CAAC,QAAQ,CAAC,OAAO;IANxE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAS;gBACI,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAmB,OAAO,GAAE,YAAiB;IAC3F,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,GAAG,CAAC,CAAC,CAAC;IACxF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS;IACnC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IACrB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YACd,KAAK;YACL,GAAG;CAClB;AAED,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE;AAChE,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqF;IAC5G,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY;IACrF,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY;IAClF,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,YAAY;IACpF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAC3B,KAAK,IAAI,IAAI;CACd"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export class TaskQueue {
|
|
2
|
+
worker;
|
|
3
|
+
options;
|
|
4
|
+
pending = [];
|
|
5
|
+
jobs = new Map();
|
|
6
|
+
controllers = new Map();
|
|
7
|
+
active = 0;
|
|
8
|
+
sequence = 0;
|
|
9
|
+
draining = false;
|
|
10
|
+
constructor(worker, options = {}) {
|
|
11
|
+
this.worker = worker;
|
|
12
|
+
this.options = options;
|
|
13
|
+
}
|
|
14
|
+
add(data, options = {}) { const id = options.id ?? `job_${Date.now()}_${this.sequence++}`; if (this.jobs.has(id))
|
|
15
|
+
throw new Error(`Job already exists: ${id}`); const job = { id, data, attempts: 0, priority: options.priority ?? 0, runAt: Date.now() + (options.delayMs ?? 0), status: "queued" }; this.jobs.set(id, job); this.pending.push(job); this.pending.sort((a, b) => b.priority - a.priority || a.runAt - b.runAt); void this.drain(); return { ...job }; }
|
|
16
|
+
get(id) { const job = this.jobs.get(id); return job ? { ...job } : undefined; }
|
|
17
|
+
cancel(id) { const job = this.jobs.get(id); if (!job || ["completed", "failed", "cancelled"].includes(job.status))
|
|
18
|
+
return false; job.status = "cancelled"; this.controllers.get(id)?.abort(); return true; }
|
|
19
|
+
async onIdle() { while (this.pending.length || this.active)
|
|
20
|
+
await new Promise((resolve) => setTimeout(resolve, 10)); }
|
|
21
|
+
async close() { this.draining = false; for (const id of this.controllers.keys())
|
|
22
|
+
this.cancel(id); }
|
|
23
|
+
async drain() { if (this.draining)
|
|
24
|
+
return; this.draining = true; try {
|
|
25
|
+
while (this.pending.length && this.active < (this.options.concurrency ?? 1)) {
|
|
26
|
+
const index = this.pending.findIndex((job) => job.runAt <= Date.now() && job.status === "queued");
|
|
27
|
+
if (index < 0) {
|
|
28
|
+
const wait = Math.max(1, Math.min(...this.pending.map((job) => job.runAt - Date.now())));
|
|
29
|
+
await new Promise((resolve) => setTimeout(resolve, wait));
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const [job] = this.pending.splice(index, 1);
|
|
33
|
+
if (!job)
|
|
34
|
+
continue;
|
|
35
|
+
this.active += 1;
|
|
36
|
+
void this.run(job).finally(() => { this.active -= 1; void this.drain(); });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
this.draining = false;
|
|
41
|
+
} }
|
|
42
|
+
async run(job) { const maxAttempts = this.options.retries ?? 0; const controller = new AbortController(); this.controllers.set(job.id, controller); try {
|
|
43
|
+
while (job.attempts <= maxAttempts && job.status !== "cancelled") {
|
|
44
|
+
job.status = "running";
|
|
45
|
+
job.attempts += 1;
|
|
46
|
+
try {
|
|
47
|
+
await this.worker(job, controller.signal);
|
|
48
|
+
job.status = "completed";
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
job.error = error;
|
|
53
|
+
if (job.attempts > maxAttempts) {
|
|
54
|
+
job.status = "failed";
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const delay = Math.min(this.options.maxBackoffMs ?? 30_000, (this.options.backoffMs ?? 250) * 2 ** (job.attempts - 1));
|
|
58
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
this.controllers.delete(job.id);
|
|
64
|
+
} }
|
|
65
|
+
}
|
|
66
|
+
export class Scheduler {
|
|
67
|
+
timers = new Map();
|
|
68
|
+
every(id, intervalMs, task) { if (intervalMs <= 0)
|
|
69
|
+
throw new RangeError("intervalMs must be positive"); this.cancel(id); const timer = setInterval(() => { void task(); }, intervalMs); this.timers.set(id, timer); return { id, cancel: () => this.cancel(id) }; }
|
|
70
|
+
after(id, delayMs, task) { this.cancel(id); const timer = setTimeout(() => { this.timers.delete(id); void task(); }, delayMs); this.timers.set(id, timer); return { id, cancel: () => this.cancel(id) }; }
|
|
71
|
+
cron(id, expression, task) { const interval = parseSimpleCronInterval(expression); return this.every(id, interval, task); }
|
|
72
|
+
cancel(id) { const timer = this.timers.get(id); if (!timer)
|
|
73
|
+
return false; clearTimeout(timer); clearInterval(timer); this.timers.delete(id); return true; }
|
|
74
|
+
clear() { for (const id of [...this.timers.keys()])
|
|
75
|
+
this.cancel(id); }
|
|
76
|
+
}
|
|
77
|
+
function parseSimpleCronInterval(expression) { const minute = expression.trim().split(/\s+/)[0]; if (minute?.startsWith("*/")) {
|
|
78
|
+
const value = Number(minute.slice(2));
|
|
79
|
+
if (Number.isInteger(value) && value > 0)
|
|
80
|
+
return value * 60_000;
|
|
81
|
+
} throw new Error("Only interval cron expressions such as */5 are supported by the built-in scheduler; use an adapter for full cron syntax."); }
|
|
82
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/queue/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Middleware } from "../middleware/compose.js";
|
|
2
|
+
export interface RoutableContext {
|
|
3
|
+
update: {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
};
|
|
6
|
+
message: {
|
|
7
|
+
text?: string;
|
|
8
|
+
chat?: {
|
|
9
|
+
id: number;
|
|
10
|
+
};
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
} | undefined;
|
|
13
|
+
callbackQuery: {
|
|
14
|
+
data?: string;
|
|
15
|
+
} | undefined;
|
|
16
|
+
params: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
type Matcher<Context> = (ctx: Context) => boolean | Promise<boolean>;
|
|
19
|
+
type Handler<Context> = Middleware<Context>;
|
|
20
|
+
export declare class Router<Context extends RoutableContext> {
|
|
21
|
+
private readonly routes;
|
|
22
|
+
private sequence;
|
|
23
|
+
use(...middleware: Handler<Context>[]): this;
|
|
24
|
+
route(matcher: Matcher<Context>, ...middleware: Handler<Context>[]): this;
|
|
25
|
+
command(name: string | RegExp, ...middleware: Handler<Context>[]): this;
|
|
26
|
+
text(value: string, ...middleware: Handler<Context>[]): this;
|
|
27
|
+
regex(expression: RegExp, ...middleware: Handler<Context>[]): this;
|
|
28
|
+
callback(pattern: string | RegExp, ...middleware: Handler<Context>[]): this;
|
|
29
|
+
chat(chatId: number | string, ...middleware: Handler<Context>[]): this;
|
|
30
|
+
predicate(matcher: Matcher<Context>, ...middleware: Handler<Context>[]): this;
|
|
31
|
+
nest(child: Router<Context>): this;
|
|
32
|
+
handle(ctx: Context, terminal?: () => Promise<void>): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/router/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IACnC,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC;IACtF,aAAa,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,KAAK,OAAO,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AACrE,KAAK,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AAG5C,qBAAa,MAAM,CAAC,OAAO,SAAS,eAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAK;IACrB,GAAG,CAAC,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAC5C,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IACzE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IACvE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAC5D,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAClE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAC3E,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IACtE,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAC7E,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI;IAC5B,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAC1E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { compose } from "../middleware/compose.js";
|
|
2
|
+
export class Router {
|
|
3
|
+
routes = [];
|
|
4
|
+
sequence = 0;
|
|
5
|
+
use(...middleware) { this.routes.push({ priority: -1_000_000 + this.sequence++, matcher: () => true, middleware }); return this; }
|
|
6
|
+
route(matcher, ...middleware) { this.routes.push({ priority: this.sequence++, matcher, middleware }); return this; }
|
|
7
|
+
command(name, ...middleware) { return this.route(async (ctx) => { const text = ctx.message?.text; if (!text?.startsWith("/"))
|
|
8
|
+
return false; const command = text.slice(1).split(/[\s@]/, 1)[0] ?? ""; return typeof name === "string" ? command === name.replace(/^\//, "") : name.test(command); }, ...middleware); }
|
|
9
|
+
text(value, ...middleware) { return this.route((ctx) => ctx.message?.text === value, ...middleware); }
|
|
10
|
+
regex(expression, ...middleware) { return this.route((ctx) => expression.test(ctx.message?.text ?? ""), ...middleware); }
|
|
11
|
+
callback(pattern, ...middleware) { return this.route((ctx) => { const data = ctx.callbackQuery?.data ?? ""; return typeof pattern === "string" ? pattern.endsWith("*") ? data.startsWith(pattern.slice(0, -1)) : data === pattern : pattern.test(data); }, ...middleware); }
|
|
12
|
+
chat(chatId, ...middleware) { return this.route((ctx) => { const id = ctx.message?.chat?.id; return id === chatId || String(id) === String(chatId); }, ...middleware); }
|
|
13
|
+
predicate(matcher, ...middleware) { return this.route(matcher, ...middleware); }
|
|
14
|
+
nest(child) { return this.route(() => true, async (ctx, next) => { await child.handle(ctx, next); }); }
|
|
15
|
+
async handle(ctx, terminal) { const ordered = [...this.routes].sort((left, right) => left.priority - right.priority); let matched = false; for (const route of ordered) {
|
|
16
|
+
if (!(await route.matcher(ctx)))
|
|
17
|
+
continue;
|
|
18
|
+
matched = true;
|
|
19
|
+
await compose(route.middleware)(ctx);
|
|
20
|
+
} if (!matched)
|
|
21
|
+
await terminal?.(); }
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/router/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Context } from "../context/context.js";
|
|
2
|
+
export interface ConversationState {
|
|
3
|
+
name: string;
|
|
4
|
+
step: number;
|
|
5
|
+
values: Record<string, unknown>;
|
|
6
|
+
status: "active" | "completed" | "cancelled";
|
|
7
|
+
updatedAt: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class ConversationFlow<S extends object = Record<string, unknown>> {
|
|
10
|
+
readonly ctx: Context<S>;
|
|
11
|
+
readonly state: ConversationState;
|
|
12
|
+
constructor(ctx: Context<S>, state: ConversationState);
|
|
13
|
+
get values(): Record<string, unknown>;
|
|
14
|
+
set<T>(key: string, value: T): this;
|
|
15
|
+
get<T>(key: string): T | undefined;
|
|
16
|
+
next(): this;
|
|
17
|
+
previous(): this;
|
|
18
|
+
complete(): void;
|
|
19
|
+
cancel(): void;
|
|
20
|
+
}
|
|
21
|
+
export declare class ConversationManager<S extends object = Record<string, unknown>> {
|
|
22
|
+
private readonly active;
|
|
23
|
+
start(key: string, name: string, values?: Record<string, unknown>): ConversationState;
|
|
24
|
+
get(key: string): ConversationState | undefined;
|
|
25
|
+
cancel(key: string): boolean;
|
|
26
|
+
clearExpired(maxAgeMs: number): number;
|
|
27
|
+
run(ctx: Context<S>, key: string, name: string, steps: Array<(flow: ConversationFlow<S>) => void | Promise<void>>): Promise<ConversationState>;
|
|
28
|
+
}
|
|
29
|
+
export interface WizardStep<S extends object = Record<string, unknown>> {
|
|
30
|
+
id: string;
|
|
31
|
+
run: (flow: ConversationFlow<S>) => void | Promise<void>;
|
|
32
|
+
optional?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare class Wizard<S extends object = Record<string, unknown>> {
|
|
35
|
+
private readonly stepsList;
|
|
36
|
+
step(step: WizardStep<S>): this;
|
|
37
|
+
run(ctx: Context<S>, key: string, manager?: ConversationManager<S>): Promise<ConversationState>;
|
|
38
|
+
get steps(): readonly WizardStep<S>[];
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=conversation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../../src/state/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AACnK,qBAAa,gBAAgB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB;gBAAlD,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAW,KAAK,EAAE,iBAAiB;IACvE,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAA8B;IACnE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IACnC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAClC,IAAI,IAAI,IAAI;IACZ,QAAQ,IAAI,IAAI;IAChB,QAAQ,IAAI,IAAI;IAChB,MAAM,IAAI,IAAI;CACf;AAED,qBAAa,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,iBAAiB;IACzF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAC/C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAC5B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAChC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC;CACrJ;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAAI,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AACpK,qBAAa,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI;IACzB,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,yBAA+B,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAC3G,IAAI,KAAK,IAAI,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,CAA2B;CACjE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export class ConversationFlow {
|
|
2
|
+
ctx;
|
|
3
|
+
state;
|
|
4
|
+
constructor(ctx, state) {
|
|
5
|
+
this.ctx = ctx;
|
|
6
|
+
this.state = state;
|
|
7
|
+
}
|
|
8
|
+
get values() { return this.state.values; }
|
|
9
|
+
set(key, value) { this.state.values[key] = value; this.state.updatedAt = Date.now(); return this; }
|
|
10
|
+
get(key) { return this.state.values[key]; }
|
|
11
|
+
next() { this.state.step += 1; this.state.updatedAt = Date.now(); return this; }
|
|
12
|
+
previous() { this.state.step = Math.max(0, this.state.step - 1); this.state.updatedAt = Date.now(); return this; }
|
|
13
|
+
complete() { this.state.status = "completed"; this.state.updatedAt = Date.now(); }
|
|
14
|
+
cancel() { this.state.status = "cancelled"; this.state.updatedAt = Date.now(); }
|
|
15
|
+
}
|
|
16
|
+
export class ConversationManager {
|
|
17
|
+
active = new Map();
|
|
18
|
+
start(key, name, values = {}) { const state = { name, step: 0, values, status: "active", updatedAt: Date.now() }; this.active.set(key, state); return state; }
|
|
19
|
+
get(key) { return this.active.get(key); }
|
|
20
|
+
cancel(key) { const state = this.active.get(key); if (!state)
|
|
21
|
+
return false; state.status = "cancelled"; state.updatedAt = Date.now(); return true; }
|
|
22
|
+
clearExpired(maxAgeMs) { const threshold = Date.now() - maxAgeMs; let removed = 0; for (const [key, state] of this.active)
|
|
23
|
+
if (state.updatedAt < threshold) {
|
|
24
|
+
this.active.delete(key);
|
|
25
|
+
removed += 1;
|
|
26
|
+
} return removed; }
|
|
27
|
+
async run(ctx, key, name, steps) { const state = this.active.get(key) ?? this.start(key, name); const flow = new ConversationFlow(ctx, state); const step = steps[state.step]; if (!step) {
|
|
28
|
+
state.status = "completed";
|
|
29
|
+
return state;
|
|
30
|
+
} await step(flow); return state; }
|
|
31
|
+
}
|
|
32
|
+
export class Wizard {
|
|
33
|
+
stepsList = [];
|
|
34
|
+
step(step) { this.stepsList.push(step); return this; }
|
|
35
|
+
async run(ctx, key, manager = new ConversationManager()) { return manager.run(ctx, key, "wizard", this.stepsList.map((step) => step.run)); }
|
|
36
|
+
get steps() { return this.stepsList; }
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../../src/state/conversation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface ValidationIssue {
|
|
2
|
+
path: string;
|
|
3
|
+
message: string;
|
|
4
|
+
code?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Field<T> {
|
|
7
|
+
name: string;
|
|
8
|
+
parse: (input: unknown) => T;
|
|
9
|
+
validate?: (value: T) => string | undefined | Promise<string | undefined>;
|
|
10
|
+
transform?: (value: T) => T | Promise<T>;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class Form<T extends Record<string, unknown>> {
|
|
14
|
+
private readonly fields;
|
|
15
|
+
private readonly values;
|
|
16
|
+
field<K extends keyof T & string>(definition: Field<T[K]> & {
|
|
17
|
+
name: K;
|
|
18
|
+
}): this;
|
|
19
|
+
parse(input: Record<string, unknown>): Promise<{
|
|
20
|
+
success: true;
|
|
21
|
+
data: T;
|
|
22
|
+
} | {
|
|
23
|
+
success: false;
|
|
24
|
+
issues: ValidationIssue[];
|
|
25
|
+
}>;
|
|
26
|
+
reset(): void;
|
|
27
|
+
}
|
|
28
|
+
export declare const validators: {
|
|
29
|
+
string: (value: unknown) => string;
|
|
30
|
+
number: (value: unknown) => number;
|
|
31
|
+
integer: (value: unknown) => number;
|
|
32
|
+
email: (value: unknown) => string;
|
|
33
|
+
url: (value: unknown) => string;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=forms.d.ts.map
|