gramio 0.0.16 → 0.0.18

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/dist/bot.d.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import { Context, ContextType, MaybeArray, UpdateName } from "@gramio/contexts";
2
- import type { APIMethods } from "@gramio/types";
3
- import "reflect-metadata";
2
+ import type { APIMethodParams, APIMethods, TelegramUser } from "@gramio/types";
4
3
  import { Plugin } from "./plugin";
5
4
  import { BotOptions, DeriveDefinitions, ErrorDefinitions, Handler, Hooks } from "./types";
6
5
  import { Updates } from "./updates";
7
6
  export declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends DeriveDefinitions = DeriveDefinitions> {
7
+ __Derives: Derives;
8
8
  readonly options: BotOptions;
9
+ info: TelegramUser | undefined;
9
10
  readonly api: APIMethods;
11
+ private dependencies;
10
12
  private errorsDefinitions;
11
13
  private errorHandler;
12
14
  updates: Updates;
@@ -66,7 +68,13 @@ export declare class Bot<Errors extends ErrorDefinitions = {}, Derives extends D
66
68
  derive<Update extends UpdateName, Handler extends Hooks.Derive<ContextType<typeof this, Update>>>(updateName: MaybeArray<Update>, handler: Handler): Bot<Errors, Derives & {
67
69
  [K in Update]: Awaited<ReturnType<Handler>>;
68
70
  }>;
71
+ onStart(handler: Hooks.OnStart): this;
69
72
  on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<ContextType<typeof this, T> & Derives["global"] & Derives[T]>): this;
70
73
  use(handler: Handler<Context<typeof this> & Derives["global"]>): this;
71
74
  extend<NewPlugin extends Plugin>(plugin: NewPlugin): Bot<Errors & NewPlugin["Errors"], Derives & NewPlugin["Derives"]>;
75
+ start({ webhook, dropPendingUpdates, allowedUpdates, }?: {
76
+ webhook?: Omit<APIMethodParams<"setWebhook">, "drop_pending_updates" | "allowed_updates">;
77
+ dropPendingUpdates?: boolean;
78
+ allowedUpdates?: NonNullable<APIMethodParams<"getUpdates">>["allowed_updates"];
79
+ }): Promise<TelegramUser>;
72
80
  }
package/dist/bot.js CHANGED
@@ -1,9 +1,37 @@
1
1
  "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
7
35
  };
8
36
  Object.defineProperty(exports, "__esModule", { value: true });
9
37
  exports.Bot = void 0;
@@ -11,183 +39,240 @@ const files_1 = require("@gramio/files");
11
39
  const format_1 = require("@gramio/format");
12
40
  const form_data_encoder_1 = require("form-data-encoder");
13
41
  const inspectable_1 = require("inspectable");
14
- require("reflect-metadata");
15
42
  const undici_1 = require("undici");
16
43
  const errors_1 = require("./errors");
17
44
  const updates_1 = require("./updates");
