gramio 0.0.1 → 0.0.3
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/README.md +0 -0
- package/dist/apiErrors.d.ts +12 -0
- package/dist/apiErrors.js +21 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +71 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +2 -0
- package/dist/updates.d.ts +17 -0
- package/dist/updates.js +75 -0
- package/package.json +15 -13
package/README.md
CHANGED
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { TelegramAPIResponseError } from "@gramio/types";
|
|
2
|
+
export interface APIErrorDetails {
|
|
3
|
+
method: string;
|
|
4
|
+
params: Record<string, any>;
|
|
5
|
+
}
|
|
6
|
+
export declare class APIError extends Error {
|
|
7
|
+
method: string;
|
|
8
|
+
params: Record<string, any>;
|
|
9
|
+
code: number;
|
|
10
|
+
payload?: TelegramAPIResponseError["parameters"];
|
|
11
|
+
constructor({ method, params }: APIErrorDetails, error: TelegramAPIResponseError);
|
|
12
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.APIError = void 0;
|
|
4
|
+
//TODO: more elegant
|
|
5
|
+
class APIError extends Error {
|
|
6
|
+
method;
|
|
7
|
+
params;
|
|
8
|
+
code;
|
|
9
|
+
payload;
|
|
10
|
+
constructor({ method, params }, error) {
|
|
11
|
+
super(error.description);
|
|
12
|
+
this.name = method;
|
|
13
|
+
this.method = method;
|
|
14
|
+
this.params = params;
|
|
15
|
+
this.code = error.error_code;
|
|
16
|
+
//TODO: delete when undefined
|
|
17
|
+
if (error.parameters)
|
|
18
|
+
this.payload = error.parameters;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.APIError = APIError;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ApiMethods } from "@gramio/types";
|
|
2
|
+
import "reflect-metadata";
|
|
3
|
+
import { BotOptions } from "./types";
|
|
4
|
+
import { Updates } from "./updates";
|
|
5
|
+
export declare class Bot {
|
|
6
|
+
readonly options: BotOptions;
|
|
7
|
+
readonly api: ApiMethods;
|
|
8
|
+
updates: Updates;
|
|
9
|
+
private _callApi;
|
|
10
|
+
constructor(token: string, options?: Omit<BotOptions, "token">);
|
|
11
|
+
}
|
|
12
|
+
export * from "@gramio/types";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
14
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
15
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
16
|
+
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;
|
|
17
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
18
|
+
};
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.Bot = void 0;
|
|
24
|
+
const files_1 = require("@gramio/files");
|
|
25
|
+
const form_data_encoder_1 = require("form-data-encoder");
|
|
26
|
+
const inspectable_1 = require("inspectable");
|
|
27
|
+
require("reflect-metadata");
|
|
28
|
+
const undici_1 = require("undici");
|
|
29
|
+
const apiErrors_1 = require("./apiErrors");
|
|
30
|
+
const updates_1 = require("./updates");
|
|
31
|
+
let Bot = class Bot {
|
|
32
|
+
options = {};
|
|
33
|
+
api = new Proxy({}, {
|
|
34
|
+
get: (_target, method) => (args) => this._callApi(method, args),
|
|
35
|
+
});
|
|
36
|
+
updates = new updates_1.Updates(this);
|
|
37
|
+
async _callApi(method, params = {}) {
|
|
38
|
+
const url = `https://api.telegram.org/bot${this.options.token}/${method}`;
|
|
39
|
+
const reqOptions = {
|
|
40
|
+
method: "POST",
|
|
41
|
+
duplex: "half",
|
|
42
|
+
};
|
|
43
|
+
if ((0, files_1.isMediaUpload)(method, params)) {
|
|
44
|
+
const formData = await (0, files_1.convertJsonToFormData)(method, params);
|
|
45
|
+
const encoder = new form_data_encoder_1.FormDataEncoder(formData);
|
|
46
|
+
reqOptions.body = encoder.encode();
|
|
47
|
+
reqOptions.headers = encoder.headers;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
reqOptions.headers = {
|
|
51
|
+
"Content-Type": "application/json",
|
|
52
|
+
};
|
|
53
|
+
reqOptions.body = JSON.stringify(params);
|
|
54
|
+
}
|
|
55
|
+
const response = await (0, undici_1.fetch)(url, reqOptions);
|
|
56
|
+
const data = (await response.json());
|
|
57
|
+
if (!data.ok)
|
|
58
|
+
throw new apiErrors_1.APIError({ method, params }, data);
|
|
59
|
+
return data.result;
|
|
60
|
+
}
|
|
61
|
+
constructor(token, options) {
|
|
62
|
+
this.options = { ...options, token };
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.Bot = Bot;
|
|
66
|
+
exports.Bot = Bot = __decorate([
|
|
67
|
+
(0, inspectable_1.Inspectable)({
|
|
68
|
+
serialize: () => ({}),
|
|
69
|
+
})
|
|
70
|
+
], Bot);
|
|
71
|
+
__exportStar(require("@gramio/types"), exports);
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { contextsMappings } from "@gramio/contexts";
|
|
2
|
+
import { NextMiddleware } from "middleware-io";
|
|
3
|
+
export interface BotOptions {
|
|
4
|
+
token?: string;
|
|
5
|
+
}
|
|
6
|
+
export type THandler<T> = (context: T, next: NextMiddleware) => unknown;
|
|
7
|
+
export type UpdateNames = keyof typeof contextsMappings;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Context, contextsMappings } from "@gramio/contexts";
|
|
2
|
+
import type { TelegramUpdate } from "@gramio/types";
|
|
3
|
+
import { Bot } from ".";
|
|
4
|
+
import { THandler, UpdateNames } from "./types";
|
|
5
|
+
export declare class Updates {
|
|
6
|
+
private readonly bot;
|
|
7
|
+
private isStarted;
|
|
8
|
+
private offset;
|
|
9
|
+
private composer;
|
|
10
|
+
constructor(bot: Bot);
|
|
11
|
+
on<T extends UpdateNames>(updateName: T, handler: THandler<InstanceType<(typeof contextsMappings)[T]>>): this;
|
|
12
|
+
use(handler: THandler<Context>): this;
|
|
13
|
+
handleUpdate(data: TelegramUpdate): Promise<void>;
|
|
14
|
+
startPolling(): Promise<null>;
|
|
15
|
+
startFetchLoop(): Promise<void>;
|
|
16
|
+
stopPolling(): void;
|
|
17
|
+
}
|
package/dist/updates.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Updates = void 0;
|
|
4
|
+
const contexts_1 = require("@gramio/contexts");
|
|
5
|
+
const middleware_io_1 = require("middleware-io");
|
|
6
|
+
class Updates {
|
|
7
|
+
bot;
|
|
8
|
+
isStarted = false;
|
|
9
|
+
offset = 0;
|
|
10
|
+
composer = middleware_io_1.Composer.builder();
|
|
11
|
+
constructor(bot) {
|
|
12
|
+
this.bot = bot;
|
|
13
|
+
}
|
|
14
|
+
on(updateName, handler) {
|
|
15
|
+
return this.use((context, next) => {
|
|
16
|
+
//TODO: fix typings
|
|
17
|
+
if (context.is(updateName))
|
|
18
|
+
handler(context, next);
|
|
19
|
+
else
|
|
20
|
+
next();
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
use(handler) {
|
|
24
|
+
this.composer.use(handler);
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
async handleUpdate(data) {
|
|
28
|
+
const updateType = Object.keys(data).at(1);
|
|
29
|
+
this.offset = data.update_id + 1;
|
|
30
|
+
try {
|
|
31
|
+
const context = new contexts_1.contextsMappings[updateType]({
|
|
32
|
+
bot: this.bot,
|
|
33
|
+
update: data,
|
|
34
|
+
//TODO: fix
|
|
35
|
+
//@ts-ignore
|
|
36
|
+
payload: data[updateType],
|
|
37
|
+
type: updateType,
|
|
38
|
+
updateId: data.update_id,
|
|
39
|
+
// raw: {
|
|
40
|
+
// update: data,
|
|
41
|
+
// updateId: data.update_id,
|
|
42
|
+
// updateType,
|
|
43
|
+
// },
|
|
44
|
+
});
|
|
45
|
+
this.composer.compose()(
|
|
46
|
+
//TODO: fix typings
|
|
47
|
+
context, middleware_io_1.noopNext);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`Update type ${updateType} not supported.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async startPolling() {
|
|
54
|
+
if (this.isStarted)
|
|
55
|
+
throw new Error("[UPDATES] Polling already started!");
|
|
56
|
+
this.isStarted = true;
|
|
57
|
+
this.startFetchLoop();
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
async startFetchLoop() {
|
|
61
|
+
while (this.isStarted) {
|
|
62
|
+
const updates = await this.bot.api.getUpdates({
|
|
63
|
+
offset: this.offset,
|
|
64
|
+
});
|
|
65
|
+
for await (const update of updates) {
|
|
66
|
+
//TODO: update errors
|
|
67
|
+
await this.handleUpdate(update).catch(console.error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
stopPolling() {
|
|
72
|
+
this.isStarted = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.Updates = Updates;
|
package/package.json
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gramio",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "WIP",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
6
7
|
"scripts": {
|
|
7
|
-
"
|
|
8
|
-
"lint": "
|
|
9
|
-
"lint:fix": "eslint \"src/**/*.{js,ts}\" --fix"
|
|
8
|
+
"lint": "bun check ./src",
|
|
9
|
+
"lint:fix": "bun lint --apply"
|
|
10
10
|
},
|
|
11
11
|
"author": "kravets",
|
|
12
12
|
"license": "ISC",
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@
|
|
15
|
-
"@types
|
|
16
|
-
"
|
|
17
|
-
"eslint-kit": "^10.6.0",
|
|
18
|
-
"prettier": "^3.0.3"
|
|
14
|
+
"@biomejs/biome": "1.5.3",
|
|
15
|
+
"@gramio/types": "^7.0.14",
|
|
16
|
+
"@types/node": "^20.11.17"
|
|
19
17
|
},
|
|
20
18
|
"dependencies": {
|
|
19
|
+
"@gramio/contexts": "^0.0.1",
|
|
20
|
+
"form-data-encoder": "^4.0.2",
|
|
21
21
|
"inspectable": "^2.1.0",
|
|
22
22
|
"middleware-io": "^2.8.1",
|
|
23
|
-
"reflect-metadata": "^0.1
|
|
24
|
-
"undici": "^
|
|
23
|
+
"reflect-metadata": "^0.2.1",
|
|
24
|
+
"undici": "^6.6.2"
|
|
25
25
|
},
|
|
26
|
-
"files": [
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
]
|
|
27
29
|
}
|