18
- let Bot = class Bot {
19
- options = {};
20
- api = new Proxy({}, {
21
- get: (_target, method) => (args) => this._callApi(method, args),
22
- });
23
- errorsDefinitions = {
24
- TELEGRAM: errors_1.TelegramError,
25
- };
26
- errorHandler(context, error) {
27
- return this.runImmutableHooks("onError", {
28
- context,
29
- //@ts-expect-error ErrorKind exists if user register error-class with .error("kind", SomeError);
30
- kind: error.constructor[errors_1.ErrorKind] ?? "UNKNOWN",
31
- error: error,
45
+ let Bot = (() => {
46
+ let _classDecorators = [(0, inspectable_1.Inspectable)({
47
+ serialize: () => ({}),
48
+ })];
49
+ let _classDescriptor;
50
+ let _classExtraInitializers = [];
51
+ let _classThis;
52
+ var Bot = class {
53
+ static { _classThis = this; }
54
+ static {
55
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
56
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
57
+ Bot = _classThis = _classDescriptor.value;
58
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
59
+ __runInitializers(_classThis, _classExtraInitializers);
60
+ }
61
+ __Derives;
62
+ options = {};
63
+ info;
64
+ api = new Proxy({}, {
65
+ get: (_target, method) => (args) => this._callApi(method, args),
32
66
  });
33
- }
34
- updates = new updates_1.Updates(this, this.errorHandler.bind(this));
35
- hooks = {
36
- preRequest: [
37
- (ctx) => {
38
- if (!ctx.params)
67
+ dependencies = [];
68
+ errorsDefinitions = {
69
+ TELEGRAM: errors_1.TelegramError,
70
+ };
71
+ errorHandler(context, error) {
72
+ return this.runImmutableHooks("onError", {
73
+ context,
74
+ //@ts-expect-error ErrorKind exists if user register error-class with .error("kind", SomeError);
75
+ kind: error.constructor[errors_1.ErrorKind] ?? "UNKNOWN",
76
+ error: error,
77
+ });
78
+ }
79
+ updates = new updates_1.Updates(this, this.errorHandler.bind(this));
80
+ hooks = {
81
+ preRequest: [
82
+ (ctx) => {
83
+ if (!ctx.params)
84
+ return ctx;
85
+ const formattable = format_1.FormattableMap[ctx.method];
86
+ // @ts-ignore add AnyTelegramMethod to @gramio/format
87
+ if (formattable)
88
+ ctx.params = formattable(ctx.params);
39
89
  return ctx;
40
- const formattable = format_1.FormattableMap[ctx.method];
41
- // @ts-ignore add AnyTelegramMethod to @gramio/format
42
- if (formattable)
43
- ctx.params = formattable(ctx.params);
44
- return ctx;
45
- },
46
- ],
47
- onError: [],
48
- };
49
- constructor(token, options) {
50
- this.options = { ...options, token };
51
- }
52
- async runHooks(type, context) {
53
- let data = context;
54
- for await (const hook of this.hooks[type]) {
55
- data = await hook(data);
90
+ },
91
+ ],
92
+ onError: [],
93
+ onStart: [],
94
+ };
95
+ constructor(token, options) {
96
+ this.options = { ...options, token };
56
97
  }
57
- return data;
58
- }
59
- async runImmutableHooks(type, context) {
60
- for await (const hook of this.hooks[type]) {
61
- await hook(context);
98
+ async runHooks(type, context) {
99
+ let data = context;
100
+ for await (const hook of this.hooks[type]) {
101
+ data = await hook(data);
102
+ }
103
+ return data;
62
104
  }
63
- }
64
- async _callApi(method, params = {}) {
65
- const url = `https://api.telegram.org/bot${this.options.token}/${method}`;
66
- const reqOptions = {
67
- method: "POST",
68
- duplex: "half",
69
- };
70
- const context = await this.runHooks("preRequest",
71
- // TODO: fix type error
72
- // @ts-expect-error
73
- {
74
- method,
75
- params,
76
- });
77
- // biome-ignore lint/style/noParameterAssign: mutate params
78
- params = context.params;
79
- if (params && (0, files_1.isMediaUpload)(method, params)) {
80
- const formData = await (0, files_1.convertJsonToFormData)(method, params);
81
- const encoder = new form_data_encoder_1.FormDataEncoder(formData);
82
- reqOptions.body = encoder.encode();
83
- reqOptions.headers = encoder.headers;
84
- }
85
- else {
86
- reqOptions.headers = {
87
- "Content-Type": "application/json",
105
+ async runImmutableHooks(type, context) {
106
+ for await (const hook of this.hooks[type]) {
107
+ //TODO: solve that later
108
+ //@ts-expect-error
109
+ await hook(context);
110
+ }
111
+ }
112
+ async _callApi(method, params = {}) {
113
+ const url = `https://api.telegram.org/bot${this.options.token}/${method}`;
114
+ const reqOptions = {
115
+ method: "POST",
116
+ duplex: "half",
88
117
  };
89
- reqOptions.body = JSON.stringify(params);
118
+ const context = await this.runHooks("preRequest",
119
+ // TODO: fix type error
120
+ // @ts-expect-error
121
+ {
122
+ method,
123
+ params,
124
+ });
125
+ // biome-ignore lint/style/noParameterAssign: mutate params
126
+ params = context.params;
127
+ if (params && (0, files_1.isMediaUpload)(method, params)) {
128
+ const formData = await (0, files_1.convertJsonToFormData)(method, params);
129
+ const encoder = new form_data_encoder_1.FormDataEncoder(formData);
130
+ reqOptions.body = encoder.encode();
131
+ reqOptions.headers = encoder.headers;
132
+ }
133
+ else {
134
+ reqOptions.headers = {
135
+ "Content-Type": "application/json",
136
+ };
137
+ reqOptions.body = JSON.stringify(params);
138
+ }
139
+ const response = await (0, undici_1.fetch)(url, reqOptions);
140
+ const data = (await response.json());
141
+ if (!data.ok)
142
+ throw new errors_1.TelegramError(data, method, params);
143
+ return data.result;
90
144
  }
91
- const response = await (0, undici_1.fetch)(url, reqOptions);
92
- const data = (await response.json());
93
- if (!data.ok)
94
- throw new errors_1.TelegramError(data, method, params);
95
- return data.result;
96
- }
97
- /**
98
- * Register custom class-error for type-safe catch in `onError` hook
99
- *
100
- * @example
101
- * ```ts
102
- * export class NoRights extends Error {
103
- * needRole: "admin" | "moderator";
104
- *
105
- * constructor(role: "admin" | "moderator") {
106
- * super();
107
- * this.needRole = role;
108
- * }
109
- * }
110
- *
111
- * const bot = new Bot(process.env.TOKEN!)
112
- * .error("NO_RIGHTS", NoRights)
113
- * .onError(({ context, kind, error }) => {
114
- * if (context.is("message") && kind === "NO_RIGHTS")
115
- * return context.send(
116
- * format`You don't have enough rights! You need to have an «${bold(
117
- * error.needRole
118
- * )}» role.`
119
- * );
120
- * });
121
- *
122
- * bot.updates.on("message", (context) => {
123
- * if (context.text === "bun") throw new NoRights("admin");
124
- * });
125
- * ```
126
- */
127
- error(kind, error) {
128
- //@ts-expect-error Set ErrorKind
129
- error[errors_1.ErrorKind] = kind;
130
- this.errorsDefinitions[kind] = error;
131
- return this;
132
- }
133
- onError(updateNameOrHandler, handler) {
134
- if (typeof updateNameOrHandler === "function") {
135
- this.hooks.onError.push(updateNameOrHandler);
145
+ /**
146
+ * Register custom class-error for type-safe catch in `onError` hook
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * export class NoRights extends Error {
151
+ * needRole: "admin" | "moderator";
152
+ *
153
+ * constructor(role: "admin" | "moderator") {
154
+ * super();
155
+ * this.needRole = role;
156
+ * }
157
+ * }
158
+ *
159
+ * const bot = new Bot(process.env.TOKEN!)
160
+ * .error("NO_RIGHTS", NoRights)
161
+ * .onError(({ context, kind, error }) => {
162
+ * if (context.is("message") && kind === "NO_RIGHTS")
163
+ * return context.send(
164
+ * format`You don't have enough rights! You need to have an «${bold(
165
+ * error.needRole
166
+ * )}» role.`
167
+ * );
168
+ * });
169
+ *
170
+ * bot.updates.on("message", (context) => {
171
+ * if (context.text === "bun") throw new NoRights("admin");
172
+ * });
173
+ * ```
174
+ */
175
+ error(kind, error) {
176
+ //@ts-expect-error Set ErrorKind
177
+ error[errors_1.ErrorKind] = kind;
178
+ this.errorsDefinitions[kind] = error;
136
179
  return this;
137
180
  }
138
- if (handler) {
139
- this.hooks.onError.push(async (errContext) => {
140
- if (errContext.context.is(updateNameOrHandler))
141
- // TODO: Sorry... fix later
142
- //@ts-expect-error
143
- await handler(errContext);
144
- });
181
+ onError(updateNameOrHandler, handler) {
182
+ if (typeof updateNameOrHandler === "function") {
183
+ this.hooks.onError.push(updateNameOrHandler);
184
+ return this;
185
+ }
186
+ if (handler) {
187
+ this.hooks.onError.push(async (errContext) => {
188
+ if (errContext.context.is(updateNameOrHandler))
189
+ // TODO: Sorry... fix later
190
+ //@ts-expect-error
191
+ await handler(errContext);
192
+ });
193
+ }
194
+ return this;
145
195
  }
146
- return this;
147
- }
148
- derive(updateNameOrHandler, handler) {
149
- if (typeof updateNameOrHandler === "function")
150
- this.updates.use(async (context, next) => {
151
- for (const [key, value] of Object.entries(await updateNameOrHandler(context))) {
152
- context[key] = value;
153
- }
154
- next();
196
+ derive(updateNameOrHandler, handler) {
197
+ if (typeof updateNameOrHandler === "function")
198
+ this.updates.use(async (context, next) => {
199
+ for (const [key, value] of Object.entries(await updateNameOrHandler(context))) {
200
+ context[key] = value;
201
+ }
202
+ next();
203
+ });
204
+ else if (handler)
205
+ this.updates.on(updateNameOrHandler, async (context, next) => {
206
+ for (const [key, value] of Object.entries(await handler(context))) {
207
+ context[key] = value;
208
+ }
209
+ next();
210
+ });
211
+ return this;
212
+ }
213
+ onStart(handler) {
214
+ this.hooks.onStart.push(handler);
215
+ return this;
216
+ }
217
+ on(updateName, handler) {
218
+ this.updates.on(updateName, handler);
219
+ return this;
220
+ }
221
+ use(handler) {
222
+ this.updates.use(handler);
223
+ return this;
224
+ }
225
+ extend(plugin) {
226
+ if (plugin.dependencies.some((dep) => !this.dependencies.includes(dep)))
227
+ throw new Error(`The «${plugin.name}» plugin needs dependencies registered before: ${plugin.dependencies
228
+ .filter((dep) => !this.dependencies.includes(dep))
229
+ .join(", ")}`);
230
+ for (const [key, value] of Object.entries(plugin.errorsDefinitions)) {
231
+ if (this.errorsDefinitions[key])
232
+ this.errorsDefinitions[key] = value;
233
+ }
234
+ for (const value of plugin.derives) {
235
+ const [derive, updateName] = value;
236
+ if (!updateName)
237
+ this.derive(derive);
238
+ else
239
+ this.derive(updateName, derive);
240
+ }
241
+ this.dependencies.push(plugin.name);
242
+ return this;
243
+ }
244
+ async start({ webhook, dropPendingUpdates, allowedUpdates, } = {}) {
245
+ //TODO: maybe it useless??
246
+ this.info = await this.api.getMe();
247
+ if (!webhook) {
248
+ await this.api.deleteWebhook({
249
+ drop_pending_updates: dropPendingUpdates,
250
+ });
251
+ await this.updates.startPolling({
252
+ allowed_updates: allowedUpdates,
253
+ });
254
+ this.runImmutableHooks("onStart", {
255
+ plugins: this.dependencies,
256
+ info: this.info,
257
+ updatesFrom: "long-polling",
258
+ });
259
+ return this.info;
260
+ }
261
+ if (this.updates.isStarted)
262
+ this.updates.stopPolling();
263
+ await this.api.setWebhook({
264
+ ...webhook,
265
+ drop_pending_updates: dropPendingUpdates,
266
+ allowed_updates: allowedUpdates,
155
267
  });
156
- else if (handler)
157
- this.updates.on(updateNameOrHandler, async (context, next) => {
158
- for (const [key, value] of Object.entries(await handler(context))) {
159
- context[key] = value;
160
- }
161
- next();
268
+ this.runImmutableHooks("onStart", {
269
+ plugins: this.dependencies,
270
+ info: this.info,
271
+ updatesFrom: "webhook",
162
272
  });
163
- return this;
164
- }
165
- on(updateName, handler) {
166
- this.updates.on(updateName, handler);
167
- return this;
168
- }
169
- use(handler) {
170
- this.updates.use(handler);
171
- return this;
172
- }
173
- extend(plugin) {
174
- for (const [key, value] of Object.entries(plugin.errorsDefinitions)) {
175
- if (this.errorsDefinitions[key])
176
- this.errorsDefinitions[key] = value;
177
- }
178
- for (const value of plugin.derives) {
179
- const [derive, updateName] = value;
180
- if (!updateName)
181
- this.derive(derive);
182
- else
183
- this.derive(updateName, derive);
184
- }
185
- return this;
186
- }
187
- };
273
+ return this.info;
274
+ }
275
+ };
276
+ return Bot = _classThis;
277
+ })();
188
278
  exports.Bot = Bot;
189
- exports.Bot = Bot = __decorate([
190
- (0, inspectable_1.Inspectable)({
191
- serialize: () => ({}),
192
- })
193
- ], Bot);
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from "./bot";
2
2
  export * from "./errors";
3
3
  export * from "./types";
4
4
  export * from "./plugin";
5
+ export * from "./webhook";
5
6
  export * from "@gramio/contexts";
6
7
  export * from "@gramio/files";
7
8
  export * from "@gramio/keyboards";
package/dist/index.js CHANGED
@@ -14,10 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ // INFO: Temp polyfill, more info https://github.com/microsoft/TypeScript/issues/55453#issuecomment-1687496648
18
+ Symbol.metadata ??= Symbol("Symbol.metadata");
17
19
  __exportStar(require("./bot"), exports);
18
20
  __exportStar(require("./errors"), exports);
19
21
  __exportStar(require("./types"), exports);
20
22
  __exportStar(require("./plugin"), exports);
23
+ __exportStar(require("./webhook"), exports);
21
24
  __exportStar(require("@gramio/contexts"), exports);
22
25
  __exportStar(require("@gramio/files"), exports);
23
26
  __exportStar(require("@gramio/keyboards"), exports);
package/dist/plugin.d.ts CHANGED
@@ -9,7 +9,10 @@ export declare class Plugin<Errors extends ErrorDefinitions = {}, Derives extend
9
9
  new (...args: any): any;
10
10
  prototype: Error;
11
11
  }>;
12
- constructor(name: string);
12
+ dependencies: string[];
13
+ constructor(name: string, { dependencies }?: {
14
+ dependencies?: string[];
15
+ });
13
16
  /**
14
17
  * Register custom class-error in plugin
15
18
  **/
package/dist/plugin.js CHANGED
@@ -1,32 +1,90 @@
1
1
  "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
2
36
  Object.defineProperty(exports, "__esModule", { value: true });
3
37
  exports.Plugin = void 0;
38
+ const inspectable_1 = require("inspectable");
4
39
  const _errors_1 = require("./errors");
5
- class Plugin {
6
- // TODO: fix that dump error. https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcCiUrQCLAGYCWAdgTAREQM5wC8cASsAMbQAmAPAFACQlMUxAOYAaHhixROAPgDcnTqEiw4TADYBDStQAKqgK6Di7cdGqgYwIq2omouQiTIVqdAN4BfKXFc8i6gLbAAFxwfAJEgnI8wJim9sSk5FQhjCxQHDy8-EKi3NyucETAAO5wABQAdFXqUIKUIepEiACUDU0ycGBYMBBIKCG2cO48Xm7uUdwsVPx6TD1QZX6BIWFCzd6ZMAAWBJQVS6h0B3LcwzwA9ABUlzxwlwzAhnwxKnp8EP4qGloAtDEScGInX0hiIt2u52isSgXDyADkAqhzJZrKFshFctw4SVBsirNQCkVSpVqrV6nBGi02ogOl1er1kMF0NChrkpGUANbEVghBGBYRwf7QXk46HrHx5c7nAACMEof3AzBgfxZAGVgPBbABpbmZIVQADa2u5AF1aHAuVYTtxNjs9vrKPFHElKAbLawzXR9RNuFANXooEQEHaKdQ9EQOUQIMUg5o4LoDEZMtxbNQAGTeOAGg6AoN84AmkIASWmjSYwAAKoz2NjirYvMM8rIeMMzgpwNB4GpNNQAEK9YzQswgCz45kSJ2JZzmjxeHzybh4ji1hOgwUjlE6EFGSlSdmZMDbogi4qr4i5VpwFdH9ej1FnojsYh4F4P1NeAD8cH7MEHEnT8ZHu+cAhNsuwbHkfowAGQZgdQcaUicrbyO2Shdt81BwhA9AEIIWxyrem7jtAEFFMArD0BAqhMgAROorD+MQNFwAAPnANH+BArAxOo8w0RMUxhLM8xlFg1EhHRDFMax7GcdxUC8dANHipklB6CgCzNNacH7MA5GUdR5picASGcGcgnwBYfDmkSgGJkQZQ0TAykVPqjlwgA8gA+vQRYAOIABIVqqNEClhOF4XKWnyBZcAAEa9DZJTfr0ZTNDwrkblYZRWTAzRAA
7
- Errors;
8
- Derives;
9
- derives = [];
10
- name;
11
- errorsDefinitions = {};
12
- constructor(name) {
13
- this.name = name;
14
- }
15
- /**
16
- * Register custom class-error in plugin
17
- **/
18
- error(kind, error) {
19
- //@ts-expect-error Set ErrorKind
20
- error[_errors_1.ErrorKind] = kind;
21
- this.errorsDefinitions[kind] = error;
22
- return this;
23
- }
24
- derive(updateNameOrHandler, handler) {
25
- if (typeof updateNameOrHandler === "string" && handler)
26
- this.derives.push([handler, updateNameOrHandler]);
27
- else if (typeof updateNameOrHandler === "function")
28
- this.derives.push([updateNameOrHandler, undefined]);
29
- return this;
30
- }
31
- }
40
+ let Plugin = (() => {
41
+ let _classDecorators = [(0, inspectable_1.Inspectable)({
42
+ serialize: (plugin) => ({
43
+ name: plugin.name,
44
+ dependencies: plugin.dependencies,
45
+ }),
46
+ })];
47
+ let _classDescriptor;
48
+ let _classExtraInitializers = [];
49
+ let _classThis;
50
+ var Plugin = class {
51
+ static { _classThis = this; }
52
+ static {
53
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
54
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
55
+ Plugin = _classThis = _classDescriptor.value;
56
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
57
+ __runInitializers(_classThis, _classExtraInitializers);
58
+ }
59
+ // TODO: fix that dump error. https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBDAnmYcCiUrQCLAGYCWAdgTAREQM5wC8cASsAMbQAmAPAFACQlMUxAOYAaHhixROAPgDcnTqEiw4TADYBDStQAKqgK6Di7cdGqgYwIq2omouQiTIVqdAN4BfKXFc8i6gLbAAFxwfAJEgnI8wJim9sSk5FQhjCxQHDy8-EKi3NyucETAAO5wABQAdFXqUIKUIepEiACUDU0ycGBYMBBIKCG2cO48Xm7uUdwsVPx6TD1QZX6BIWFCzd6ZMAAWBJQVS6h0B3LcwzwA9ABUlzxwlwzAhnwxKnp8EP4qGloAtDEScGInX0hiIt2u52isSgXDyADkAqhzJZrKFshFctw4SVBsirNQCkVSpVqrV6nBGi02ogOl1er1kMF0NChrkpGUANbEVghBGBYRwf7QXk46HrHx5c7nAACMEof3AzBgfxZAGVgPBbABpbmZIVQADa2u5AF1aHAuVYTtxNjs9vrKPFHElKAbLawzXR9RNuFANXooEQEHaKdQ9EQOUQIMUg5o4LoDEZMtxbNQAGTeOAGg6AoN84AmkIASWmjSYwAAKoz2NjirYvMM8rIeMMzgpwNB4GpNNQAEK9YzQswgCz45kSJ2JZzmjxeHzybh4ji1hOgwUjlE6EFGSlSdmZMDbogi4qr4i5VpwFdH9ej1FnojsYh4F4P1NeAD8cH7MEHEnT8ZHu+cAhNsuwbHkfowAGQZgdQcaUicrbyO2Shdt81BwhA9AEIIWxyrem7jtAEFFMArD0BAqhMgAROorD+MQNFwAAPnANH+BArAxOo8w0RMUxhLM8xlFg1EhHRDFMax7GcdxUC8dANHipklB6CgCzNNacH7MA5GUdR5picASGcGcgnwBYfDmkSgGJkQZQ0TAykVPqjlwgA8gA+vQRYAOIABIVqqNEClhOF4XKWnyBZcAAEa9DZJTfr0ZTNDwrkblYZRWTAzRAA
60
+ Errors;
61
+ Derives;
62
+ derives = [];
63
+ name;
64
+ errorsDefinitions = {};
65
+ dependencies = [];
66
+ constructor(name, { dependencies } = {}) {
67
+ this.name = name;
68
+ if (dependencies)
69
+ this.dependencies = dependencies;
70
+ }
71
+ /**
72
+ * Register custom class-error in plugin
73
+ **/
74
+ error(kind, error) {
75
+ //@ts-expect-error Set ErrorKind
76
+ error[_errors_1.ErrorKind] = kind;
77
+ this.errorsDefinitions[kind] = error;
78
+ return this;
79
+ }
80
+ derive(updateNameOrHandler, handler) {
81
+ if (typeof updateNameOrHandler === "string" && handler)
82
+ this.derives.push([handler, updateNameOrHandler]);
83
+ else if (typeof updateNameOrHandler === "function")
84
+ this.derives.push([updateNameOrHandler, undefined]);
85
+ return this;
86
+ }
87
+ };
88
+ return Plugin = _classThis;
89
+ })();
32
90
  exports.Plugin = Plugin;
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BotLike, Context, UpdateName } from "@gramio/contexts";
2
- import { APIMethodParams, APIMethods } from "@gramio/types";
2
+ import { APIMethodParams, APIMethods, TelegramUser } from "@gramio/types";
3
3
  import { NextMiddleware } from "middleware-io";
4
4
  import { TelegramError } from "./errors";
5
5
  export interface BotOptions {
@@ -29,9 +29,15 @@ export declare namespace Hooks {
29
29
  [K in keyof T]: ErrorHandlerParams<Ctx, K & string, T[K & string]>;
30
30
  }[keyof T];
31
31
  type OnError<T extends ErrorDefinitions, Ctx extends Context<BotLike> = Context<BotLike>> = (options: OnErrorContext<Ctx, T>) => unknown;
32
+ type OnStart = (context: {
33
+ plugins: string[];
34
+ info: TelegramUser;
35
+ updatesFrom: "webhook" | "long-polling";
36
+ }) => unknown;
32
37
  interface Store<T extends ErrorDefinitions> {
33
38
  preRequest: PreRequest[];
34
39
  onError: OnError<T>[];
40
+ onStart: OnStart[];
35
41
  }
36
42
  }
37
43
  export type ErrorDefinitions = Record<string, Error>;
package/dist/updates.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Context, MaybeArray, UpdateName } from "@gramio/contexts";
2
- import type { TelegramUpdate } from "@gramio/types";
2
+ import type { APIMethodParams, TelegramUpdate } from "@gramio/types";
3
3
  import { CaughtMiddlewareHandler } from "middleware-io";
4
4
  import type { Bot } from "./bot";
5
5
  import { Handler } from "./types";
6
6
  export declare class Updates {
7
7
  private readonly bot;
8
- private isStarted;
8
+ isStarted: boolean;
9
9
  private offset;
10
10
  private composer;
11
11
  private onError;
@@ -13,7 +13,8 @@ export declare class Updates {
13
13
  on<T extends UpdateName>(updateName: MaybeArray<T>, handler: Handler<any>): this;
14
14
  use(handler: Handler<any>): this;
15
15
  handleUpdate(data: TelegramUpdate): Promise<void>;
16
- startPolling(): Promise<void>;
17
- startFetchLoop(): Promise<void>;
16
+ /**@deprecated use bot.start instead */
17
+ startPolling(params?: APIMethodParams<"getUpdates">): Promise<void>;
18
+ startFetchLoop(params?: APIMethodParams<"getUpdates">): Promise<void>;
18
19
  stopPolling(): void;
19
20
  }
package/dist/updates.js CHANGED
@@ -63,17 +63,19 @@ class Updates {
63
63
  throw new Error(`[UPDATES] Update type ${updateType} not supported.`);
64
64
  }
65
65
  }
66
- async startPolling() {
66
+ /**@deprecated use bot.start instead */
67
+ async startPolling(params = {}) {
67
68
  if (this.isStarted)
68
69
  throw new Error("[UPDATES] Polling already started!");
69
70
  this.isStarted = true;
70
- this.startFetchLoop();
71
+ this.startFetchLoop(params);
71
72
  return;
72
73
  }
73
- async startFetchLoop() {
74
+ async startFetchLoop(params = {}) {
74
75
  while (this.isStarted) {
75
76
  const updates = await this.bot.api.getUpdates({
76
77
  offset: this.offset,
78
+ ...params,
77
79
  });
78
80
  for await (const update of updates) {
79
81
  //TODO: update errors
@@ -0,0 +1,16 @@
1
+ import { TelegramUpdate } from "@gramio/types";
2
+ export interface FrameworkHandler {
3
+ update: TelegramUpdate;
4
+ header?: string;
5
+ }
6
+ export type FrameworkAdapter = (...args: any[]) => FrameworkHandler;
7
+ export declare const frameworks: {
8
+ elysia: ({ body, headers }: any) => {
9
+ update: any;
10
+ header: any;
11
+ };
12
+ fastify: (request: any) => {
13
+ update: any;
14
+ header: any;
15
+ };
16
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.frameworks = void 0;
4
+ const SECRET_TOKEN_HEADER = "X-Telegram-Bot-Api-Secret-Token";
5
+ exports.frameworks = {
6
+ elysia: ({ body, headers }) => ({
7
+ update: body,
8
+ header: headers[SECRET_TOKEN_HEADER],
9
+ }),
10
+ fastify: (request) => ({
11
+ update: request.body,
12
+ header: request.headers[SECRET_TOKEN_HEADER],
13
+ }),
14
+ };
@@ -0,0 +1,3 @@
1
+ import { Bot } from "../bot";
2
+ import { frameworks } from "./adapters";
3
+ export declare function webhookHandler(bot: Bot, framework: keyof typeof frameworks): (...args: any[]) => Promise<void>;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webhookHandler = void 0;
4
+ const adapters_1 = require("./adapters");
5
+ function webhookHandler(bot, framework) {
6
+ const frameworkAdapter = adapters_1.frameworks[framework];
7
+ return async (...args) => {
8
+ const { update } = frameworkAdapter(...args);
9
+ await bot.updates.handleUpdate(update);
10
+ };
11
+ }
12
+ exports.webhookHandler = webhookHandler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gramio",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "Powerful Telegram Bot API framework",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -25,19 +25,18 @@
25
25
  "license": "ISC",
26
26
  "devDependencies": {
27
27
  "@biomejs/biome": "1.5.3",
28
- "@gramio/types": "^7.1.3",
28
+ "@gramio/types": "^7.1.4",
29
29
  "@types/node": "^20.11.20",
30
30
  "typescript": "^5.3.3"
31
31
  },
32
32
  "dependencies": {
33
- "@gramio/contexts": "^0.0.5",
33
+ "@gramio/contexts": "^0.0.6",
34
34
  "@gramio/files": "^0.0.3",
35
35
  "@gramio/format": "^0.0.8",
36
- "@gramio/keyboards": "^0.1.6",
36
+ "@gramio/keyboards": "^0.2.0",
37
37
  "form-data-encoder": "^4.0.2",
38
- "inspectable": "^2.1.0",
38
+ "inspectable": "^3.0.0",
39
39
  "middleware-io": "^2.8.1",
40
- "reflect-metadata": "^0.2.1",
41
40
  "undici": "^6.6.2"
42
41
  },
43
42
  "files": [