From 4ee65bc8fccdb7fe408a9780cfe6349f2c63c7d4 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 20:37:55 +0500 Subject: [PATCH 1/9] feat: convert node.js, and remove deno project --- .gitignore | 15 +- .idea/.gitignore | 8 + .idea/modules.xml | 8 + .idea/telegram.iml | 12 + .idea/vcs.xml | 6 + README.md | 43 +- core.ts | 76 -- default.nix | 28 - delta/mod.ts | 31 - deno.json | 9 - deno.lock | 227 ---- deps.ts | 17 - flake.lock | 61 -- flake.nix | 40 - justfile | 16 - mod.ts | 1 - package-lock.json | 1635 +++++++++++++++++++++++++++++ package.json | 31 + shell.nix | 54 - src/core.ts | 76 ++ {delta => src/delta}/about.ts | 8 +- {delta => src/delta}/code.ts | 7 +- {delta => src/delta}/feedback.ts | 7 +- {delta => src/delta}/groups.ts | 26 +- {delta => src/delta}/help.ts | 8 +- {delta => src/delta}/honor.ts | 8 +- {delta => src/delta}/inline.ts | 7 +- src/delta/mod.ts | 31 + {delta => src/delta}/rules.ts | 8 +- {delta => src/delta}/start.ts | 6 +- {delta => src/delta}/text.ts | 5 +- {delta => src/delta}/trigger.ts | 9 +- {delta => src/delta}/warrior.ts | 10 +- {delta => src/delta}/which.ts | 8 +- src/deps.ts | 9 + {hooks => src/hooks}/isAdmin.ts | 2 +- {hooks => src/hooks}/isGroup.ts | 2 +- {hooks => src/hooks}/isHome.ts | 4 +- {hooks => src/hooks}/isPrivate.ts | 4 +- {hooks => src/hooks}/isReply.ts | 6 +- {hooks => src/hooks}/isUwU.ts | 4 +- src/index.ts | 2 + src/mod.ts | 2 + src/topics.json | 20 + {types => src/types}/Pacman.ts | 34 +- {types => src/types}/Tealdeer.ts | 15 +- src/utils/cli.ts | 9 + {utils => src/utils}/config.ts | 13 +- {utils => src/utils}/normalize.ts | 9 +- {utils => src/utils}/sender.ts | 7 +- tsconfig.json | 19 + utils/cli.ts | 5 - 52 files changed, 2040 insertions(+), 668 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/modules.xml create mode 100644 .idea/telegram.iml create mode 100644 .idea/vcs.xml delete mode 100755 core.ts delete mode 100644 default.nix delete mode 100755 delta/mod.ts delete mode 100755 deno.json delete mode 100644 deno.lock delete mode 100755 deps.ts delete mode 100644 flake.lock delete mode 100644 flake.nix delete mode 100755 justfile delete mode 100755 mod.ts create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 shell.nix create mode 100644 src/core.ts rename {delta => src/delta}/about.ts (79%) mode change 100755 => 100644 rename {delta => src/delta}/code.ts (93%) mode change 100755 => 100644 rename {delta => src/delta}/feedback.ts (78%) mode change 100755 => 100644 rename {delta => src/delta}/groups.ts (78%) mode change 100755 => 100644 rename {delta => src/delta}/help.ts (86%) mode change 100755 => 100644 rename {delta => src/delta}/honor.ts (81%) mode change 100755 => 100644 rename {delta => src/delta}/inline.ts (83%) mode change 100755 => 100644 create mode 100644 src/delta/mod.ts rename {delta => src/delta}/rules.ts (85%) mode change 100755 => 100644 rename {delta => src/delta}/start.ts (83%) mode change 100755 => 100644 rename {delta => src/delta}/text.ts (79%) mode change 100755 => 100644 rename {delta => src/delta}/trigger.ts (92%) mode change 100755 => 100644 rename {delta => src/delta}/warrior.ts (74%) mode change 100755 => 100644 rename {delta => src/delta}/which.ts (80%) mode change 100755 => 100644 create mode 100644 src/deps.ts rename {hooks => src/hooks}/isAdmin.ts (86%) mode change 100755 => 100644 rename {hooks => src/hooks}/isGroup.ts (78%) mode change 100755 => 100644 rename {hooks => src/hooks}/isHome.ts (75%) mode change 100755 => 100644 rename {hooks => src/hooks}/isPrivate.ts (74%) mode change 100755 => 100644 rename {hooks => src/hooks}/isReply.ts (64%) mode change 100755 => 100644 rename {hooks => src/hooks}/isUwU.ts (68%) mode change 100755 => 100644 create mode 100644 src/index.ts create mode 100644 src/mod.ts create mode 100755 src/topics.json rename {types => src/types}/Pacman.ts (81%) mode change 100755 => 100644 rename {types => src/types}/Tealdeer.ts (94%) mode change 100755 => 100644 create mode 100644 src/utils/cli.ts rename {utils => src/utils}/config.ts (77%) rename {utils => src/utils}/normalize.ts (78%) mode change 100755 => 100644 rename {utils => src/utils}/sender.ts (71%) mode change 100755 => 100644 create mode 100644 tsconfig.json delete mode 100644 utils/cli.ts diff --git a/.gitignore b/.gitignore index a0120c6..397b0d9 100755 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,5 @@ -# Direnv garbage -.direnv - -# Environmental files +node_modules/ +dist/ +*.log .env - -# Editors -.idea -.vscode - -# Data file -config.toml +.DS_Store diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c79c77a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/telegram.iml b/.idea/telegram.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/telegram.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 14cab6f..5fc6594 100755 --- a/README.md +++ b/README.md @@ -16,29 +16,46 @@ Ecma Uzbekistan consists of sub-communities which needs moderation tools like te ## Development -This project has everything configured ready to get started with developer right away thanks to Nix package manager. In order to get started: +This project has been migrated to Node.js with Grammy.js. To get started: ```bash -# Start development environment -nix develop -c $SHELL +# Install dependencies +npm install -# Open favorite editor of your choice -zed . +# Create a config.toml file with your bot token +# Example: +# token = "YOUR_BOT_TOKEN" +# mode = "polling" +# host = "https://your-domain.com" +# port = 8000 -# Start development server -npm run dev +# Start development server with hot reload +npm run dev -- --config config.toml + +# Or build and run in production +npm run build +npm run start -- --config config.toml ``` -## Building +## Configuration -This project aims to build standalone javascript and deployed in [Kolyma Labs](https://github.com/kolyma-labs). Kolyma's NixOS server gets `nix build` output, but you can build it inside development environment using `npm` package manager. +Create a `config.toml` file with your bot configuration: -```bash -# Building with nix` -nix build . +```toml +token = "YOUR_BOT_TOKEN_HERE" +host = "127.0.0.1" +port = 8000 +mode = "polling" +``` -# Building with npm +## Building + +```bash +# Build for production npm run build + +# Start production server +npm start -- --config config.toml ``` ## Thanks diff --git a/core.ts b/core.ts deleted file mode 100755 index e94a7c8..0000000 --- a/core.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { blue, Bot, webhookCallback } from "./deps.ts"; -import "./utils/config.ts"; -import delta from "./delta/mod.ts"; -import { Config, Configs } from "./utils/config.ts"; -import args from "./utils/cli.ts"; - -export const handle = (bot: Bot) => webhookCallback(bot, "std/http"); - -const webhook = (bot: Bot, config: Configs) => { - console.log(blue("[INFO]"), `bot is starting on ${config.mode}`); - - Deno.serve({ - port: config.port, - hostname: "127.0.0.1", - }, async (req) => { - const url = new URL(req.url); - - console.log(config); - - if (req.method === "POST") { - if (url.pathname.slice(1) === bot.token) { - try { - return await handle(bot)(req); - } catch (err) { - console.error(err); - } - } - } - - if (req.method === "GET") { - try { - await bot.api.setWebhook(`${config.host}/${bot.token}`); - return new Response("Done. Set"); - } catch (_) { - return new Response("Couldn't succeed with installing webhook"); - } - } - - return new Response("What you're trying to post?"); - }); -}; - -const polling = async (bot: Bot) => { - await bot.start(); -}; - -export const launch = async () => { - if (args.config == undefined) { - console.log("Path to config file is not defined!"); - Deno.exit(1); - } - - const config = new Config(args.config); - await config.consume(); - - const data: Configs = config.data(); - const bot = new Bot(data.token); - - delta(bot); - bot.catch((error) => { - console.log(error, error.ctx.api); - }); - - switch (data.mode) { - case "webhook": - webhook(bot, data); - break; - case "polling": - await polling(bot); - break; - default: - throw new Error("Deploy method not validated!"); - } -}; - -await launch(); diff --git a/default.nix b/default.nix deleted file mode 100644 index 5e63508..0000000 --- a/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{pkgs ? import {}, ...}: let - lib = pkgs.lib; -in - pkgs.stdenv.mkDerivation { - pname = "telegram"; - version = "0.0.1"; - - src = ./.; - - buildInputs = with pkgs; [ - deno - ]; - - buildPhase = '' - deno compile ./mod.ts - ''; - - installPhase = '' - mkdir -p $out/bin - echo "something" > $out/bin/something - ''; - - meta = with lib; { - homepage = "https://ecma.uz"; - description = "Telergam bot of Ecma Uzbekistan"; - platforms = with platforms; darwin ++ linux; - }; - } diff --git a/delta/mod.ts b/delta/mod.ts deleted file mode 100755 index b69224c..0000000 --- a/delta/mod.ts +++ /dev/null @@ -1,31 +0,0 @@ -import start from "./start.ts"; -import help from "./help.ts"; -import inline from "./inline.ts"; -import which from "./which.ts"; -import { Bot } from "../deps.ts"; -import about from "./about.ts"; -import rules from "./rules.ts"; -import text from "./text.ts"; -import groups from "./groups.ts"; -import honor from "./honor.ts"; -import warrior from "./warrior.ts"; -import trigger from "./trigger.ts"; -import feedback from "./feedback.ts"; -import code from "./code.ts"; - -export default (bot: Bot) => { - bot - .use(start) - .use(honor) - .use(help) - .use(groups) - .use(inline) - .use(which) - .use(about) - .use(rules) - .use(feedback) - .use(warrior) - .use(trigger) - .use(code) - .use(text); -}; diff --git a/deno.json b/deno.json deleted file mode 100755 index 8973394..0000000 --- a/deno.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "fmt": { - "files": { - "exclude": [ - "all.json" - ] - } - } -} diff --git a/deno.lock b/deno.lock deleted file mode 100644 index dc665af..0000000 --- a/deno.lock +++ /dev/null @@ -1,227 +0,0 @@ -{ - "version": "4", - "specifiers": { - "jsr:@std/cli@*": "1.0.17", - "jsr:@std/cli@^1.0.17": "1.0.17", - "jsr:@std/collections@^1.0.11": "1.0.11", - "jsr:@std/encoding@^1.0.10": "1.0.10", - "jsr:@std/fmt@*": "1.0.7", - "jsr:@std/fmt@^1.0.7": "1.0.7", - "jsr:@std/fs@*": "1.0.17", - "jsr:@std/html@^1.0.3": "1.0.3", - "jsr:@std/http@*": "1.0.15", - "jsr:@std/media-types@^1.1.0": "1.1.0", - "jsr:@std/net@^1.0.4": "1.0.4", - "jsr:@std/path@^1.0.9": "1.0.9", - "jsr:@std/streams@^1.0.9": "1.0.9", - "jsr:@std/toml@*": "1.0.5" - }, - "jsr": { - "@std/cli@1.0.17": { - "integrity": "e15b9abe629e17be90cc6216327f03a29eae613365f1353837fa749aad29ce7b" - }, - "@std/collections@1.0.11": { - "integrity": "2f62cf9587484b1fff364f6c3e1f83478eea53dbb6faed6ffeda92ddb6b172f0" - }, - "@std/encoding@1.0.10": { - "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" - }, - "@std/fmt@1.0.7": { - "integrity": "2a727c043d8df62cd0b819b3fb709b64dd622e42c3b1bb817ea7e6cc606360fb" - }, - "@std/fs@1.0.17": { - "integrity": "1c00c632677c1158988ef7a004cb16137f870aafdb8163b9dce86ec652f3952b" - }, - "@std/html@1.0.3": { - "integrity": "7a0ac35e050431fb49d44e61c8b8aac1ebd55937e0dc9ec6409aa4bab39a7988" - }, - "@std/http@1.0.15": { - "integrity": "435a4934b4e196e82a8233f724da525f7b7112f3566502f28815e94764c19159", - "dependencies": [ - "jsr:@std/cli@^1.0.17", - "jsr:@std/encoding", - "jsr:@std/fmt@^1.0.7", - "jsr:@std/html", - "jsr:@std/media-types", - "jsr:@std/net", - "jsr:@std/path", - "jsr:@std/streams" - ] - }, - "@std/media-types@1.1.0": { - "integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4" - }, - "@std/net@1.0.4": { - "integrity": "2f403b455ebbccf83d8a027d29c5a9e3a2452fea39bb2da7f2c04af09c8bc852" - }, - "@std/path@1.0.9": { - "integrity": "260a49f11edd3db93dd38350bf9cd1b4d1366afa98e81b86167b4e3dd750129e" - }, - "@std/streams@1.0.9": { - "integrity": "a9d26b1988cdd7aa7b1f4b51e1c36c1557f3f252880fa6cc5b9f37078b1a5035" - }, - "@std/toml@1.0.5": { - "integrity": "08061156e9c5716443a144b6e40a8668738b8b424ad99ab0b6fdf1b6ea4da806", - "dependencies": [ - "jsr:@std/collections" - ] - } - }, - "remote": { - "https://cdn.skypack.dev/-/debug@v4.3.4-o4liVvMlOnQWbLSYZMXw/dist=es2019,mode=imports/optimized/debug.js": "671100993996e39b501301a87000607916d4d2d9f8fc8e9c5200ae5ba64a1389", - "https://cdn.skypack.dev/-/ms@v2.1.2-giBDZ1IA5lmQ3ZXaa87V/dist=es2019,mode=imports/optimized/ms.js": "fd88e2d51900437011f1ad232f3393ce97db1b87a7844b3c58dd6d65562c1276", - "https://cdn.skypack.dev/debug@4.3.4": "7b1d010cc930f71b940ba5941da055bc181115229e29de7214bdb4425c68ea76", - "https://deno.land/std@0.178.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", - "https://deno.land/std@0.178.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", - "https://deno.land/std@0.178.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8", - "https://deno.land/std@0.178.0/bytes/bytes_list.ts": "b4cbdfd2c263a13e8a904b12d082f6177ea97d9297274a4be134e989450dfa6a", - "https://deno.land/std@0.178.0/bytes/copy.ts": "939d89e302a9761dcf1d9c937c7711174ed74c59eef40a1e4569a05c9de88219", - "https://deno.land/std@0.178.0/io/buffer.ts": "e2b7564f684dad625cab08f5106f33572d325705d19a36822b3272fbdfb8f726", - "https://deno.land/std@0.178.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", - "https://deno.land/std@0.178.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", - "https://deno.land/std@0.178.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", - "https://deno.land/std@0.178.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", - "https://deno.land/std@0.178.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", - "https://deno.land/std@0.178.0/path/mod.ts": "4b83694ac500d7d31b0cdafc927080a53dc0c3027eb2895790fb155082b0d232", - "https://deno.land/std@0.178.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", - "https://deno.land/std@0.178.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", - "https://deno.land/std@0.178.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", - "https://deno.land/std@0.178.0/streams/_common.ts": "f45cba84f0d813de3326466095539602364a9ba521f804cc758f7a475cda692d", - "https://deno.land/std@0.178.0/streams/buffer.ts": "7e7676c29e0e72f6821c3b5fede2540886a216bb91c849bb5db20bb82a01d8a1", - "https://deno.land/std@0.178.0/streams/byte_slice_stream.ts": "cf5785b0d9223ebb51fcf6679d881dfaf614c3b288fb4577b511b6f7801a01aa", - "https://deno.land/std@0.178.0/streams/copy.ts": "de0de21701d8cceba84ca01d9731c77f4b3597bb9de6a1b08f32250353feeae8", - "https://deno.land/std@0.178.0/streams/delimiter_stream.ts": "de8f822a1c394cdb805a97e364400955cd1757cc282d932b4040a0f78fba3b5f", - "https://deno.land/std@0.178.0/streams/early_zip_readable_streams.ts": "64828085be5812ec5f4896c10b59f14e5a322b2c0439be9331dde332ae9c91de", - "https://deno.land/std@0.178.0/streams/iterate_reader.ts": "06491ed8f1bb1c619abbfa04c10b173ff95a93e51fe5037b7c1ad0b5cc01fc7d", - "https://deno.land/std@0.178.0/streams/limited_bytes_transform_stream.ts": "3bc04143b8b91a923f5ee81a3c618b6606ac7da66ccbcde62a67aaa0375cbc71", - "https://deno.land/std@0.178.0/streams/limited_transform_stream.ts": "b336f5d649a06e35e2692849e3682a673bb32531738443eb2ce9f57538722f75", - "https://deno.land/std@0.178.0/streams/merge_readable_streams.ts": "5d6302888f4bb0616dafb5768771be0aec9bedc05fbae6b3d726d05ffbec5b15", - "https://deno.land/std@0.178.0/streams/mod.ts": "c07ec010e700b9ea887dc36ca08729828bc7912f711e4054e24d33fd46282252", - "https://deno.land/std@0.178.0/streams/read_all.ts": "bfa220b0e1d06fa4d0cb5178baba8f8b466019a7411511982bfa2320ca292815", - "https://deno.land/std@0.178.0/streams/readable_stream_from_iterable.ts": "cae337ddafd2abc5e3df699ef2af888ac04091f12732ae658448fba2c7b187e8", - "https://deno.land/std@0.178.0/streams/readable_stream_from_reader.ts": "9aceaeefa9e04b08f56b2d07272baedc3b6432840b66198d72fa2ada3e6608ea", - "https://deno.land/std@0.178.0/streams/reader_from_iterable.ts": "05f7759b9336fd4c233d9daadf92aec9a7d2c07a05986da466a935cec2dd79d9", - "https://deno.land/std@0.178.0/streams/reader_from_stream_reader.ts": "3fda9390ec8520c8a9ea2aba2579208b18880a7663d7a9feec8f193b7af14e41", - "https://deno.land/std@0.178.0/streams/text_delimiter_stream.ts": "ee216316360366c3744197f5665a066a25e6baa8cfe836fbe9a0033e079e089e", - "https://deno.land/std@0.178.0/streams/text_line_stream.ts": "a9dd2636c6b90e626e19df26c97034c5f638bdd957cbd5c531d6278fe1d08e90", - "https://deno.land/std@0.178.0/streams/to_transform_stream.ts": "31c8cce967a2f602be5f164973a5c6cedd4c76e1d2fbc22ae0081b084f73fb0e", - "https://deno.land/std@0.178.0/streams/writable_stream_from_writer.ts": "0320b759aa343f9f4f58b014fe301d9a7abcbfb8413d260502a885995e6a0776", - "https://deno.land/std@0.178.0/streams/write_all.ts": "3b2e1ce44913f966348ce353d02fa5369e94115181037cd8b602510853ec3033", - "https://deno.land/std@0.178.0/streams/writer_from_stream_writer.ts": "31126a6bf2e678c5a718011d4831dbe75dbdbd885965d3dbd5dd105e6f20f976", - "https://deno.land/std@0.178.0/streams/zip_readable_streams.ts": "9eb82070d83055fe6f077192fb204dc7612695a4b330148e9aa376df1a65e708", - "https://deno.land/std@0.178.0/types.d.ts": "220ed56662a0bd393ba5d124aa6ae2ad36a00d2fcbc0e8666a65f4606aaa9784", - "https://deno.land/std@0.179.0/async/abortable.ts": "73acfb3ed7261ce0d930dbe89e43db8d34e017b063cf0eaa7d215477bf53442e", - "https://deno.land/std@0.179.0/async/deadline.ts": "c5facb0b404eede83e38bd2717ea8ab34faa2ffb20ef87fd261fcba32ba307aa", - "https://deno.land/std@0.179.0/async/debounce.ts": "adab11d04ca38d699444ac8a9d9856b4155e8dda2afd07ce78276c01ea5a4332", - "https://deno.land/std@0.179.0/async/deferred.ts": "42790112f36a75a57db4a96d33974a936deb7b04d25c6084a9fa8a49f135def8", - "https://deno.land/std@0.179.0/async/delay.ts": "73aa04cec034c84fc748c7be49bb15cac3dd43a57174bfdb7a4aec22c248f0dd", - "https://deno.land/std@0.179.0/async/mod.ts": "f04344fa21738e5ad6bea37a6bfffd57c617c2d372bb9f9dcfd118a1b622e576", - "https://deno.land/std@0.179.0/async/mux_async_iterator.ts": "70c7f2ee4e9466161350473ad61cac0b9f115cff4c552eaa7ef9d50c4cbb4cc9", - "https://deno.land/std@0.179.0/async/pool.ts": "fd082bd4aaf26445909889435a5c74334c017847842ec035739b4ae637ae8260", - "https://deno.land/std@0.179.0/async/retry.ts": "5efa3ba450ac0c07a40a82e2df296287b5013755d232049efd7ea2244f15b20f", - "https://deno.land/std@0.179.0/async/tee.ts": "47e42d35f622650b02234d43803d0383a89eb4387e1b83b5a40106d18ae36757", - "https://deno.land/std@0.179.0/fmt/colors.ts": "938c5d44d889fb82eff6c358bea8baa7e85950a16c9f6dae3ec3a7a729164471", - "https://deno.land/std@0.179.0/http/server.ts": "cbb17b594651215ba95c01a395700684e569c165a567e4e04bba327f41197433", - "https://deno.land/std@0.211.0/path/_common/assert_path.ts": "2ca275f36ac1788b2acb60fb2b79cb06027198bc2ba6fb7e163efaedde98c297", - "https://deno.land/std@0.211.0/path/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2", - "https://deno.land/std@0.211.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c", - "https://deno.land/std@0.211.0/path/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a", - "https://deno.land/std@0.211.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15", - "https://deno.land/std@0.211.0/path/basename.ts": "5d341aadb7ada266e2280561692c165771d071c98746fcb66da928870cd47668", - "https://deno.land/std@0.211.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d", - "https://deno.land/std@0.211.0/path/posix/basename.ts": "39ee27a29f1f35935d3603ccf01d53f3d6e0c5d4d0f84421e65bd1afeff42843", - "https://deno.land/std@0.211.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808", - "https://deno.land/std@0.211.0/path/windows/basename.ts": "e2dbf31d1d6385bfab1ce38c333aa290b6d7ae9e0ecb8234a654e583cf22f8fe", - "https://deno.land/x/deno_dom@v0.1.33-alpha/build/deno-wasm/deno-wasm.js": "b3ba6f2047b5fd8424292408c6c6ad2cb8c56a22984fdaceea2333a727bece25", - "https://deno.land/x/deno_dom@v0.1.33-alpha/deno-dom-wasm.ts": "bfd999a493a6974e9fca4d331bee03bfb68cfc600c662cd0b48b21d67a2a8ba0", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/api.ts": "0ff5790f0a3eeecb4e00b7d8fbfa319b165962cf6d0182a65ba90f158d74f7d7", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/constructor-lock.ts": "59714df7e0571ec7bd338903b1f396202771a6d4d7f55a452936bd0de9deb186", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/deserialize.ts": "f4d34514ca00473ca428b69ad437ba345925744b5d791cb9552e2d7a0e7b0439", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/document-fragment.ts": "a40c6e18dd0efcf749a31552c1c9a6f7fa614452245e86ee38fc92ba0235e5ae", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/document.ts": "bcb96378097106d82e0d1a356496baea1b73f92dd7d492e6ed655016025665df", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/dom-parser.ts": "609097b426f8c2358f3e5d2bca55ed026cf26cdf86562e94130dfdb0f2537f92", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/element.ts": "312ae401081e6ce11cf62a854c0f78388e4be46579c1fdd9c1d118bc9c79db38", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/elements/html-template-element.ts": "19ad97c55222115e8daaca2788b9c98cc31a7f9d2547ed5bca0c56a4a12bfec8", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/html-collection.ts": "ae90197f5270c32074926ad6cf30ee07d274d44596c7e413c354880cebce8565", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/node-list.ts": "d9c07baf0acc383112cbabafacf26a0aedb04d0866645e7485f5ab23e470b6f8", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/node.ts": "778b7cf182105ae2c39a7d0b44aaea701c0af35e85b7cfa5e8b38f8bd67f7ad4", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/custom-api.ts": "852696bd58e534bc41bd3be9e2250b60b67cd95fd28ed16b1deff1d548531a71", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/nwsapi-types.ts": "c43b36c36acc5d32caabaa54fda8c9d239b2b0fcbce9a28efb93c84aa1021698", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/nwsapi.js": "985d7d8fc1eabbb88946b47a1c44c1b2d4aa79ff23c21424219f1528fa27a2ff", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/selectors.ts": "83eab57be2290fb48e3130533448c93c6c61239f2a2f3b85f1917f80ca0fdc75", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/sizzle-types.ts": "78149e2502409989ce861ed636b813b059e16bc267bb543e7c2b26ef43e4798b", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/selectors/sizzle.js": "c3aed60c1045a106d8e546ac2f85cc82e65f62d9af2f8f515210b9212286682a", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/utils-types.ts": "96db30e3e4a75b194201bb9fa30988215da7f91b380fca6a5143e51ece2a8436", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/dom/utils.ts": "ecd889ba74f3ce282620d8ca1d4d5e0365e6cc86101d2352f3bbf936ae496e2c", - "https://deno.land/x/deno_dom@v0.1.33-alpha/src/parser.ts": "b65eb7e673fa7ca611de871de109655f0aa9fa35ddc1de73df1a5fc2baafc332", - "https://deno.land/x/dotenv@v3.2.0/mod.ts": "077b48773de9205266a0b44c3c3a3c3083449ed64bb0b6cc461b95720678d38e", - "https://deno.land/x/dotenv@v3.2.0/util.ts": "693730877b13f8ead2b79b2aa31e2a0652862f7dc0c5f6d2f313f4d39c7b7670", - "https://deno.land/x/fuse@v6.4.1/dist/fuse.esm.js": "15050048306354349cf4eaf673774d010eba47c0303c80e5847d31733c999c65", - "https://deno.land/x/grammy@v1.15.1/bot.ts": "48a3a6e597b0e08ba89927443a048146ff371feeaf348cf650a6421354ce4ead", - "https://deno.land/x/grammy@v1.15.1/composer.ts": "1d2e164f9934466553d7f9bf9bf2fe65a1f453b7f7ce3cf57066d87382c6dac2", - "https://deno.land/x/grammy@v1.15.1/context.ts": "72df84eef4f159aef06dab536d0d27beba38534769416d4b1099ce535b0767d0", - "https://deno.land/x/grammy@v1.15.1/convenience/frameworks.ts": "f89568f28835aaba764a62e1501c8d625ead88d4bfb1f1ba9fd4c4ca2234820f", - "https://deno.land/x/grammy@v1.15.1/convenience/keyboard.ts": "a794e8bc4b39670bf320410e6bd30fc42aed3c4e5e28d55a909300f29f3f872d", - "https://deno.land/x/grammy@v1.15.1/convenience/session.ts": "ae65f3a12ce20286f0e83e2145c05a10f6ab85255fcda90194d674029679d3db", - "https://deno.land/x/grammy@v1.15.1/convenience/webhook.ts": "f1da7d6426171fb7b5d5f6b59633f91d3bab9a474eea821f714932650965eb9e", - "https://deno.land/x/grammy@v1.15.1/core/api.ts": "67b5f06cc9d627b7ffa772ff1fbd7398e943abb42f321c91c78836ac6afe2794", - "https://deno.land/x/grammy@v1.15.1/core/client.ts": "8914f13b2cb69f16104a9711e4fea0a4500edd0950736dcc3ac078ab46f7a5ab", - "https://deno.land/x/grammy@v1.15.1/core/error.ts": "4638b2127ebe60249c78b83011d468f5e1e1a87748d32fe11a8200d9f824ad13", - "https://deno.land/x/grammy@v1.15.1/core/payload.ts": "bed2e44fb567259ee2cab70a7734544c90fae80cb937b354ee1427d0f0883b39", - "https://deno.land/x/grammy@v1.15.1/filter.ts": "2c341f376bff726ca300e547843abcd989219cd10a05ae612844efaaa2cefe50", - "https://deno.land/x/grammy@v1.15.1/mod.ts": "6d96b0c7b4c8b9448b9f9903a95a78c3379febd36b0f6485ad567d79b153c794", - "https://deno.land/x/grammy@v1.15.1/platform.deno.ts": "18b9af227a0455edec89ed517c11feaa6a1904f3da1a1a46c07a3a98b4409ffa", - "https://deno.land/x/grammy@v1.15.1/types.deno.ts": "bcc5e5eaec266cea7f0af0b647eaab40995f4222a309673937a27abcb668480e", - "https://deno.land/x/grammy@v1.15.1/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", - "https://deno.land/x/grammy@v1.36.1/bot.ts": "b0e3159726c9873787ab7a06c2bcf5b8bb90da3493486b31a50cf260534bfa9e", - "https://deno.land/x/grammy@v1.36.1/composer.ts": "dab5a40d8a6fdc734bfb218f8b2e4ef846c05b833219ddd3fdee3f145bb2660b", - "https://deno.land/x/grammy@v1.36.1/context.ts": "7e096053edbdf289b62b718d657c4d54b063d0eb8e7b25ecc9c84a96de502068", - "https://deno.land/x/grammy@v1.36.1/convenience/constants.ts": "1560129784be52f49aa0bea8716f09ed00dac367fef195be6a2c09bdfc43fb99", - "https://deno.land/x/grammy@v1.36.1/convenience/frameworks.ts": "e78afd522b62202053c09dc119ff282d356d85845a05af6d678a4ffa7ca3037d", - "https://deno.land/x/grammy@v1.36.1/convenience/inline_query.ts": "409d1940c7670708064efa495003bcbfdf6763a756b2e6303c464489fd3394ff", - "https://deno.land/x/grammy@v1.36.1/convenience/input_media.ts": "7af72a5fdb1af0417e31b1327003f536ddfdf64e06ab8bc7f5da6b574de38658", - "https://deno.land/x/grammy@v1.36.1/convenience/keyboard.ts": "dc5d3f53d0f6a15600ced9b40c85debe55a5d381436826b4cdede18c84bd6bae", - "https://deno.land/x/grammy@v1.36.1/convenience/session.ts": "5e4b976528a0b3d7893645ac23e2e35e78671af578a3aed5efb4b621e7e9b6da", - "https://deno.land/x/grammy@v1.36.1/convenience/webhook.ts": "722f6da8de7578ecfcd263ca07ec3b81f09e7f243fdf2a887ac0e6cab509e116", - "https://deno.land/x/grammy@v1.36.1/core/api.ts": "7c4e031a31dc40fd66fccd0bd6d89673f6ccab51caf5b0f57e9eafc72bdb129a", - "https://deno.land/x/grammy@v1.36.1/core/client.ts": "44a9f9fd6dc7eb8ab3c57dab3f550ef5ec53142c5df16ab5501da8e3ea62dcff", - "https://deno.land/x/grammy@v1.36.1/core/error.ts": "5245f18f273da6be364f525090c24d2e9a282c180904f674f66946f2b2556247", - "https://deno.land/x/grammy@v1.36.1/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b", - "https://deno.land/x/grammy@v1.36.1/filter.ts": "a7e73097a2e569091a1eff0ea72fab71791bf21a2476290f114bd28668263f3e", - "https://deno.land/x/grammy@v1.36.1/mod.ts": "a973e356760eed1b58bc89280e6eb41bbdf74035f6348c08d6cebf50da1dac34", - "https://deno.land/x/grammy@v1.36.1/platform.deno.ts": "68272a7e1d9a2d74d8a45342526485dbc0531dee812f675d7f8a4e7fc8393028", - "https://deno.land/x/grammy@v1.36.1/types.deno.ts": "07efef6ec62170d78370a13d8a41a87b195cfdb3769672a7091a734d62707428", - "https://deno.land/x/grammy@v1.36.1/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", - "https://deno.land/x/grammy_types@v3.0.0/api.ts": "efc90a31eb6f59ae5e7a4cf5838f46529e2fa6fa7e97a51a82dbd28afad21592", - "https://deno.land/x/grammy_types@v3.0.0/inline.ts": "8c84406fde94dbc790699043b08e09a9ea6f5f2467e5d0fe345465590f20d70f", - "https://deno.land/x/grammy_types@v3.0.0/manage.ts": "9179a6e024eddd9962a75789131d1203e4273b2e6614e77f6775aa9ff6b8a373", - "https://deno.land/x/grammy_types@v3.0.0/markup.ts": "70fbfa9e2403fc1683c2eba22c6efe0803e5be81091e2a0e92b48f6da2527994", - "https://deno.land/x/grammy_types@v3.0.0/message.ts": "505c1186e0110372d448c2aa88fddcf9d36f0814f348718de77c9d03e75f0afd", - "https://deno.land/x/grammy_types@v3.0.0/methods.ts": "2db1355ddc413deacd5f24b34bb5412ddc95cf446fbff332f11723b276be0170", - "https://deno.land/x/grammy_types@v3.0.0/mod.ts": "c9171f1ad0d4ae2b5c07b15b559b7e6a09f5083fec50587419cd1fb7b20b5554", - "https://deno.land/x/grammy_types@v3.0.0/passport.ts": "e3fb63aec96510bcc317ef48fd25b435444b8f407502d7568c00fce15f2958fd", - "https://deno.land/x/grammy_types@v3.0.0/payment.ts": "d23e9038c5b479b606e620dd84e3e67b6642ada110a962f2d5b5286e99ec7de5", - "https://deno.land/x/grammy_types@v3.0.0/settings.ts": "1706823f6a0d1f538f286cc80830077a6f5d01da4c4742d63f25172e329aadde", - "https://deno.land/x/grammy_types@v3.0.0/update.ts": "9415d29fd8f148f880e15daa04ece325d4f5a5a03bcd2bdce66ec32e53116aea", - "https://deno.land/x/grammy_types@v3.20.0/api.ts": "ae04d6628e3d25ae805bc07a19475065044fc44cde0a40877405bc3544d03a5f", - "https://deno.land/x/grammy_types@v3.20.0/inline.ts": "9afd0340eafd22acb163f2f680d58b85719f0edc92dffa4d259fc5232e543d23", - "https://deno.land/x/grammy_types@v3.20.0/langs.ts": "5f5fd09c58ba3ae942dd7cea2696f95587d2032c1829bba4bca81762b7ef73b6", - "https://deno.land/x/grammy_types@v3.20.0/manage.ts": "c02480bbba003bc66dbc30bd0d1edf837b09ad9ee459ef82afd8d3492caac0da", - "https://deno.land/x/grammy_types@v3.20.0/markup.ts": "b989e0712f9731c59e6cb308371b1722d823dd55de3d6bcaf3e4ed645a42e1f9", - "https://deno.land/x/grammy_types@v3.20.0/message.ts": "243968db23afa31e0a390d46b58489ca182fac10e81aa05c859f6a4b3a66fe13", - "https://deno.land/x/grammy_types@v3.20.0/methods.ts": "2d9e398a9ef09dff6633caaa23b5a89375340f083e046f7f3be7ce6179cca38b", - "https://deno.land/x/grammy_types@v3.20.0/mod.ts": "2a22dc7cd29c2739647c22cec00d5d4e2f49ba1c61bcaf70b4206a14bce29799", - "https://deno.land/x/grammy_types@v3.20.0/passport.ts": "19820e7d6c279521f8bc8912d6a378239f73d4ab525453808994b5f44ef95215", - "https://deno.land/x/grammy_types@v3.20.0/payment.ts": "8f016ffe46221c80d9d1a1b30848d8ccc10548f0ec281c9d3312b598cb0c2a4d", - "https://deno.land/x/grammy_types@v3.20.0/settings.ts": "f8ff810da6f1007ed24cd504809bf46820229c395ff9bfc3e5c8ceaef5b2aae1", - "https://deno.land/x/grammy_types@v3.20.0/story.ts": "f558c6e6054a43fa1403c2376f7c0b51e2138f4e0d13f0f6e870ffd1cd085ae2", - "https://deno.land/x/grammy_types@v3.20.0/update.ts": "71cc0d5ec860149b71415ba03282b1d7edd0466b36e2789521a3b3a3d7796493", - "https://deno.land/x/xeorarchx@v3.1.0/aur.ts": "8858faabc084da8141ed6958734a3407e12dbd40a0b069bacd62afaeea9caea1", - "https://deno.land/x/xeorarchx@v3.1.0/deps.ts": "c395d4e364163768505d5e34fe864055d550b3435d7cbccd1040805f1205d836", - "https://deno.land/x/xeorarchx@v3.1.0/fetcher.ts": "99edbc6c2b79a96ef7f8343489f47e8d319f17019a393214f21f2920261cf029", - "https://deno.land/x/xeorarchx@v3.1.0/groups.ts": "af46736e7f756c38f8a0e4b6da1619b39282250aa5d4a0fda3fabcf593d0ead2", - "https://deno.land/x/xeorarchx@v3.1.0/mod.ts": "478fa1e3fe61736950f5858b0be877f28fcdc8a92f01c6bd2a4c5d4c42d4edc9", - "https://deno.land/x/xeorarchx@v3.1.0/search.ts": "e435c6ce1cb25646da1ef1ac4a1ba6007e00ce8da8171a44ec84802a97b3c715", - "https://deno.land/x/xeorarchx@v3.1.0/std.ts": "4fc3cb2c4748fa43447363706a5f50c115b3c1427474717fbb08edcfab7e38d4" - } -} diff --git a/deps.ts b/deps.ts deleted file mode 100755 index c489bc7..0000000 --- a/deps.ts +++ /dev/null @@ -1,17 +0,0 @@ -export { - Bot, - Composer, - Context, - InlineKeyboard, - InputFile, - type NextFunction, - webhookCallback, -} from "https://deno.land/x/grammy@v1.36.1/mod.ts"; -export { exists } from "jsr:@std/fs/exists"; -export * as toml from "jsr:@std/toml"; -export { parseArgs } from "jsr:@std/cli/parse-args"; -export { config } from "https://deno.land/x/dotenv@v3.2.0/mod.ts"; -export { blue, bold, green, red, yellow } from "jsr:@std/fmt/colors"; -export { Groups, Search } from "https://deno.land/x/xeorarchx@v3.1.0/mod.ts"; -export type { Package } from "https://deno.land/x/xeorarchx@v3.1.0/search.ts"; -export type { InlineQueryResult } from "https://deno.land/x/grammy_types@v3.20.0/inline.ts"; diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 728ea19..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1745930157, - "narHash": "sha256-y3h3NLnzRSiUkYpnfvnS669zWZLoqqI6NprtLQ+5dck=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "46e634be05ce9dc6d4db8e664515ba10b78151ae", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index adbf4a1..0000000 --- a/flake.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ - description = "Telegram bot for Ecma Uzbekistan"; - - inputs = { - # Too old to work with most libraries - # nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; - - # Perfect! - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - - # The flake-utils library - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { - self, - nixpkgs, - flake-utils, - ... - }: - flake-utils.lib.eachDefaultSystem - ( - system: let - pkgs = nixpkgs.legacyPackages.${system}; - in { - # Nix script formatter - formatter = pkgs.alejandra; - - # Development environment - devShells.default = import ./shell.nix {inherit pkgs;}; - - # Output package - packages.default = pkgs.callPackage ./. {}; - } - ); - # // { - # # Overlay module - # nixosModules.bot = import ./module.nix self; - # }; -} diff --git a/justfile b/justfile deleted file mode 100755 index c5717ac..0000000 --- a/justfile +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env just --justfile - -start: - deno run --allow-all mod.ts - -dev: - deno run --watch-hmr --allow-all mod.ts - -fmt: - deno fmt - -lint: - deno lint - -cache: - deno cache ./deps.ts diff --git a/mod.ts b/mod.ts deleted file mode 100755 index 13873f9..0000000 --- a/mod.ts +++ /dev/null @@ -1 +0,0 @@ -import "./core.ts"; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..653802f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1635 @@ +{ + "name": "ecma-uz-telegram", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ecma-uz-telegram", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.21", + "dotenv": "^16.4.5", + "express": "^4.18.2", + "grammy": "^1.36.1", + "toml": "^3.0.0" + }, + "devDependencies": { + "@types/node": "^20.11.5", + "tsx": "^4.7.1", + "typescript": "^5.3.3" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@grammyjs/types": { + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.22.2.tgz", + "integrity": "sha512-uu7DX2ezhnBPozL3bXHmwhLvaFsh59E4QyviNH4Cij7EdVekYrs6mCzeXsa2pDk30l3uXo7DBahlZLzTPtpYZg==", + "license": "MIT" + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.24.tgz", + "integrity": "sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.7", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", + "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.23.tgz", + "integrity": "sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/grammy": { + "version": "1.38.3", + "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.38.3.tgz", + "integrity": "sha512-1eQwNfxrRQ0JOFqd3n1nKqyWkHvCQRCNiH8e5aYm27mIjGPobgss58XN8GORC2ejAWM2+NSdUknrMhYj87cjGg==", + "license": "MIT", + "dependencies": { + "@grammyjs/types": "3.22.2", + "abort-controller": "^3.0.0", + "debug": "^4.4.3", + "node-fetch": "^2.7.0" + }, + "engines": { + "node": "^12.20.0 || >=14.13.1" + } + }, + "node_modules/grammy/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/grammy/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tsx": { + "version": "4.20.6", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", + "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..2a97a51 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "ecma-uz-telegram", + "version": "1.0.0", + "description": "Telegram bot for managing all sub-communities", + "main": "src/core.ts", + "scripts": { + "dev": "tsx watch src/core.ts", + "build": "tsc", + "start": "node dist/core.js", + "start:src": "tsx src/core.ts" + }, + "keywords": [ + "telegram", + "bot", + "grammy" + ], + "author": "", + "license": "MIT", + "dependencies": { + "grammy": "^1.36.1", + "express": "^4.18.2", + "@types/express": "^4.17.21", + "toml": "^3.0.0", + "dotenv": "^16.4.5" + }, + "devDependencies": { + "@types/node": "^20.11.5", + "tsx": "^4.7.1", + "typescript": "^5.3.3" + } +} \ No newline at end of file diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 88d01f1..0000000 --- a/shell.nix +++ /dev/null @@ -1,54 +0,0 @@ -{pkgs ? import {}}: let - getLibFolder = pkg: "${pkg}/lib"; -in - pkgs.stdenv.mkDerivation { - name = "bot"; - - nativeBuildInputs = with pkgs; [ - # LLVM & GCC - deno - - # Launch scripts - just - - # Hail the Nix - nixd - statix - deadnix - alejandra - ]; - - buildInputs = with pkgs; [ - openssl - ]; - - - shellHook = '' - # Load the environment variables from the .env file - # if [ ! -f .env ]; then - # echo "Please enter your telegram bot token: "; - # read -r TELOXIDE_TOKEN; - # echo "TELOXIDE_TOKEN=$TELOXIDE_TOKEN" > .env; - # else - # source .env; - # fi - - # Set the environment variable - # export TELOXIDE_TOKEN=$TELOXIDE_TOKEN; - - # Start watching for changes - # Start watching for changes in the background - # cargo watch -x "run --bin bot" & - - # Store the PID of the background process - # CARGO_WATCH_PID=$! - - # Function to clean up the background process on exit - # cleanup() { - # kill $CARGO_WATCH_PID - # } - - # Trap EXIT signal to run cleanup function - # trap cleanup EXIT - ''; - } diff --git a/src/core.ts b/src/core.ts new file mode 100644 index 0000000..969b5d8 --- /dev/null +++ b/src/core.ts @@ -0,0 +1,76 @@ +import { Bot } from "./deps"; +import delta from "./delta/mod"; +import { Config, Configs } from "./utils/config"; +import args from "./utils/cli"; +import express from "express"; + +const handle = (bot: Bot, express: express.Express) => { + return express.raw({ type: "application/json" }); +}; + +const webhook = (bot: Bot, config: Configs, app: express.Express) => { + console.log(`[INFO] bot is starting on ${config.mode}`); + + app.use(express.json()); + + app.post(`/${bot.token}`, async (req, res) => { + try { + await bot.handleUpdate(req.body); + res.sendStatus(200); + } catch (err) { + console.error(err); + res.sendStatus(500); + } + }); + + app.get("/", async (req, res) => { + try { + await bot.api.setWebhook(`${config.host}/${bot.token}`); + res.send("Done. Set"); + } catch (_) { + res.send("Couldn't succeed with installing webhook"); + } + }); + + app.listen(config.port, "127.0.0.1", () => { + console.log(`Server listening on port ${config.port}`); + }); +}; + +const polling = async (bot: Bot) => { + await bot.start(); +}; + +const launch = async () => { + if (args.config == undefined) { + console.log("Path to config file is not defined!"); + process.exit(1); + } + + const config = new Config(args.config); + config.consume(); + + const data: Configs = config.data(); + const bot = new Bot(data.token); + + delta(bot); + bot.catch((error) => { + console.log(error, error.ctx.api); + }); + + const app = express(); + + switch (data.mode) { + case "webhook": + webhook(bot, data, app); + break; + case "polling": + await polling(bot); + break; + default: + throw new Error("Deploy method not validated!"); + } +}; + +launch(); + diff --git a/delta/about.ts b/src/delta/about.ts old mode 100755 new mode 100644 similarity index 79% rename from delta/about.ts rename to src/delta/about.ts index 56a2160..604ea29 --- a/delta/about.ts +++ b/src/delta/about.ts @@ -1,5 +1,5 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isPrivate from "../hooks/isPrivate.ts"; +import { Composer, Context, InlineKeyboard } from "../deps"; +import isPrivate from "../hooks/isPrivate"; const composer = new Composer(); @@ -16,9 +16,9 @@ export const keyboard = new InlineKeyboard().url( ); composer.command("about", isPrivate, async (ctx: Context): Promise => { - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(message, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", reply_markup: keyboard, }); diff --git a/delta/code.ts b/src/delta/code.ts old mode 100755 new mode 100644 similarity index 93% rename from delta/code.ts rename to src/delta/code.ts index 4c53ea3..b11bd78 --- a/delta/code.ts +++ b/src/delta/code.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps.ts"; +import { Composer, Context } from "../deps"; const composer = new Composer(); @@ -42,7 +42,6 @@ composer.command("code", async (ctx: Context) => { const lang = splitted[1].toLowerCase(); - // parsing python code from tg message is hard -_- if (lang === "python" || lang === "py") { return ctx.reply( "Uzr, python tili sintaksisda \"space\"ga ishongani uchun, menga to'g'ri kelmaydi", @@ -65,7 +64,6 @@ composer.command("code", async (ctx: Context) => { ); const available_version = foundLang?.version; - // what if programming language is not supported if ( typeof available_version === "undefined" && (ctx.chat?.type === "group" || ctx.chat?.type === "supergroup") @@ -90,7 +88,6 @@ composer.command("code", async (ctx: Context) => { return await ctx.reply(msg, { reply_to_message_id: msg_id }); } - // execute the code const _output = await fetch("https://emkc.org/api/v2/piston/execute", { method: "POST", body: JSON.stringify({ @@ -109,13 +106,11 @@ composer.command("code", async (ctx: Context) => { const outputjson = (await _output.json()) as Response; - // lil bit formatting const stdout = outputjson.run.stdout.replace(/\n/gi, " ") + "\n"; const stderror = outputjson.run.stderr.replace(/\n/gi, " ") + "\n"; const output = outputjson.run.output.replace(/\n/gi, " ") + "\n"; const exitCode = outputjson.run.code; - // send the output const message = `Til: ${outputjson.language}\n` + `Versiya: ${outputjson.version}\n` + `Natija:\n` + diff --git a/delta/feedback.ts b/src/delta/feedback.ts old mode 100755 new mode 100644 similarity index 78% rename from delta/feedback.ts rename to src/delta/feedback.ts index 21ba197..f92468a --- a/delta/feedback.ts +++ b/src/delta/feedback.ts @@ -1,7 +1,6 @@ -// deno-lint-ignore-file no-explicit-any -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isPrivate from "../hooks/isPrivate.ts"; -import { reply } from "../utils/sender.ts"; +import { Composer, Context, InlineKeyboard } from "../deps"; +import isPrivate from "../hooks/isPrivate"; +import { reply } from "../utils/sender"; const composer = new Composer(); diff --git a/delta/groups.ts b/src/delta/groups.ts old mode 100755 new mode 100644 similarity index 78% rename from delta/groups.ts rename to src/delta/groups.ts index c6c9834..34d1a53 --- a/delta/groups.ts +++ b/src/delta/groups.ts @@ -1,7 +1,27 @@ -import { Composer, Context, Groups, InlineKeyboard } from "../deps.ts"; +import { Composer, Context, InlineKeyboard } from "../deps"; const composer = new Composer(); +// Placeholder for Groups API - needs implementation +interface Group { + name: string; + packs: number; +} + +class GroupsAPI { + static async groups(page: number): Promise { + // This is a placeholder - you'll need to implement the actual API call + return []; + } + + static async group(name: string): Promise { + // This is a placeholder - you'll need to implement the actual API call + return { arch: "", name: "", packs: [] }; + } +} + +const Groups = GroupsAPI; + composer.command("groups", async (ctx: Context): Promise => { const groups = await Groups.groups(1); const nextLength = (await Groups.groups(2)).length; @@ -19,9 +39,9 @@ composer.command("groups", async (ctx: Context): Promise => { keyboard.text(`Keyingi ➡️`, `groups_2`); } - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(`Ushbu ro'yxatdan kerakli guruhni tanlab oling`, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", reply_markup: keyboard, }); diff --git a/delta/help.ts b/src/delta/help.ts old mode 100755 new mode 100644 similarity index 86% rename from delta/help.ts rename to src/delta/help.ts index f6e5558..9ed5571 --- a/delta/help.ts +++ b/src/delta/help.ts @@ -1,5 +1,5 @@ -import { Composer, Context } from "../deps.ts"; -import * as start from "./start.ts"; +import { Composer, Context } from "../deps"; +import * as start from "./start"; const composer = new Composer(); @@ -25,9 +25,9 @@ export const message = `Mavjud komandalar ro'yxati:` + export const keyboard = start.keyboard; composer.command("help", async (ctx: Context): Promise => { - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(message, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", reply_markup: keyboard, }); diff --git a/delta/honor.ts b/src/delta/honor.ts old mode 100755 new mode 100644 similarity index 81% rename from delta/honor.ts rename to src/delta/honor.ts index 488438c..44a72ce --- a/delta/honor.ts +++ b/src/delta/honor.ts @@ -1,7 +1,7 @@ -import { Composer, Context } from "../deps.ts"; -import isAdmin from "../hooks/isAdmin.ts"; -import isReply from "../hooks/isReply.ts"; -import isGroup from "../hooks/isGroup.ts"; +import { Composer, Context } from "../deps"; +import isAdmin from "../hooks/isAdmin"; +import isReply from "../hooks/isReply"; +import isGroup from "../hooks/isGroup"; const composer = new Composer(); diff --git a/delta/inline.ts b/src/delta/inline.ts old mode 100755 new mode 100644 similarity index 83% rename from delta/inline.ts rename to src/delta/inline.ts index c5d5c64..6213b74 --- a/delta/inline.ts +++ b/src/delta/inline.ts @@ -1,6 +1,7 @@ -import { Composer, Context } from "../deps.ts"; -import { Pacman } from "../types/Pacman.ts"; -import { Tealdeer } from "../types/Tealdeer.ts"; +import { Composer, Context } from "../deps"; +import { Pacman } from "../types/Pacman"; +import { Tealdeer } from "../types/Tealdeer"; +import crypto from "crypto"; const composer = new Composer(); diff --git a/src/delta/mod.ts b/src/delta/mod.ts new file mode 100644 index 0000000..c90c6cb --- /dev/null +++ b/src/delta/mod.ts @@ -0,0 +1,31 @@ +import start from "./start"; +import help from "./help"; +import inline from "./inline"; +import which from "./which"; +import { Bot } from "../deps"; +import about from "./about"; +import rules from "./rules"; +import text from "./text"; +import groups from "./groups"; +import honor from "./honor"; +import warrior from "./warrior"; +import trigger from "./trigger"; +import feedback from "./feedback"; +import code from "./code"; + +export default (bot: Bot) => { + bot + .use(start) + .use(honor) + .use(help) + .use(groups) + .use(inline) + .use(which) + .use(about) + .use(rules) + .use(feedback) + .use(warrior) + .use(trigger) + .use(code) + .use(text); +}; diff --git a/delta/rules.ts b/src/delta/rules.ts old mode 100755 new mode 100644 similarity index 85% rename from delta/rules.ts rename to src/delta/rules.ts index 95a4d7a..19e200f --- a/delta/rules.ts +++ b/src/delta/rules.ts @@ -1,5 +1,5 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; -import isPrivate from "../hooks/isPrivate.ts"; +import { Composer, Context, InlineKeyboard } from "../deps"; +import isPrivate from "../hooks/isPrivate"; const composer = new Composer(); @@ -28,9 +28,9 @@ export const keyboard = new InlineKeyboard().url( ); composer.command("rules", isPrivate, async (ctx: Context): Promise => { - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(message, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", reply_markup: keyboard, }); diff --git a/delta/start.ts b/src/delta/start.ts old mode 100755 new mode 100644 similarity index 83% rename from delta/start.ts rename to src/delta/start.ts index 71d2c4b..98b0554 --- a/delta/start.ts +++ b/src/delta/start.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InlineKeyboard } from "../deps.ts"; +import { Composer, Context, InlineKeyboard } from "../deps"; const composer = new Composer(); @@ -15,9 +15,9 @@ export const keyboard = new InlineKeyboard() .url("Web Sahifa", "https://xinux.uz"); composer.command("start", async (ctx: Context): Promise => { - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(message, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", reply_markup: keyboard, }); diff --git a/delta/text.ts b/src/delta/text.ts old mode 100755 new mode 100644 similarity index 79% rename from delta/text.ts rename to src/delta/text.ts index 8f0a175..85cebe4 --- a/delta/text.ts +++ b/src/delta/text.ts @@ -1,6 +1,5 @@ -// deno-lint-ignore-file no-explicit-any -import { Composer, Context } from "../deps.ts"; -import topics from "../topics.json" with { type: "json" }; +import { Composer, Context } from "../deps"; +import topics from "../../topics.json"; const composer = new Composer(); diff --git a/delta/trigger.ts b/src/delta/trigger.ts old mode 100755 new mode 100644 similarity index 92% rename from delta/trigger.ts rename to src/delta/trigger.ts index b4e76ba..066457f --- a/delta/trigger.ts +++ b/src/delta/trigger.ts @@ -1,8 +1,7 @@ -// deno-lint-ignore-file no-explicit-any -import { reply } from "../utils/sender.ts"; -import isReply from "../hooks/isReply.ts"; -import topics from "../topics.json" with { type: "json" }; -import { Composer, Context, InlineKeyboard } from "../deps.ts"; +import { reply } from "../utils/sender"; +import isReply from "../hooks/isReply"; +import topics from "../../topics.json"; +import { Composer, Context, InlineKeyboard } from "../deps"; const composer = new Composer(); diff --git a/delta/warrior.ts b/src/delta/warrior.ts old mode 100755 new mode 100644 similarity index 74% rename from delta/warrior.ts rename to src/delta/warrior.ts index 3360516..9e76ba2 --- a/delta/warrior.ts +++ b/src/delta/warrior.ts @@ -1,6 +1,6 @@ -import { Composer, Context, InputFile } from "../deps.ts"; -import isUwU from "../hooks/isUwU.ts"; -import isReply from "../hooks/isReply.ts"; +import { Composer, Context, InputFile } from "../deps"; +import isUwU from "../hooks/isUwU"; +import isReply from "../hooks/isReply"; const composer = new Composer(); @@ -16,9 +16,9 @@ composer.command( const caption = `${name} ga Faxriy Yorlig' ob chiqilar!`; - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.replyWithPhoto(file, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, caption, parse_mode: "HTML", }); diff --git a/delta/which.ts b/src/delta/which.ts old mode 100755 new mode 100644 similarity index 80% rename from delta/which.ts rename to src/delta/which.ts index 6c4c9a9..5e28337 --- a/delta/which.ts +++ b/src/delta/which.ts @@ -1,5 +1,5 @@ -import { Composer, Context } from "../deps.ts"; -import isGroup from "../hooks/isGroup.ts"; +import { Composer, Context } from "../deps"; +import isGroup from "../hooks/isGroup"; const composer = new Composer(); @@ -16,9 +16,9 @@ composer.command("which", isGroup, async (ctx: Context): Promise => { `User ID: ${ctx.message.from.id}` + `\n`) + `Status: ${status}`; - if (ctx.message!.is_topic_message) { + if (ctx.message?.message_thread_id) { await ctx.reply(text, { - message_thread_id: ctx.message!.message_thread_id, + message_thread_id: ctx.message.message_thread_id, parse_mode: "HTML", }); } else { diff --git a/src/deps.ts b/src/deps.ts new file mode 100644 index 0000000..a072f42 --- /dev/null +++ b/src/deps.ts @@ -0,0 +1,9 @@ +export { + Bot, + Composer, + Context, + InlineKeyboard, + InputFile, + HttpError, +} from "grammy"; + diff --git a/hooks/isAdmin.ts b/src/hooks/isAdmin.ts old mode 100755 new mode 100644 similarity index 86% rename from hooks/isAdmin.ts rename to src/hooks/isAdmin.ts index cc39939..0831185 --- a/hooks/isAdmin.ts +++ b/src/hooks/isAdmin.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction } from "../deps.ts"; +import { Context, NextFunction } from "../deps"; export default async (ctx: Context, next: NextFunction) => { const adminList = await ctx.getChatAdministrators(); diff --git a/hooks/isGroup.ts b/src/hooks/isGroup.ts old mode 100755 new mode 100644 similarity index 78% rename from hooks/isGroup.ts rename to src/hooks/isGroup.ts index f581b98..6b1dbf8 --- a/hooks/isGroup.ts +++ b/src/hooks/isGroup.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction } from "../deps.ts"; +import { Context, NextFunction } from "../deps"; export default async (ctx: Context, next: NextFunction) => { if (ctx.chat!.type === "private") { diff --git a/hooks/isHome.ts b/src/hooks/isHome.ts old mode 100755 new mode 100644 similarity index 75% rename from hooks/isHome.ts rename to src/hooks/isHome.ts index e2d0098..2c50ca4 --- a/hooks/isHome.ts +++ b/src/hooks/isHome.ts @@ -1,5 +1,5 @@ -import { Context, InlineKeyboard, NextFunction } from "../deps.ts"; -import { reply } from "../utils/sender.ts"; +import { Context, NextFunction, InlineKeyboard } from "../deps"; +import { reply } from "../utils/sender"; const keyboard = new InlineKeyboard().url( `Guruhimizga o'ting`, diff --git a/hooks/isPrivate.ts b/src/hooks/isPrivate.ts old mode 100755 new mode 100644 similarity index 74% rename from hooks/isPrivate.ts rename to src/hooks/isPrivate.ts index c0b09a0..230c5d4 --- a/hooks/isPrivate.ts +++ b/src/hooks/isPrivate.ts @@ -1,5 +1,5 @@ -import { Context, InlineKeyboard, NextFunction } from "../deps.ts"; -import { reply } from "../utils/sender.ts"; +import { Context, NextFunction, InlineKeyboard } from "../deps"; +import { reply } from "../utils/sender"; const keyboard = new InlineKeyboard().url( `Shaxsiy Chat`, diff --git a/hooks/isReply.ts b/src/hooks/isReply.ts old mode 100755 new mode 100644 similarity index 64% rename from hooks/isReply.ts rename to src/hooks/isReply.ts index d7a22ca..cbb62f4 --- a/hooks/isReply.ts +++ b/src/hooks/isReply.ts @@ -1,6 +1,6 @@ -import { reply } from "../utils/sender.ts"; -import { Context, NextFunction } from "../deps.ts"; -import topics from "../topics.json" with { type: "json" }; +import { reply } from "../utils/sender"; +import { Context, NextFunction } from "../deps"; +import topics from "../../topics.json"; export default async (ctx: Context, next: NextFunction) => { if ( diff --git a/hooks/isUwU.ts b/src/hooks/isUwU.ts old mode 100755 new mode 100644 similarity index 68% rename from hooks/isUwU.ts rename to src/hooks/isUwU.ts index 73eb643..caad469 --- a/hooks/isUwU.ts +++ b/src/hooks/isUwU.ts @@ -1,5 +1,5 @@ -import { Context, NextFunction } from "../deps.ts"; -import { reply } from "../utils/sender.ts"; +import { Context, NextFunction } from "../deps"; +import { reply } from "../utils/sender"; export default async (ctx: Context, next: NextFunction) => { if (ctx.message!.from!.id! !== 756870298) { diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..ae3db19 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +import "./core"; + diff --git a/src/mod.ts b/src/mod.ts new file mode 100644 index 0000000..ae3db19 --- /dev/null +++ b/src/mod.ts @@ -0,0 +1,2 @@ +import "./core"; + diff --git a/src/topics.json b/src/topics.json new file mode 100755 index 0000000..8a068f8 --- /dev/null +++ b/src/topics.json @@ -0,0 +1,20 @@ +{ + "asosiy": 0, + "xinux": 178640, + "coding": 180629, + "yordam": 178646, + "devops": 179980, + "offtopic": 178666, + "redhat": 180526, + "windows": 180916, + "neofetch": 178654, + "unix": 180689, + "debian": 180507, + "i10n": 182187, + "macos": 180536, + "gaming": 195168, + "meme": 207822, + "learning": 207118, + "fikrlar": 258076, + "moderator": 255895 +} diff --git a/types/Pacman.ts b/src/types/Pacman.ts old mode 100755 new mode 100644 similarity index 81% rename from types/Pacman.ts rename to src/types/Pacman.ts index 8fd1747..7e4564d --- a/types/Pacman.ts +++ b/src/types/Pacman.ts @@ -1,5 +1,35 @@ -import normalize from "../utils/normalize.ts"; -import { InlineKeyboard, InlineQueryResult, Package, Search } from "../deps.ts"; +import normalize from "../utils/normalize"; +import { InlineKeyboard } from "../deps"; +import crypto from "crypto"; + +export interface Package { + name: string; + desc: string; + repo: string; + arch: string; + updated: string; + installed: string; + version: string; + install: string; + url?: string; + type: string; +} + +export interface InlineQueryResult { + type: string; + id: string; + title?: string; + description?: string; + url?: string; + reply_markup?: any; + input_message_content?: any; +} + +export class Search { + static async search(query: string): Promise { + return []; + } +} export class Pacman { protected results: Package[]; diff --git a/types/Tealdeer.ts b/src/types/Tealdeer.ts old mode 100755 new mode 100644 similarity index 94% rename from types/Tealdeer.ts rename to src/types/Tealdeer.ts index 0265a47..0e7cb93 --- a/types/Tealdeer.ts +++ b/src/types/Tealdeer.ts @@ -1,6 +1,5 @@ -// deno-lint-ignore-file no-explicit-any - -import { InlineKeyboard, InlineQueryResult } from "../deps.ts"; +import { InlineKeyboard } from "../deps"; +import crypto from "crypto"; interface File { name: string; @@ -14,6 +13,16 @@ interface Page { link: string; } +export interface InlineQueryResult { + type: string; + id: string; + title?: string; + description?: string; + url?: string; + reply_markup?: any; + input_message_content?: any; +} + const API_URL = "https://api.github.com/repos/tldr-pages/tldr/contents/pages"; const DL_URL = "https://raw.githubusercontent.com/tldr-pages/tldr/main/pages"; const WEB_URL = "https://tldr.inbrowser.app/pages"; diff --git a/src/utils/cli.ts b/src/utils/cli.ts new file mode 100644 index 0000000..f80d33c --- /dev/null +++ b/src/utils/cli.ts @@ -0,0 +1,9 @@ +const args: { [key: string]: string | undefined } = {}; + +for (let i = 0; i < process.argv.length; i++) { + if (process.argv[i].startsWith("--") && process.argv[i + 1]) { + args[process.argv[i].slice(2)] = process.argv[i + 1]; + } +} + +export default args; diff --git a/utils/config.ts b/src/utils/config.ts similarity index 77% rename from utils/config.ts rename to src/utils/config.ts index 9001821..617dbcb 100644 --- a/utils/config.ts +++ b/src/utils/config.ts @@ -1,4 +1,5 @@ -import { exists, toml } from "../deps.ts"; +import * as fs from "fs"; +import { parse } from "toml"; export interface Configs { port: number; @@ -22,14 +23,14 @@ export class Config { this.path = path; } - async consume(): Promise { - if (!(await exists(this.path))) { + consume(): void { + if (!fs.existsSync(this.path)) { console.log("Does even your config file exists?"); - Deno.exit(1); + process.exit(1); } - const read = Deno.readTextFileSync(this.path); - const data = toml.parse(read); + const read = fs.readFileSync(this.path, "utf-8"); + const data = parse(read) as any; this.port = data.port as number; this.mode = data.mode as string; diff --git a/utils/normalize.ts b/src/utils/normalize.ts old mode 100755 new mode 100644 similarity index 78% rename from utils/normalize.ts rename to src/utils/normalize.ts index 6cf35dd..6f86482 --- a/utils/normalize.ts +++ b/src/utils/normalize.ts @@ -1,4 +1,11 @@ -import { Package } from "https://deno.land/x/xeorarchx@v3.1.0/search.ts"; +interface Package { + name: string; + desc: string; + repo: string; + arch: string; + url?: string; + type: string; +} const normalize = (pack: Package): string => { if (pack.type === "aur") { diff --git a/utils/sender.ts b/src/utils/sender.ts old mode 100755 new mode 100644 similarity index 71% rename from utils/sender.ts rename to src/utils/sender.ts index ed4df14..0d2ff13 --- a/utils/sender.ts +++ b/src/utils/sender.ts @@ -1,5 +1,4 @@ -// deno-lint-ignore-file no-explicit-any -import { Context, InlineKeyboard } from "../deps.ts"; +import { Context, InlineKeyboard } from "../deps"; /** * Reply to message api but with topics support @@ -16,8 +15,8 @@ export const reply = async ( parse_mode: "HTML", }; - if (ctx.message!.is_topic_message) { - config["message_thread_id"] = ctx.message!.message_thread_id; + if (ctx.message?.message_thread_id) { + config["message_thread_id"] = ctx.message.message_thread_id; } if (buttons) { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ab4b79f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["ES2020"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "types": ["node"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} + diff --git a/utils/cli.ts b/utils/cli.ts deleted file mode 100644 index bcf5a5f..0000000 --- a/utils/cli.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { parseArgs } from "../deps.ts"; - -export default parseArgs(Deno.args, { - string: ["config"], -}); From f8355ae03e326e9ad709246e5354188c14431772 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 21:05:05 +0500 Subject: [PATCH 2/9] refactor: some change imports and code styles --- src/core.ts | 24 ++++++++++-------------- src/delta/about.ts | 2 +- src/delta/code.ts | 2 +- src/delta/feedback.ts | 2 +- src/delta/groups.ts | 7 +------ src/delta/help.ts | 2 +- src/delta/honor.ts | 2 +- src/delta/inline.ts | 3 +-- src/delta/mod.ts | 6 +++--- src/delta/rules.ts | 2 +- src/delta/start.ts | 2 +- src/delta/text.ts | 2 +- src/delta/trigger.ts | 2 +- src/delta/warrior.ts | 2 +- src/delta/which.ts | 2 +- src/deps.ts | 9 --------- src/hooks/isAdmin.ts | 2 +- src/hooks/isGroup.ts | 2 +- src/hooks/isHome.ts | 2 +- src/hooks/isPrivate.ts | 2 +- src/hooks/isReply.ts | 2 +- src/hooks/isUwU.ts | 2 +- src/index.ts | 2 -- src/mod.ts | 2 -- src/types/Pacman.ts | 20 ++++++-------------- src/types/Tealdeer.ts | 24 ++++++++---------------- src/utils/sender.ts | 2 +- 27 files changed, 47 insertions(+), 86 deletions(-) delete mode 100644 src/deps.ts delete mode 100644 src/index.ts delete mode 100644 src/mod.ts diff --git a/src/core.ts b/src/core.ts index 969b5d8..9d716b3 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1,14 +1,10 @@ -import { Bot } from "./deps"; -import delta from "./delta/mod"; +import { Bot } from "grammy"; +import { setupModules } from "./delta/mod"; import { Config, Configs } from "./utils/config"; import args from "./utils/cli"; import express from "express"; -const handle = (bot: Bot, express: express.Express) => { - return express.raw({ type: "application/json" }); -}; - -const webhook = (bot: Bot, config: Configs, app: express.Express) => { +function setupWebhook(bot: Bot, config: Configs, app: express.Express): void { console.log(`[INFO] bot is starting on ${config.mode}`); app.use(express.json()); @@ -37,11 +33,11 @@ const webhook = (bot: Bot, config: Configs, app: express.Express) => { }); }; -const polling = async (bot: Bot) => { +async function startPolling(bot: Bot): Promise { await bot.start(); -}; +} -const launch = async () => { +async function launch(): Promise { if (args.config == undefined) { console.log("Path to config file is not defined!"); process.exit(1); @@ -53,7 +49,7 @@ const launch = async () => { const data: Configs = config.data(); const bot = new Bot(data.token); - delta(bot); + setupModules(bot); bot.catch((error) => { console.log(error, error.ctx.api); }); @@ -62,13 +58,13 @@ const launch = async () => { switch (data.mode) { case "webhook": - webhook(bot, data, app); + setupWebhook(bot, data, app); break; case "polling": - await polling(bot); + await startPolling(bot); break; default: - throw new Error("Deploy method not validated!"); + throw new Error(`Invalid deployment mode: ${data.mode}`); } }; diff --git a/src/delta/about.ts b/src/delta/about.ts index 604ea29..e85f1ae 100644 --- a/src/delta/about.ts +++ b/src/delta/about.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; import isPrivate from "../hooks/isPrivate"; const composer = new Composer(); diff --git a/src/delta/code.ts b/src/delta/code.ts index b11bd78..7d93032 100644 --- a/src/delta/code.ts +++ b/src/delta/code.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; const composer = new Composer(); diff --git a/src/delta/feedback.ts b/src/delta/feedback.ts index f92468a..7076cac 100644 --- a/src/delta/feedback.ts +++ b/src/delta/feedback.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; import isPrivate from "../hooks/isPrivate"; import { reply } from "../utils/sender"; diff --git a/src/delta/groups.ts b/src/delta/groups.ts index 34d1a53..87702f4 100644 --- a/src/delta/groups.ts +++ b/src/delta/groups.ts @@ -1,8 +1,7 @@ -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; const composer = new Composer(); -// Placeholder for Groups API - needs implementation interface Group { name: string; packs: number; @@ -10,12 +9,10 @@ interface Group { class GroupsAPI { static async groups(page: number): Promise { - // This is a placeholder - you'll need to implement the actual API call return []; } static async group(name: string): Promise { - // This is a placeholder - you'll need to implement the actual API call return { arch: "", name: "", packs: [] }; } } @@ -56,11 +53,9 @@ composer.command("groups", async (ctx: Context): Promise => { composer.callbackQuery( /^groups_(\d+)$/, async (ctx: Context): Promise => { - // Arguments const page = Number(ctx.match![1]); const keyboard = new InlineKeyboard(); - // Data const groups = await Groups.groups(page); const nextLength = (await Groups.groups(page - 1)).length; const prevLength = (await Groups.groups(page + 1)).length; diff --git a/src/delta/help.ts b/src/delta/help.ts index 9ed5571..ad2491f 100644 --- a/src/delta/help.ts +++ b/src/delta/help.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; import * as start from "./start"; const composer = new Composer(); diff --git a/src/delta/honor.ts b/src/delta/honor.ts index 44a72ce..5f25708 100644 --- a/src/delta/honor.ts +++ b/src/delta/honor.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; import isAdmin from "../hooks/isAdmin"; import isReply from "../hooks/isReply"; import isGroup from "../hooks/isGroup"; diff --git a/src/delta/inline.ts b/src/delta/inline.ts index 6213b74..81ae67e 100644 --- a/src/delta/inline.ts +++ b/src/delta/inline.ts @@ -1,7 +1,6 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; import { Pacman } from "../types/Pacman"; import { Tealdeer } from "../types/Tealdeer"; -import crypto from "crypto"; const composer = new Composer(); diff --git a/src/delta/mod.ts b/src/delta/mod.ts index c90c6cb..7f8e3e0 100644 --- a/src/delta/mod.ts +++ b/src/delta/mod.ts @@ -2,7 +2,7 @@ import start from "./start"; import help from "./help"; import inline from "./inline"; import which from "./which"; -import { Bot } from "../deps"; +import { Bot } from "grammy"; import about from "./about"; import rules from "./rules"; import text from "./text"; @@ -13,7 +13,7 @@ import trigger from "./trigger"; import feedback from "./feedback"; import code from "./code"; -export default (bot: Bot) => { +export const setupModules = (bot: Bot): void => { bot .use(start) .use(honor) @@ -28,4 +28,4 @@ export default (bot: Bot) => { .use(trigger) .use(code) .use(text); -}; +} diff --git a/src/delta/rules.ts b/src/delta/rules.ts index 19e200f..1091a3e 100644 --- a/src/delta/rules.ts +++ b/src/delta/rules.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; import isPrivate from "../hooks/isPrivate"; const composer = new Composer(); diff --git a/src/delta/start.ts b/src/delta/start.ts index 98b0554..092de4d 100644 --- a/src/delta/start.ts +++ b/src/delta/start.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; const composer = new Composer(); diff --git a/src/delta/text.ts b/src/delta/text.ts index 85cebe4..117d143 100644 --- a/src/delta/text.ts +++ b/src/delta/text.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; import topics from "../../topics.json"; const composer = new Composer(); diff --git a/src/delta/trigger.ts b/src/delta/trigger.ts index 066457f..27a0ce2 100644 --- a/src/delta/trigger.ts +++ b/src/delta/trigger.ts @@ -1,7 +1,7 @@ import { reply } from "../utils/sender"; import isReply from "../hooks/isReply"; import topics from "../../topics.json"; -import { Composer, Context, InlineKeyboard } from "../deps"; +import { Composer, Context, InlineKeyboard } from "grammy"; const composer = new Composer(); diff --git a/src/delta/warrior.ts b/src/delta/warrior.ts index 9e76ba2..0de5e36 100644 --- a/src/delta/warrior.ts +++ b/src/delta/warrior.ts @@ -1,4 +1,4 @@ -import { Composer, Context, InputFile } from "../deps"; +import { Composer, Context, InputFile } from "grammy"; import isUwU from "../hooks/isUwU"; import isReply from "../hooks/isReply"; diff --git a/src/delta/which.ts b/src/delta/which.ts index 5e28337..efbc07f 100644 --- a/src/delta/which.ts +++ b/src/delta/which.ts @@ -1,4 +1,4 @@ -import { Composer, Context } from "../deps"; +import { Composer, Context } from "grammy"; import isGroup from "../hooks/isGroup"; const composer = new Composer(); diff --git a/src/deps.ts b/src/deps.ts deleted file mode 100644 index a072f42..0000000 --- a/src/deps.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { - Bot, - Composer, - Context, - InlineKeyboard, - InputFile, - HttpError, -} from "grammy"; - diff --git a/src/hooks/isAdmin.ts b/src/hooks/isAdmin.ts index 0831185..62d9bda 100644 --- a/src/hooks/isAdmin.ts +++ b/src/hooks/isAdmin.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction } from "../deps"; +import { Context, NextFunction } from "grammy"; export default async (ctx: Context, next: NextFunction) => { const adminList = await ctx.getChatAdministrators(); diff --git a/src/hooks/isGroup.ts b/src/hooks/isGroup.ts index 6b1dbf8..f49b049 100644 --- a/src/hooks/isGroup.ts +++ b/src/hooks/isGroup.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction } from "../deps"; +import { Context, NextFunction } from "grammy"; export default async (ctx: Context, next: NextFunction) => { if (ctx.chat!.type === "private") { diff --git a/src/hooks/isHome.ts b/src/hooks/isHome.ts index 2c50ca4..7d812aa 100644 --- a/src/hooks/isHome.ts +++ b/src/hooks/isHome.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction, InlineKeyboard } from "../deps"; +import { Context, NextFunction, InlineKeyboard } from "grammy"; import { reply } from "../utils/sender"; const keyboard = new InlineKeyboard().url( diff --git a/src/hooks/isPrivate.ts b/src/hooks/isPrivate.ts index 230c5d4..d5157b8 100644 --- a/src/hooks/isPrivate.ts +++ b/src/hooks/isPrivate.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction, InlineKeyboard } from "../deps"; +import { Context, NextFunction, InlineKeyboard } from "grammy"; import { reply } from "../utils/sender"; const keyboard = new InlineKeyboard().url( diff --git a/src/hooks/isReply.ts b/src/hooks/isReply.ts index cbb62f4..ded29c5 100644 --- a/src/hooks/isReply.ts +++ b/src/hooks/isReply.ts @@ -1,5 +1,5 @@ import { reply } from "../utils/sender"; -import { Context, NextFunction } from "../deps"; +import { Context, NextFunction } from "grammy"; import topics from "../../topics.json"; export default async (ctx: Context, next: NextFunction) => { diff --git a/src/hooks/isUwU.ts b/src/hooks/isUwU.ts index caad469..59d099f 100644 --- a/src/hooks/isUwU.ts +++ b/src/hooks/isUwU.ts @@ -1,4 +1,4 @@ -import { Context, NextFunction } from "../deps"; +import { Context, NextFunction } from "grammy"; import { reply } from "../utils/sender"; export default async (ctx: Context, next: NextFunction) => { diff --git a/src/index.ts b/src/index.ts deleted file mode 100644 index ae3db19..0000000 --- a/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -import "./core"; - diff --git a/src/mod.ts b/src/mod.ts deleted file mode 100644 index ae3db19..0000000 --- a/src/mod.ts +++ /dev/null @@ -1,2 +0,0 @@ -import "./core"; - diff --git a/src/types/Pacman.ts b/src/types/Pacman.ts index 7e4564d..bbf437c 100644 --- a/src/types/Pacman.ts +++ b/src/types/Pacman.ts @@ -1,7 +1,9 @@ import normalize from "../utils/normalize"; -import { InlineKeyboard } from "../deps"; +import { InlineKeyboard } from "grammy"; import crypto from "crypto"; +type InlineQueryResult = any; + export interface Package { name: string; desc: string; @@ -15,16 +17,6 @@ export interface Package { type: string; } -export interface InlineQueryResult { - type: string; - id: string; - title?: string; - description?: string; - url?: string; - reply_markup?: any; - input_message_content?: any; -} - export class Search { static async search(query: string): Promise { return []; @@ -48,7 +40,7 @@ export class Pacman { public inline(limit = 49): InlineQueryResult[] { return this.results.slice(0, limit).map((item: Package) => ({ - type: "article", + type: "article" as const, id: crypto.randomUUID(), title: item.name, url: normalize(item), @@ -76,7 +68,7 @@ export class Pacman { public notFound(query: string): InlineQueryResult[] { return [{ - type: "article", + type: "article" as const, id: "404", title: "Xatolik yuz berdi!", description: `Ushbu ${query} ga oid natija topilmadi!`, @@ -95,7 +87,7 @@ export class Pacman { public noQuery(): InlineQueryResult[] { return [{ - type: "article", + type: "article" as const, id: "102", title: "Qidirishni boshlang!", description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", diff --git a/src/types/Tealdeer.ts b/src/types/Tealdeer.ts index 0e7cb93..50dbdc1 100644 --- a/src/types/Tealdeer.ts +++ b/src/types/Tealdeer.ts @@ -1,6 +1,8 @@ -import { InlineKeyboard } from "../deps"; +import { InlineKeyboard } from "grammy"; import crypto from "crypto"; +type InlineQueryResult = any; + interface File { name: string; [key: string]: any; @@ -13,16 +15,6 @@ interface Page { link: string; } -export interface InlineQueryResult { - type: string; - id: string; - title?: string; - description?: string; - url?: string; - reply_markup?: any; - input_message_content?: any; -} - const API_URL = "https://api.github.com/repos/tldr-pages/tldr/contents/pages"; const DL_URL = "https://raw.githubusercontent.com/tldr-pages/tldr/main/pages"; const WEB_URL = "https://tldr.inbrowser.app/pages"; @@ -38,13 +30,13 @@ export class Tealdeer { return this.results.length; } - public async query(type: string, page: string) { + public async query(type: string, page: string): Promise { const matches: string[] = []; const response = await fetch(`${API_URL}/${type}`); if (response.status != 200) return []; - const jsonData: File[] = await response.json(); + const jsonData = await response.json() as File[]; jsonData.forEach((file) => { const fileName = file.name.slice(0, -3); @@ -104,7 +96,7 @@ export class Tealdeer { public inline(limit = 49): InlineQueryResult[] { return this.results.slice(0, limit).map((page) => ({ - type: "article", + type: "article" as const, id: crypto.randomUUID(), title: page.title, description: page.description, @@ -119,7 +111,7 @@ export class Tealdeer { public notFound(query: string): InlineQueryResult[] { return [{ - type: "article", + type: "article" as const, id: "404tldr", title: "Xatolik yuz berdi!", description: `Ushbu ${query} ga oid sahifa topilmadi!`, @@ -139,7 +131,7 @@ export class Tealdeer { public noQuery(): InlineQueryResult[] { return [{ - type: "article", + type: "article" as const, id: "102", title: "Qidirishni boshlang!", description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", diff --git a/src/utils/sender.ts b/src/utils/sender.ts index 0d2ff13..1fa5cde 100644 --- a/src/utils/sender.ts +++ b/src/utils/sender.ts @@ -1,4 +1,4 @@ -import { Context, InlineKeyboard } from "../deps"; +import { Context, InlineKeyboard } from "grammy"; /** * Reply to message api but with topics support From 8a7c20b880f2327faa249f9a7d3c9bdcc600b944 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 21:36:14 +0500 Subject: [PATCH 3/9] refactor: change architecture clean and update naming --- package.json | 2 +- src/{delta => commands}/about.ts | 2 +- src/{delta => commands}/code.ts | 0 src/{delta => commands}/feedback.ts | 6 +- src/{delta => commands}/groups.ts | 0 src/{delta => commands}/help.ts | 0 src/{delta => commands}/honor.ts | 6 +- src/{delta/mod.ts => commands/index.ts} | 14 +- src/{delta => commands}/inline.ts | 15 +- src/{delta => commands}/rules.ts | 2 +- src/{delta => commands}/start.ts | 0 src/{delta => commands}/text.ts | 0 src/{delta => commands}/trigger.ts | 16 +- src/{delta => commands}/warrior.ts | 4 +- src/{delta => commands}/which.ts | 2 +- src/{utils => config}/cli.ts | 0 src/{utils => config}/config.ts | 16 +- src/config/index.ts | 3 + src/core.ts | 18 +- src/{utils/sender.ts => handlers/reply.ts} | 15 +- src/middleware/index.ts | 7 + src/{hooks => middleware}/isAdmin.ts | 0 src/{hooks => middleware}/isGroup.ts | 0 src/{hooks => middleware}/isHome.ts | 4 +- src/{hooks => middleware}/isPrivate.ts | 4 +- src/{hooks => middleware}/isReply.ts | 6 +- src/{hooks => middleware}/isUwU.ts | 4 +- src/services/index.ts | 3 + src/services/package-search.ts | 248 +++++++++++++++++++++ src/types/Pacman.ts | 112 ---------- src/types/Tealdeer.ts | 156 ------------- src/utils/normalize.ts | 5 +- 32 files changed, 330 insertions(+), 340 deletions(-) rename src/{delta => commands}/about.ts (95%) rename src/{delta => commands}/code.ts (100%) rename src/{delta => commands}/feedback.ts (82%) rename src/{delta => commands}/groups.ts (100%) rename src/{delta => commands}/help.ts (100%) rename src/{delta => commands}/honor.ts (86%) rename src/{delta/mod.ts => commands/index.ts} (88%) rename src/{delta => commands}/inline.ts (59%) rename src/{delta => commands}/rules.ts (96%) rename src/{delta => commands}/start.ts (100%) rename src/{delta => commands}/text.ts (100%) rename src/{delta => commands}/trigger.ts (87%) rename src/{delta => commands}/warrior.ts (90%) rename src/{delta => commands}/which.ts (95%) rename src/{utils => config}/cli.ts (100%) rename src/{utils => config}/config.ts (74%) create mode 100644 src/config/index.ts rename src/{utils/sender.ts => handlers/reply.ts} (61%) create mode 100644 src/middleware/index.ts rename src/{hooks => middleware}/isAdmin.ts (100%) rename src/{hooks => middleware}/isGroup.ts (100%) rename src/{hooks => middleware}/isHome.ts (81%) rename src/{hooks => middleware}/isPrivate.ts (81%) rename src/{hooks => middleware}/isReply.ts (60%) rename src/{hooks => middleware}/isUwU.ts (56%) create mode 100644 src/services/index.ts create mode 100644 src/services/package-search.ts delete mode 100644 src/types/Pacman.ts delete mode 100644 src/types/Tealdeer.ts diff --git a/package.json b/package.json index 2a97a51..4ed85ea 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "bot", "grammy" ], - "author": "", + "author": "Ecma Uzbekistan Jamiyati", "license": "MIT", "dependencies": { "grammy": "^1.36.1", diff --git a/src/delta/about.ts b/src/commands/about.ts similarity index 95% rename from src/delta/about.ts rename to src/commands/about.ts index e85f1ae..b255224 100644 --- a/src/delta/about.ts +++ b/src/commands/about.ts @@ -1,5 +1,5 @@ import { Composer, Context, InlineKeyboard } from "grammy"; -import isPrivate from "../hooks/isPrivate"; +import isPrivate from "../middleware/isPrivate"; const composer = new Composer(); diff --git a/src/delta/code.ts b/src/commands/code.ts similarity index 100% rename from src/delta/code.ts rename to src/commands/code.ts diff --git a/src/delta/feedback.ts b/src/commands/feedback.ts similarity index 82% rename from src/delta/feedback.ts rename to src/commands/feedback.ts index 7076cac..aefbe2f 100644 --- a/src/delta/feedback.ts +++ b/src/commands/feedback.ts @@ -1,6 +1,6 @@ import { Composer, Context, InlineKeyboard } from "grammy"; -import isPrivate from "../hooks/isPrivate"; -import { reply } from "../utils/sender"; +import isPrivate from "../middleware/isPrivate"; +import { replyWithTopic } from "../handlers/reply"; const composer = new Composer(); @@ -20,7 +20,7 @@ export const keyboard = new InlineKeyboard().url( ); composer.command("feedback", isPrivate, async (ctx: Context): Promise => { - return await reply(ctx, message(ctx), keyboard); + return await replyWithTopic(ctx, message(ctx), keyboard); }); export default composer; diff --git a/src/delta/groups.ts b/src/commands/groups.ts similarity index 100% rename from src/delta/groups.ts rename to src/commands/groups.ts diff --git a/src/delta/help.ts b/src/commands/help.ts similarity index 100% rename from src/delta/help.ts rename to src/commands/help.ts diff --git a/src/delta/honor.ts b/src/commands/honor.ts similarity index 86% rename from src/delta/honor.ts rename to src/commands/honor.ts index 5f25708..9965c2f 100644 --- a/src/delta/honor.ts +++ b/src/commands/honor.ts @@ -1,7 +1,7 @@ import { Composer, Context } from "grammy"; -import isAdmin from "../hooks/isAdmin"; -import isReply from "../hooks/isReply"; -import isGroup from "../hooks/isGroup"; +import isAdmin from "../middleware/isAdmin"; +import isReply from "../middleware/isReply"; +import isGroup from "../middleware/isGroup"; const composer = new Composer(); diff --git a/src/delta/mod.ts b/src/commands/index.ts similarity index 88% rename from src/delta/mod.ts rename to src/commands/index.ts index 7f8e3e0..e7a3f23 100644 --- a/src/delta/mod.ts +++ b/src/commands/index.ts @@ -1,19 +1,18 @@ import start from "./start"; import help from "./help"; -import inline from "./inline"; -import which from "./which"; -import { Bot } from "grammy"; import about from "./about"; import rules from "./rules"; -import text from "./text"; -import groups from "./groups"; +import which from "./which"; import honor from "./honor"; import warrior from "./warrior"; -import trigger from "./trigger"; +import inline from "./inline"; +import groups from "./groups"; import feedback from "./feedback"; +import trigger from "./trigger"; import code from "./code"; +import text from "./text"; -export const setupModules = (bot: Bot): void => { +export function setupCommands(bot: any): void { bot .use(start) .use(honor) @@ -29,3 +28,4 @@ export const setupModules = (bot: Bot): void => { .use(code) .use(text); } + diff --git a/src/delta/inline.ts b/src/commands/inline.ts similarity index 59% rename from src/delta/inline.ts rename to src/commands/inline.ts index 81ae67e..ccee631 100644 --- a/src/delta/inline.ts +++ b/src/commands/inline.ts @@ -1,26 +1,25 @@ import { Composer, Context } from "grammy"; -import { Pacman } from "../types/Pacman"; -import { Tealdeer } from "../types/Tealdeer"; +import { PacmanSearch, TealdeerSearch } from "../services"; const composer = new Composer(); composer.inlineQuery(/(.*)/ig, async (ctx: Context) => { let search: string | undefined; - let instance: Pacman | Tealdeer = new Pacman(); + let instance: PacmanSearch | TealdeerSearch = new PacmanSearch(); if (!ctx.inlineQuery?.query) { - return await ctx.answerInlineQuery(await instance.noQuery()); + return await ctx.answerInlineQuery(await instance.getEmptyQuery()); } const split = ctx.inlineQuery?.query.split(" "); switch (split![0]) { case "tldr": - instance = new Tealdeer(); + instance = new TealdeerSearch(); search = split?.slice(1).join(" "); break; default: - instance = new Pacman(); + instance = new PacmanSearch(); search = split?.join(" "); break; } @@ -28,11 +27,11 @@ composer.inlineQuery(/(.*)/ig, async (ctx: Context) => { await instance.search(search); if (instance.getLength() === 0) { - return await ctx.answerInlineQuery(await instance.notFound(search)); + return await ctx.answerInlineQuery(await instance.getNotFound(search)); } return await ctx.answerInlineQuery( - await instance.inline(), + await instance.getResults(), ); }); diff --git a/src/delta/rules.ts b/src/commands/rules.ts similarity index 96% rename from src/delta/rules.ts rename to src/commands/rules.ts index 1091a3e..06a62ad 100644 --- a/src/delta/rules.ts +++ b/src/commands/rules.ts @@ -1,5 +1,5 @@ import { Composer, Context, InlineKeyboard } from "grammy"; -import isPrivate from "../hooks/isPrivate"; +import isPrivate from "../middleware/isPrivate"; const composer = new Composer(); diff --git a/src/delta/start.ts b/src/commands/start.ts similarity index 100% rename from src/delta/start.ts rename to src/commands/start.ts diff --git a/src/delta/text.ts b/src/commands/text.ts similarity index 100% rename from src/delta/text.ts rename to src/commands/text.ts diff --git a/src/delta/trigger.ts b/src/commands/trigger.ts similarity index 87% rename from src/delta/trigger.ts rename to src/commands/trigger.ts index 27a0ce2..9c48b50 100644 --- a/src/delta/trigger.ts +++ b/src/commands/trigger.ts @@ -1,6 +1,6 @@ -import { reply } from "../utils/sender"; -import isReply from "../hooks/isReply"; -import topics from "../../topics.json"; +import { replyWithTopic } from "../handlers/reply"; +import isReply from "../middleware/isReply"; +import topics from "../topics.json"; import { Composer, Context, InlineKeyboard } from "grammy"; const composer = new Composer(); @@ -17,7 +17,7 @@ composer.command( : ctx.match!.join(" "); if (!Object.keys(topics).includes(requestedTopic)) { - return await reply( + return await replyWithTopic( ctx, `Bunaqangi topic bizda borga o'xshamaydiyov...\n\nBizda faqat quyidagi topic (mavzu)lar bor:` + `\n` + `${Object.keys(registeredTopics).join(" | ")}`, @@ -33,7 +33,7 @@ composer.command( if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { if (ctx.message) { - return await reply(ctx, `Ha-ha... yaxshi urinish!`); + return await replyWithTopic(ctx, `Ha-ha... yaxshi urinish!`); } } @@ -64,13 +64,13 @@ composer.command( `https://t.me/xinuxuz/${requestedTopicURL}`, ); - return await reply(ctx, text, keyboard); + return await replyWithTopic(ctx, text, keyboard); }, ); composer.command("doc", isReply, async (ctx: Context): Promise => { if (ctx?.message?.reply_to_message?.from?.id === ctx.me.id) { - return await reply(ctx, `Ha-ha... yaxshi urinish!`); + return await replyWithTopic(ctx, `Ha-ha... yaxshi urinish!`); } else { await ctx.api.deleteMessage( ctx.message!.chat!.id, @@ -88,7 +88,7 @@ composer.command("doc", isReply, async (ctx: Context): Promise => { `javob olsa bo'larkanda. Yanachi, unga avtorlar shunchalik ko'p vaqt ajratishar ` + `ekanu, lekin uni sanoqligina odam o'qisharkan. Attang...`; - return await reply(ctx, text); + return await replyWithTopic(ctx, text); } }); diff --git a/src/delta/warrior.ts b/src/commands/warrior.ts similarity index 90% rename from src/delta/warrior.ts rename to src/commands/warrior.ts index 0de5e36..d469933 100644 --- a/src/delta/warrior.ts +++ b/src/commands/warrior.ts @@ -1,6 +1,6 @@ import { Composer, Context, InputFile } from "grammy"; -import isUwU from "../hooks/isUwU"; -import isReply from "../hooks/isReply"; +import isUwU from "../middleware/isUwU"; +import isReply from "../middleware/isReply"; const composer = new Composer(); diff --git a/src/delta/which.ts b/src/commands/which.ts similarity index 95% rename from src/delta/which.ts rename to src/commands/which.ts index efbc07f..8ab6efe 100644 --- a/src/delta/which.ts +++ b/src/commands/which.ts @@ -1,5 +1,5 @@ import { Composer, Context } from "grammy"; -import isGroup from "../hooks/isGroup"; +import isGroup from "../middleware/isGroup"; const composer = new Composer(); diff --git a/src/utils/cli.ts b/src/config/cli.ts similarity index 100% rename from src/utils/cli.ts rename to src/config/cli.ts diff --git a/src/utils/config.ts b/src/config/config.ts similarity index 74% rename from src/utils/config.ts rename to src/config/config.ts index 617dbcb..d88b68c 100644 --- a/src/utils/config.ts +++ b/src/config/config.ts @@ -1,18 +1,18 @@ import * as fs from "fs"; import { parse } from "toml"; -export interface Configs { +export interface BotConfig { port: number; - mode: string; + mode: "webhook" | "polling"; host: string; token: string; } -export class Config { +export default class Config { private path: string; private host: string; private port: number; - private mode: string; + private mode: "webhook" | "polling"; private token: string; constructor(path: string) { @@ -25,7 +25,7 @@ export class Config { consume(): void { if (!fs.existsSync(this.path)) { - console.log("Does even your config file exists?"); + console.error("Config file does not exist:", this.path); process.exit(1); } @@ -33,12 +33,12 @@ export class Config { const data = parse(read) as any; this.port = data.port as number; - this.mode = data.mode as string; + this.mode = data.mode as "webhook" | "polling"; this.host = data.host as string; this.token = data.token as string; } - data(): Configs { + data(): BotConfig { return { host: this.host, port: this.port, @@ -47,5 +47,3 @@ export class Config { }; } } - -export default Config; diff --git a/src/config/index.ts b/src/config/index.ts new file mode 100644 index 0000000..38c6d92 --- /dev/null +++ b/src/config/index.ts @@ -0,0 +1,3 @@ +export { default as Config, BotConfig } from "./config"; +export { default as parseArgs } from "./cli"; + diff --git a/src/core.ts b/src/core.ts index 9d716b3..7a561ff 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1,11 +1,11 @@ import { Bot } from "grammy"; -import { setupModules } from "./delta/mod"; -import { Config, Configs } from "./utils/config"; -import args from "./utils/cli"; +import { setupCommands } from "./commands"; +import Config, { BotConfig } from "./config/config"; +import parseArgs from "./config/cli"; import express from "express"; -function setupWebhook(bot: Bot, config: Configs, app: express.Express): void { - console.log(`[INFO] bot is starting on ${config.mode}`); +function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { + console.info(`[INFO] bot is starting on ${config.mode}`); app.use(express.json()); @@ -38,18 +38,18 @@ async function startPolling(bot: Bot): Promise { } async function launch(): Promise { - if (args.config == undefined) { + if (parseArgs.config == undefined) { console.log("Path to config file is not defined!"); process.exit(1); } - const config = new Config(args.config); + const config = new Config(parseArgs.config); config.consume(); - const data: Configs = config.data(); + const data: BotConfig = config.data(); const bot = new Bot(data.token); - setupModules(bot); + setupCommands(bot); bot.catch((error) => { console.log(error, error.ctx.api); }); diff --git a/src/utils/sender.ts b/src/handlers/reply.ts similarity index 61% rename from src/utils/sender.ts rename to src/handlers/reply.ts index 1fa5cde..e934295 100644 --- a/src/utils/sender.ts +++ b/src/handlers/reply.ts @@ -1,16 +1,16 @@ import { Context, InlineKeyboard } from "grammy"; /** - * Reply to message api but with topics support - * @param ctx Context from Grammy.js middleware - * @param message The message you want to send - * @param buttons InlineKeyboard button to attach to the message + * Reply to message with topic support + * @param ctx - Grammy context + * @param message - Message text + * @param buttons - Optional inline keyboard */ -export const reply = async ( +export async function replyWithTopic( ctx: Context, message: string, buttons?: InlineKeyboard, -): Promise => { +): Promise { const config: { [key: string]: any } = { parse_mode: "HTML", }; @@ -24,4 +24,5 @@ export const reply = async ( } return await ctx.reply(message, config); -}; +} + diff --git a/src/middleware/index.ts b/src/middleware/index.ts new file mode 100644 index 0000000..2b75e7e --- /dev/null +++ b/src/middleware/index.ts @@ -0,0 +1,7 @@ +export { default as isAdmin } from "./isAdmin"; +export { default as isGroup } from "./isGroup"; +export { default as isHome } from "./isHome"; +export { default as isPrivate } from "./isPrivate"; +export { default as isReply } from "./isReply"; +export { default as isUwU } from "./isUwU"; + diff --git a/src/hooks/isAdmin.ts b/src/middleware/isAdmin.ts similarity index 100% rename from src/hooks/isAdmin.ts rename to src/middleware/isAdmin.ts diff --git a/src/hooks/isGroup.ts b/src/middleware/isGroup.ts similarity index 100% rename from src/hooks/isGroup.ts rename to src/middleware/isGroup.ts diff --git a/src/hooks/isHome.ts b/src/middleware/isHome.ts similarity index 81% rename from src/hooks/isHome.ts rename to src/middleware/isHome.ts index 7d812aa..0b808dd 100644 --- a/src/hooks/isHome.ts +++ b/src/middleware/isHome.ts @@ -1,5 +1,5 @@ import { Context, NextFunction, InlineKeyboard } from "grammy"; -import { reply } from "../utils/sender"; +import { replyWithTopic } from "../handlers/reply"; const keyboard = new InlineKeyboard().url( `Guruhimizga o'ting`, @@ -8,7 +8,7 @@ const keyboard = new InlineKeyboard().url( export default async (ctx: Context, next: NextFunction) => { if (ctx.chat!.id !== -1001174263940) { - return await reply( + return await replyWithTopic( ctx, `⚠️ Bu komanda faqat o'zimizni guruh uchun`, keyboard, diff --git a/src/hooks/isPrivate.ts b/src/middleware/isPrivate.ts similarity index 81% rename from src/hooks/isPrivate.ts rename to src/middleware/isPrivate.ts index d5157b8..18bd0ca 100644 --- a/src/hooks/isPrivate.ts +++ b/src/middleware/isPrivate.ts @@ -1,5 +1,5 @@ import { Context, NextFunction, InlineKeyboard } from "grammy"; -import { reply } from "../utils/sender"; +import { replyWithTopic } from "../handlers/reply"; const keyboard = new InlineKeyboard().url( `Shaxsiy Chat`, @@ -8,7 +8,7 @@ const keyboard = new InlineKeyboard().url( export default async (ctx: Context, next: NextFunction) => { if (ctx.chat!.type !== "private") { - return await reply( + return await replyWithTopic( ctx, `⚠️ Bu komanda faqat shaxsiy chat uchun!`, keyboard, diff --git a/src/hooks/isReply.ts b/src/middleware/isReply.ts similarity index 60% rename from src/hooks/isReply.ts rename to src/middleware/isReply.ts index ded29c5..b26c84d 100644 --- a/src/hooks/isReply.ts +++ b/src/middleware/isReply.ts @@ -1,13 +1,13 @@ -import { reply } from "../utils/sender"; +import { replyWithTopic } from "../handlers/reply"; import { Context, NextFunction } from "grammy"; -import topics from "../../topics.json"; +import topics from "../topics.json"; export default async (ctx: Context, next: NextFunction) => { if ( !ctx.message?.reply_to_message || Object.values(topics).includes(ctx.message!.reply_to_message!.message_id) ) { - return await reply(ctx, `↪ Reply bilan ko'rsatingchi habarni!`); + return await replyWithTopic(ctx, `↪ Reply bilan ko'rsatingchi habarni!`); } await next(); }; diff --git a/src/hooks/isUwU.ts b/src/middleware/isUwU.ts similarity index 56% rename from src/hooks/isUwU.ts rename to src/middleware/isUwU.ts index 59d099f..2dae8b0 100644 --- a/src/hooks/isUwU.ts +++ b/src/middleware/isUwU.ts @@ -1,9 +1,9 @@ import { Context, NextFunction } from "grammy"; -import { reply } from "../utils/sender"; +import { replyWithTopic } from "../handlers/reply"; export default async (ctx: Context, next: NextFunction) => { if (ctx.message!.from!.id! !== 756870298) { - return await reply(ctx, `⚠️ Bu komanda faqat Xinux Asoschisi uchun!`); + return await replyWithTopic(ctx, `⚠️ Bu komanda faqat Xinux Asoschisi uchun!`); } await next(); }; diff --git a/src/services/index.ts b/src/services/index.ts new file mode 100644 index 0000000..fb9c1ec --- /dev/null +++ b/src/services/index.ts @@ -0,0 +1,3 @@ +export { PacmanSearch, TealdeerSearch, SearchService } from "./package-search"; +export type { Package } from "./package-search"; + diff --git a/src/services/package-search.ts b/src/services/package-search.ts new file mode 100644 index 0000000..7611eba --- /dev/null +++ b/src/services/package-search.ts @@ -0,0 +1,248 @@ +import normalize from "../utils/normalize"; + +import { InlineKeyboard } from "grammy"; +import crypto from "crypto"; + +type InlineQueryResult = any; + +export interface Package { + name: string; + desc: string; + repo: string; + arch: string; + updated: string; + installed: string; + version: string; + install: string; + url?: string; + type: string; +} + +export class SearchService { + static async search(query: string): Promise { + // Implement Arch Linux package search + return []; + } +} + +export class PacmanSearch { + protected results: Package[]; + + constructor() { + this.results = []; + } + + public getLength(): number { + return this.results.length; + } + + public async search(query: string): Promise { + this.results = await SearchService.search(query); + } + + public getResults(limit = 49): InlineQueryResult[] { + return this.results.slice(0, limit).map((item: Package) => ({ + type: "article" as const, + id: crypto.randomUUID(), + title: item.name, + url: normalize(item), + description: item.desc, + reply_markup: new InlineKeyboard().url(`Web Sahifasi`, normalize(item)), + input_message_content: { + message_text: `Nomi: ${item.name}` + + `\n` + + (item.version && + "Versiyasi: " + item.version + `\n`) + + (item.desc && "Ma'lumot: " + item.desc + `\n`) + + (item.repo ? "Repozitoriya: " + item.repo + `\n` : "") + + (item.updated && + "O'zgartirilgan: " + + `${new Date(item.updated).toLocaleString()}` + + `\n`) + + `\n` + + `O'rnatish uchun:` + + `\n` + + `${item.install}`, + parse_mode: "HTML", + }, + })); + } + + public getNotFound(query: string): InlineQueryResult[] { + return [{ + type: "article" as const, + id: "404", + title: "Xatolik yuz berdi!", + description: `Ushbu ${query} ga oid natija topilmadi!`, + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "foobar", + ), + input_message_content: { + message_text: `"${query}" ga oid natija mavjud emas!` + + `\n` + + `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring.`, + parse_mode: "HTML", + }, + }]; + } + + public getEmptyQuery(): InlineQueryResult[] { + return [{ + type: "article" as const, + id: "102", + title: "Qidirishni boshlang!", + description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "foobar", + ), + input_message_content: { + message_text: `Salom foydalanuvchi!` + + `\n` + + `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + + `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + + `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + + `\n` + + `@xeonittebot \/tldr <sahifa nomi>` + + `\n` + + `yozasiz`, + parse_mode: "HTML", + }, + }]; + } +} + +export class TealdeerSearch { + protected results: any[]; + + constructor() { + this.results = []; + } + + public getLength(): number { + return this.results.length; + } + + public async query(type: string, page: string): Promise { + const matches: string[] = []; + const response = await fetch(`https://api.github.com/repos/tldr-pages/tldr/contents/pages/${type}`); + + if (response.status != 200) return []; + + const jsonData = await response.json() as any[]; + + jsonData.forEach((file) => { + const fileName = file.name.slice(0, -3); + if (fileName.startsWith(page)) { + if (fileName == page) { + matches.unshift(fileName); + } else { + matches.push(fileName); + } + } + }); + + return matches; + } + + public async getPage(type: string, page: string): Promise { + const response = await fetch(`https://raw.githubusercontent.com/tldr-pages/tldr/main/pages/${type}/${page}.md`); + const responseText = await response.text(); + const lines = responseText.split("\n").map((line) => { + if (line.startsWith(">")) { + return `_${line.slice(2)}_`; + } + return line; + }); + const title = lines[0].replace(/^#\s?/, ""); + lines[0] = `*${title}*`; + const content = lines.join("\n"); + + return { + title: title, + description: type, + content: content, + link: `https://tldr.inbrowser.app/pages/${type}/${page}`, + }; + } + + public async search(page: string): Promise { + const query = page.toLowerCase(); + const matches = await this.query("linux", query); + const pages = await Promise.all( + matches.map(async (page) => await this.getPage("linux", page)), + ); + + if (pages.length < 10) { + const _matches = await this.query("common", query); + const _pages = await Promise.all( + _matches.map(async (page) => await this.getPage("common", page)), + ); + pages.push(..._pages); + } + + this.results = pages; + } + + public getResults(limit = 49): InlineQueryResult[] { + return this.results.slice(0, limit).map((page) => ({ + type: "article" as const, + id: crypto.randomUUID(), + title: page.title, + description: page.description, + url: page.link, + reply_markup: new InlineKeyboard().url(`Brauzerda ko\'rish`, page.link), + input_message_content: { + message_text: page.content, + parse_mode: "Markdown", + }, + })); + } + + public getNotFound(query: string): InlineQueryResult[] { + return [{ + type: "article" as const, + id: "404tldr", + title: "Xatolik yuz berdi!", + description: `Ushbu ${query} ga oid sahifa topilmadi!`, + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "ls", + ), + input_message_content: { + message_text: `"${query}" ga oid natija mavjud emas!` + + `\n` + + `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan tldr sahifa` + + `nomini yozib qidirib ko'ring.`, + parse_mode: "HTML", + }, + }]; + } + + public getEmptyQuery(): InlineQueryResult[] { + return [{ + type: "article" as const, + id: "102", + title: "Qidirishni boshlang!", + description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "ls", + ), + input_message_content: { + message_text: `Salom foydalanuvchi!` + + `\n` + + `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + + `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + + `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + + `\n` + + `@xeonittebot \/tldr <sahifa nomi>` + + `\n` + + `yozasiz`, + parse_mode: "HTML", + }, + }]; + } +} + diff --git a/src/types/Pacman.ts b/src/types/Pacman.ts deleted file mode 100644 index bbf437c..0000000 --- a/src/types/Pacman.ts +++ /dev/null @@ -1,112 +0,0 @@ -import normalize from "../utils/normalize"; -import { InlineKeyboard } from "grammy"; -import crypto from "crypto"; - -type InlineQueryResult = any; - -export interface Package { - name: string; - desc: string; - repo: string; - arch: string; - updated: string; - installed: string; - version: string; - install: string; - url?: string; - type: string; -} - -export class Search { - static async search(query: string): Promise { - return []; - } -} - -export class Pacman { - protected results: Package[]; - - constructor() { - this.results = []; - } - - public getLength(): number { - return this.results.length; - } - - public async search(query: string) { - this.results = await Search.search(query); - } - - public inline(limit = 49): InlineQueryResult[] { - return this.results.slice(0, limit).map((item: Package) => ({ - type: "article" as const, - id: crypto.randomUUID(), - title: item.name, - url: normalize(item), - description: item.desc, - reply_markup: new InlineKeyboard().url(`Web Sahifasi`, normalize(item)), - input_message_content: { - message_text: `Nomi: ${item.name}` + - `\n` + - (item.version && - "Versiyasi: " + item.version + `\n`) + - (item.desc && "Ma'lumot: " + item.desc + `\n`) + - (item.repo ? "Repozitoriya: " + item.repo + `\n` : "") + - (item.updated && - "O'zgartirilgan: " + - `${new Date(item.updated).toLocaleString()}` + - `\n`) + - `\n` + - `O'rnatish uchun:` + - `\n` + - `${item.install}`, - parse_mode: "HTML", - }, - })); - } - - public notFound(query: string): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "404", - title: "Xatolik yuz berdi!", - description: `Ushbu ${query} ga oid natija topilmadi!`, - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "foobar", - ), - input_message_content: { - message_text: `"${query}" ga oid natija mavjud emas!` + - `\n` + - `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring.`, - parse_mode: "HTML", - }, - }]; - } - - public noQuery(): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "102", - title: "Qidirishni boshlang!", - description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "foobar", - ), - input_message_content: { - message_text: `Salom foydalanuvchi!` + - `\n` + - `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + - `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + - `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + - `\n` + - `@xeonittebot \/tldr <sahifa nomi>` + - `\n` + - `yozasiz`, - parse_mode: "HTML", - }, - }]; - } -} diff --git a/src/types/Tealdeer.ts b/src/types/Tealdeer.ts deleted file mode 100644 index 50dbdc1..0000000 --- a/src/types/Tealdeer.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { InlineKeyboard } from "grammy"; -import crypto from "crypto"; - -type InlineQueryResult = any; - -interface File { - name: string; - [key: string]: any; -} - -interface Page { - title: string; - description: string; - content: string; - link: string; -} - -const API_URL = "https://api.github.com/repos/tldr-pages/tldr/contents/pages"; -const DL_URL = "https://raw.githubusercontent.com/tldr-pages/tldr/main/pages"; -const WEB_URL = "https://tldr.inbrowser.app/pages"; - -export class Tealdeer { - protected results: Page[]; - - constructor() { - this.results = []; - } - - public getLength(): number { - return this.results.length; - } - - public async query(type: string, page: string): Promise { - const matches: string[] = []; - const response = await fetch(`${API_URL}/${type}`); - - if (response.status != 200) return []; - - const jsonData = await response.json() as File[]; - - jsonData.forEach((file) => { - const fileName = file.name.slice(0, -3); - if (fileName.startsWith(page)) { - if (fileName == page) { - matches.unshift(fileName); - } else { - matches.push(fileName); - } - } - }); - - return matches; - } - - public async getPage(type: string, page: string): Promise { - const response = await fetch(`${DL_URL}/${type}/${page}.md`); - - const responseText = await response.text(); - - const lines = responseText.split("\n").map((line) => { - if (line.startsWith(">")) { - return `_${line.slice(2)}_`; - } - return line; - }); - const title = lines[0].replace(/^#\s?/, ""); - - lines[0] = `*${title}*`; - const content = lines.join("\n"); - - return { - title: title, - description: type, - content: content, - link: `${WEB_URL}/${type}/${page}`, - }; - } - - public async search(page: string) { - const query = page.toLowerCase(); - const matches = await this.query("linux", query); - const pages = await Promise.all( - matches.map(async (page) => await this.getPage("linux", page)), - ); - - if (pages.length < 10) { - const _matches = await this.query("common", query); - const _pages = await Promise.all( - _matches.map(async (page) => await this.getPage("common", page)), - ); - pages.push(..._pages); - } - - this.results = pages; - } - - public inline(limit = 49): InlineQueryResult[] { - return this.results.slice(0, limit).map((page) => ({ - type: "article" as const, - id: crypto.randomUUID(), - title: page.title, - description: page.description, - url: page.link, - reply_markup: new InlineKeyboard().url(`Brauzerda ko\'rish`, page.link), - input_message_content: { - message_text: page.content, - parse_mode: "Markdown", - }, - })); - } - - public notFound(query: string): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "404tldr", - title: "Xatolik yuz berdi!", - description: `Ushbu ${query} ga oid sahifa topilmadi!`, - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "ls", - ), - input_message_content: { - message_text: `"${query}" ga oid natija mavjud emas!` + - `\n` + - `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan tldr sahifa` + - `nomini yozib qidirib ko'ring.`, - parse_mode: "HTML", - }, - }]; - } - - public noQuery(): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "102", - title: "Qidirishni boshlang!", - description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "ls", - ), - input_message_content: { - message_text: `Salom foydalanuvchi!` + - `\n` + - `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + - `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + - `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + - `\n` + - `@xeonittebot \/tldr <sahifa nomi>` + - `\n` + - `yozasiz`, - parse_mode: "HTML", - }, - }]; - } -} diff --git a/src/utils/normalize.ts b/src/utils/normalize.ts index 6f86482..caef164 100644 --- a/src/utils/normalize.ts +++ b/src/utils/normalize.ts @@ -7,7 +7,7 @@ interface Package { type: string; } -const normalize = (pack: Package): string => { +export default function normalize(pack: Package): string { if (pack.type === "aur") { if (pack.url) return pack.url; else return `https://aur.archlinux.org/packages/${pack.name}`; @@ -21,6 +21,5 @@ const normalize = (pack: Package): string => { } return "https://archlinux.org/"; -}; +} -export default normalize; From dddeef7d0d5d9084c8a4e11d8d012a1df0b65275 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 21:53:20 +0500 Subject: [PATCH 4/9] feat: added environment --- .env.example | 18 +- .gitignore | 15 + README.md | 43 +- package-lock.json | 1635 -------------------------------------- package.json | 36 +- pnpm-lock.yaml | 992 +++++++++++++++++++++++ src/commands/text.ts | 5 +- src/config/env.ts | 14 + src/{core.ts => main.ts} | 33 +- src/middleware/isHome.ts | 3 +- src/middleware/isUwU.ts | 3 +- src/services/index.ts | 3 +- topics.json | 20 - 13 files changed, 1100 insertions(+), 1720 deletions(-) delete mode 100644 package-lock.json create mode 100644 pnpm-lock.yaml create mode 100644 src/config/env.ts rename src/{core.ts => main.ts} (69%) delete mode 100755 topics.json diff --git a/.env.example b/.env.example index 178ad4f..28118f6 100755 --- a/.env.example +++ b/.env.example @@ -1,3 +1,15 @@ -TOKEN= -HOST= -MODE= +# Telegram Bot Configuration +BOT_TOKEN=your_bot_token_here + +# Bot Mode: polling or webhook +BOT_MODE=polling + +# Server Configuration +BOT_HOST=127.0.0.1 +BOT_PORT=8000 + +# Admin User ID (can be multiple IDs separated by comma) +ADMIN_USER_ID=756870298 + +# Home Chat ID (main group chat ID) +HOME_CHAT_ID=-1001174263940 diff --git a/.gitignore b/.gitignore index 397b0d9..4dc9c92 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,20 @@ +# Dependencies node_modules/ +.pnpm-store/ + +# Build output dist/ *.log + +# Environment .env +.env.local + +# System files .DS_Store +*.swp +*.swo + +# IDE +.vscode/ +.idea/ diff --git a/README.md b/README.md index 5fc6594..14cab6f 100755 --- a/README.md +++ b/README.md @@ -16,46 +16,29 @@ Ecma Uzbekistan consists of sub-communities which needs moderation tools like te ## Development -This project has been migrated to Node.js with Grammy.js. To get started: +This project has everything configured ready to get started with developer right away thanks to Nix package manager. In order to get started: ```bash -# Install dependencies -npm install +# Start development environment +nix develop -c $SHELL -# Create a config.toml file with your bot token -# Example: -# token = "YOUR_BOT_TOKEN" -# mode = "polling" -# host = "https://your-domain.com" -# port = 8000 +# Open favorite editor of your choice +zed . -# Start development server with hot reload -npm run dev -- --config config.toml - -# Or build and run in production -npm run build -npm run start -- --config config.toml -``` - -## Configuration - -Create a `config.toml` file with your bot configuration: - -```toml -token = "YOUR_BOT_TOKEN_HERE" -host = "127.0.0.1" -port = 8000 -mode = "polling" +# Start development server +npm run dev ``` ## Building +This project aims to build standalone javascript and deployed in [Kolyma Labs](https://github.com/kolyma-labs). Kolyma's NixOS server gets `nix build` output, but you can build it inside development environment using `npm` package manager. + ```bash -# Build for production -npm run build +# Building with nix` +nix build . -# Start production server -npm start -- --config config.toml +# Building with npm +npm run build ``` ## Thanks diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 653802f..0000000 --- a/package-lock.json +++ /dev/null @@ -1,1635 +0,0 @@ -{ - "name": "ecma-uz-telegram", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "ecma-uz-telegram", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@types/express": "^4.17.21", - "dotenv": "^16.4.5", - "express": "^4.18.2", - "grammy": "^1.36.1", - "toml": "^3.0.0" - }, - "devDependencies": { - "@types/node": "^20.11.5", - "tsx": "^4.7.1", - "typescript": "^5.3.3" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", - "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", - "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", - "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", - "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", - "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", - "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", - "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", - "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", - "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", - "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", - "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", - "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", - "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", - "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", - "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", - "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", - "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", - "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", - "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", - "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", - "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", - "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", - "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", - "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", - "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", - "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@grammyjs/types": { - "version": "3.22.2", - "resolved": "https://registry.npmjs.org/@grammyjs/types/-/types-3.22.2.tgz", - "integrity": "sha512-uu7DX2ezhnBPozL3bXHmwhLvaFsh59E4QyviNH4Cij7EdVekYrs6mCzeXsa2pDk30l3uXo7DBahlZLzTPtpYZg==", - "license": "MIT" - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.24.tgz", - "integrity": "sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg==", - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.19.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.23.tgz", - "integrity": "sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@types/send": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/dotenv": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", - "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", - "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.11", - "@esbuild/android-arm": "0.25.11", - "@esbuild/android-arm64": "0.25.11", - "@esbuild/android-x64": "0.25.11", - "@esbuild/darwin-arm64": "0.25.11", - "@esbuild/darwin-x64": "0.25.11", - "@esbuild/freebsd-arm64": "0.25.11", - "@esbuild/freebsd-x64": "0.25.11", - "@esbuild/linux-arm": "0.25.11", - "@esbuild/linux-arm64": "0.25.11", - "@esbuild/linux-ia32": "0.25.11", - "@esbuild/linux-loong64": "0.25.11", - "@esbuild/linux-mips64el": "0.25.11", - "@esbuild/linux-ppc64": "0.25.11", - "@esbuild/linux-riscv64": "0.25.11", - "@esbuild/linux-s390x": "0.25.11", - "@esbuild/linux-x64": "0.25.11", - "@esbuild/netbsd-arm64": "0.25.11", - "@esbuild/netbsd-x64": "0.25.11", - "@esbuild/openbsd-arm64": "0.25.11", - "@esbuild/openbsd-x64": "0.25.11", - "@esbuild/openharmony-arm64": "0.25.11", - "@esbuild/sunos-x64": "0.25.11", - "@esbuild/win32-arm64": "0.25.11", - "@esbuild/win32-ia32": "0.25.11", - "@esbuild/win32-x64": "0.25.11" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/grammy": { - "version": "1.38.3", - "resolved": "https://registry.npmjs.org/grammy/-/grammy-1.38.3.tgz", - "integrity": "sha512-1eQwNfxrRQ0JOFqd3n1nKqyWkHvCQRCNiH8e5aYm27mIjGPobgss58XN8GORC2ejAWM2+NSdUknrMhYj87cjGg==", - "license": "MIT", - "dependencies": { - "@grammyjs/types": "3.22.2", - "abort-controller": "^3.0.0", - "debug": "^4.4.3", - "node-fetch": "^2.7.0" - }, - "engines": { - "node": "^12.20.0 || >=14.13.1" - } - }, - "node_modules/grammy/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/grammy/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/toml": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", - "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", - "license": "MIT" - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/tsx": { - "version": "4.20.6", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", - "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "license": "MIT" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } -} diff --git a/package.json b/package.json index 4ed85ea..ccd8c5d 100644 --- a/package.json +++ b/package.json @@ -2,30 +2,34 @@ "name": "ecma-uz-telegram", "version": "1.0.0", "description": "Telegram bot for managing all sub-communities", - "main": "src/core.ts", + "main": "src/main.ts", + "author": { + "name": "Ecma Uzbekistan Hamjamiyati", + "email": "support@floss.uz", + "url": "https://ecma.uz" + }, + "license": "MIT", "scripts": { - "dev": "tsx watch src/core.ts", + "dev": "tsx watch src/main.ts", "build": "tsc", - "start": "node dist/core.js", - "start:src": "tsx src/core.ts" + "start": "node dist/main.js", + "prebuild": "rm -rf dist" }, - "keywords": [ - "telegram", - "bot", - "grammy" - ], - "author": "Ecma Uzbekistan Jamiyati", - "license": "MIT", "dependencies": { - "grammy": "^1.36.1", + "dotenv": "^16.4.5", "express": "^4.18.2", - "@types/express": "^4.17.21", - "toml": "^3.0.0", - "dotenv": "^16.4.5" + "grammy": "^1.36.1", + "toml": "^3.0.0" }, "devDependencies": { + "@types/express": "^4.17.21", "@types/node": "^20.11.5", "tsx": "^4.7.1", "typescript": "^5.3.3" - } + }, + "engines": { + "node": ">=18.0.0", + "pnpm": ">=8.15.0" + }, + "packageManager": "pnpm@8.15.0" } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d417797 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,992 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + dotenv: + specifier: ^16.4.5 + version: 16.6.1 + express: + specifier: ^4.18.2 + version: 4.21.2 + grammy: + specifier: ^1.36.1 + version: 1.38.3 + toml: + specifier: ^3.0.0 + version: 3.0.0 + +devDependencies: + '@types/express': + specifier: ^4.17.21 + version: 4.17.24 + '@types/node': + specifier: ^20.11.5 + version: 20.19.23 + tsx: + specifier: ^4.7.1 + version: 4.20.6 + typescript: + specifier: ^5.3.3 + version: 5.9.3 + +packages: + + /@esbuild/aix-ppc64@0.25.11: + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.25.11: + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.25.11: + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.25.11: + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.25.11: + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.25.11: + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.25.11: + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.25.11: + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.25.11: + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.25.11: + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.25.11: + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.25.11: + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.25.11: + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.25.11: + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.25.11: + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.25.11: + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.25.11: + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-arm64@0.25.11: + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.25.11: + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-arm64@0.25.11: + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.25.11: + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openharmony-arm64@0.25.11: + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.25.11: + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.25.11: + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.25.11: + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.25.11: + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@grammyjs/types@3.22.2: + resolution: {integrity: sha512-uu7DX2ezhnBPozL3bXHmwhLvaFsh59E4QyviNH4Cij7EdVekYrs6mCzeXsa2pDk30l3uXo7DBahlZLzTPtpYZg==} + dev: false + + /@types/body-parser@1.19.6: + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.19.23 + dev: true + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.19.23 + dev: true + + /@types/express-serve-static-core@4.19.7: + resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} + dependencies: + '@types/node': 20.19.23 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + dev: true + + /@types/express@4.17.24: + resolution: {integrity: sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg==} + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.7 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.10 + dev: true + + /@types/http-errors@2.0.5: + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + dev: true + + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + dev: true + + /@types/node@20.19.23: + resolution: {integrity: sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==} + dependencies: + undici-types: 6.21.0 + dev: true + + /@types/qs@6.14.0: + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + dev: true + + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + dev: true + + /@types/send@0.17.6: + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.19.23 + dev: true + + /@types/send@1.2.1: + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + dependencies: + '@types/node': 20.19.23 + dev: true + + /@types/serve-static@1.15.10: + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 20.19.23 + '@types/send': 0.17.6 + dev: true + + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: false + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: false + + /body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: false + + /call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + dev: false + + /call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: false + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: false + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: false + + /cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + dev: false + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: false + + /debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: false + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: false + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: false + + /dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dev: false + + /dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: false + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: false + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: false + + /encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + dev: false + + /es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: false + + /es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: false + + /esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + + /express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: false + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false + + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + dev: false + + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + dev: false + + /get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + dev: false + + /grammy@1.38.3: + resolution: {integrity: sha512-1eQwNfxrRQ0JOFqd3n1nKqyWkHvCQRCNiH8e5aYm27mIjGPobgss58XN8GORC2ejAWM2+NSdUknrMhYj87cjGg==} + engines: {node: ^12.20.0 || >=14.13.1} + dependencies: + '@grammyjs/types': 3.22.2 + abort-controller: 3.0.0 + debug: 4.4.3 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: false + + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + dev: false + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: false + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: false + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: false + + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + dev: false + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: false + + /merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + dev: false + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: false + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: false + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false + + /path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + dev: false + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: false + + /qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.1.0 + dev: false + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false + + /raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false + + /send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + dev: false + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: false + + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: false + + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: false + + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: false + + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: false + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: false + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: false + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.25.11 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: false + + /typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: false + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: false + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false diff --git a/src/commands/text.ts b/src/commands/text.ts index 117d143..32a8dc4 100644 --- a/src/commands/text.ts +++ b/src/commands/text.ts @@ -1,11 +1,12 @@ import { Composer, Context } from "grammy"; -import topics from "../../topics.json"; +import topics from "../topics.json"; +import env from "../config/env"; const composer = new Composer(); composer.on("message:text", async (ctx: Context): Promise => { if ( - ctx.chat!.id === -1001174263940 && + ctx.chat!.id === env.homeChatId && ctx.message!.message_thread_id === topics["neofetch"] ) { return await ctx.deleteMessage(); diff --git a/src/config/env.ts b/src/config/env.ts new file mode 100644 index 0000000..8062865 --- /dev/null +++ b/src/config/env.ts @@ -0,0 +1,14 @@ +import dotenv from "dotenv"; + +dotenv.config(); + +export default { + token: process.env.BOT_TOKEN || "", + mode: (process.env.BOT_MODE as "webhook" | "polling") || "polling", + host: process.env.BOT_HOST || "127.0.0.1", + port: parseInt(process.env.BOT_PORT || "8000", 10), + adminUserId: parseInt(process.env.ADMIN_USER_ID || "0", 10), + homeChatId: parseInt(process.env.HOME_CHAT_ID || "0", 10), + adminUserIds: process.env.ADMIN_USER_ID?.split(",").map(id => parseInt(id.trim(), 10)) || [], +}; + diff --git a/src/core.ts b/src/main.ts similarity index 69% rename from src/core.ts rename to src/main.ts index 7a561ff..4b4775a 100644 --- a/src/core.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { Bot } from "grammy"; import { setupCommands } from "./commands"; import Config, { BotConfig } from "./config/config"; import parseArgs from "./config/cli"; +import env from "./config/env"; import express from "express"; function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { @@ -29,7 +30,7 @@ function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { }); app.listen(config.port, "127.0.0.1", () => { - console.log(`Server listening on port ${config.port}`); + console.info(`Server listening on port ${config.port}`); }); }; @@ -38,20 +39,32 @@ async function startPolling(bot: Bot): Promise { } async function launch(): Promise { - if (parseArgs.config == undefined) { - console.log("Path to config file is not defined!"); - process.exit(1); - } - - const config = new Config(parseArgs.config); - config.consume(); + const useEnv = env.token !== ""; + let data: BotConfig; + + if (useEnv) { + data = { + token: env.token, + mode: env.mode, + host: env.host, + port: env.port, + }; + } else { + if (parseArgs.config == undefined) { + console.error("BOT_TOKEN environment variable or --config argument required!"); + process.exit(1); + } - const data: BotConfig = config.data(); + const config = new Config(parseArgs.config); + config.consume(); + data = config.data(); + } + const bot = new Bot(data.token); setupCommands(bot); bot.catch((error) => { - console.log(error, error.ctx.api); + console.error(error, error.ctx.api); }); const app = express(); diff --git a/src/middleware/isHome.ts b/src/middleware/isHome.ts index 0b808dd..d597d99 100644 --- a/src/middleware/isHome.ts +++ b/src/middleware/isHome.ts @@ -1,5 +1,6 @@ import { Context, NextFunction, InlineKeyboard } from "grammy"; import { replyWithTopic } from "../handlers/reply"; +import env from "../config/env"; const keyboard = new InlineKeyboard().url( `Guruhimizga o'ting`, @@ -7,7 +8,7 @@ const keyboard = new InlineKeyboard().url( ); export default async (ctx: Context, next: NextFunction) => { - if (ctx.chat!.id !== -1001174263940) { + if (ctx.chat!.id !== env.homeChatId) { return await replyWithTopic( ctx, `⚠️ Bu komanda faqat o'zimizni guruh uchun`, diff --git a/src/middleware/isUwU.ts b/src/middleware/isUwU.ts index 2dae8b0..bd9124b 100644 --- a/src/middleware/isUwU.ts +++ b/src/middleware/isUwU.ts @@ -1,8 +1,9 @@ import { Context, NextFunction } from "grammy"; import { replyWithTopic } from "../handlers/reply"; +import env from "../config/env"; export default async (ctx: Context, next: NextFunction) => { - if (ctx.message!.from!.id! !== 756870298) { + if (!env.adminUserIds.includes(ctx.message!.from!.id!)) { return await replyWithTopic(ctx, `⚠️ Bu komanda faqat Xinux Asoschisi uchun!`); } await next(); diff --git a/src/services/index.ts b/src/services/index.ts index fb9c1ec..bdbd526 100644 --- a/src/services/index.ts +++ b/src/services/index.ts @@ -1,3 +1,2 @@ -export { PacmanSearch, TealdeerSearch, SearchService } from "./package-search"; -export type { Package } from "./package-search"; +export { PacmanSearch, TealdeerSearch, SearchService, type Package } from "./package-search"; diff --git a/topics.json b/topics.json deleted file mode 100755 index 8a068f8..0000000 --- a/topics.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "asosiy": 0, - "xinux": 178640, - "coding": 180629, - "yordam": 178646, - "devops": 179980, - "offtopic": 178666, - "redhat": 180526, - "windows": 180916, - "neofetch": 178654, - "unix": 180689, - "debian": 180507, - "i10n": 182187, - "macos": 180536, - "gaming": 195168, - "meme": 207822, - "learning": 207118, - "fikrlar": 258076, - "moderator": 255895 -} From ea9f789cf69d5dfed61b59bea904122b969beb52 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 22:09:55 +0500 Subject: [PATCH 5/9] fix: fucking revert nix configurate and configurate just file --- .env.example | 2 +- default.nix | 28 +++++++++++++++++ flake.nix | 40 +++++++++++++++++++++++++ justfile | 17 +++++++++++ shell.nix | 54 +++++++++++++++++++++++++++++++++ src/main.ts | 85 ---------------------------------------------------- 6 files changed, 140 insertions(+), 86 deletions(-) create mode 100644 default.nix create mode 100644 flake.nix create mode 100644 justfile create mode 100644 shell.nix delete mode 100644 src/main.ts diff --git a/.env.example b/.env.example index 28118f6..c6d03aa 100755 --- a/.env.example +++ b/.env.example @@ -11,5 +11,5 @@ BOT_PORT=8000 # Admin User ID (can be multiple IDs separated by comma) ADMIN_USER_ID=756870298 -# Home Chat ID (main group chat ID) +# Home Chat ID (main group chat ID, start with -100) HOME_CHAT_ID=-1001174263940 diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..5e63508 --- /dev/null +++ b/default.nix @@ -0,0 +1,28 @@ +{pkgs ? import {}, ...}: let + lib = pkgs.lib; +in + pkgs.stdenv.mkDerivation { + pname = "telegram"; + version = "0.0.1"; + + src = ./.; + + buildInputs = with pkgs; [ + deno + ]; + + buildPhase = '' + deno compile ./mod.ts + ''; + + installPhase = '' + mkdir -p $out/bin + echo "something" > $out/bin/something + ''; + + meta = with lib; { + homepage = "https://ecma.uz"; + description = "Telergam bot of Ecma Uzbekistan"; + platforms = with platforms; darwin ++ linux; + }; + } diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..adbf4a1 --- /dev/null +++ b/flake.nix @@ -0,0 +1,40 @@ +{ + description = "Telegram bot for Ecma Uzbekistan"; + + inputs = { + # Too old to work with most libraries + # nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; + + # Perfect! + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + + # The flake-utils library + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { + self, + nixpkgs, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem + ( + system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + # Nix script formatter + formatter = pkgs.alejandra; + + # Development environment + devShells.default = import ./shell.nix {inherit pkgs;}; + + # Output package + packages.default = pkgs.callPackage ./. {}; + } + ); + # // { + # # Overlay module + # nixosModules.bot = import ./module.nix self; + # }; +} diff --git a/justfile b/justfile new file mode 100644 index 0000000..e8fa2a7 --- /dev/null +++ b/justfile @@ -0,0 +1,17 @@ +dev: + pnpm dev + +build: + pnpm build + +start: + pnpm start + +install: + pnpm install + +clean: + rm -rf dist node_modules + +fmt: + pnpm exec tsc --noEmit diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..88d01f1 --- /dev/null +++ b/shell.nix @@ -0,0 +1,54 @@ +{pkgs ? import {}}: let + getLibFolder = pkg: "${pkg}/lib"; +in + pkgs.stdenv.mkDerivation { + name = "bot"; + + nativeBuildInputs = with pkgs; [ + # LLVM & GCC + deno + + # Launch scripts + just + + # Hail the Nix + nixd + statix + deadnix + alejandra + ]; + + buildInputs = with pkgs; [ + openssl + ]; + + + shellHook = '' + # Load the environment variables from the .env file + # if [ ! -f .env ]; then + # echo "Please enter your telegram bot token: "; + # read -r TELOXIDE_TOKEN; + # echo "TELOXIDE_TOKEN=$TELOXIDE_TOKEN" > .env; + # else + # source .env; + # fi + + # Set the environment variable + # export TELOXIDE_TOKEN=$TELOXIDE_TOKEN; + + # Start watching for changes + # Start watching for changes in the background + # cargo watch -x "run --bin bot" & + + # Store the PID of the background process + # CARGO_WATCH_PID=$! + + # Function to clean up the background process on exit + # cleanup() { + # kill $CARGO_WATCH_PID + # } + + # Trap EXIT signal to run cleanup function + # trap cleanup EXIT + ''; + } diff --git a/src/main.ts b/src/main.ts deleted file mode 100644 index 4b4775a..0000000 --- a/src/main.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Bot } from "grammy"; -import { setupCommands } from "./commands"; -import Config, { BotConfig } from "./config/config"; -import parseArgs from "./config/cli"; -import env from "./config/env"; -import express from "express"; - -function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { - console.info(`[INFO] bot is starting on ${config.mode}`); - - app.use(express.json()); - - app.post(`/${bot.token}`, async (req, res) => { - try { - await bot.handleUpdate(req.body); - res.sendStatus(200); - } catch (err) { - console.error(err); - res.sendStatus(500); - } - }); - - app.get("/", async (req, res) => { - try { - await bot.api.setWebhook(`${config.host}/${bot.token}`); - res.send("Done. Set"); - } catch (_) { - res.send("Couldn't succeed with installing webhook"); - } - }); - - app.listen(config.port, "127.0.0.1", () => { - console.info(`Server listening on port ${config.port}`); - }); -}; - -async function startPolling(bot: Bot): Promise { - await bot.start(); -} - -async function launch(): Promise { - const useEnv = env.token !== ""; - let data: BotConfig; - - if (useEnv) { - data = { - token: env.token, - mode: env.mode, - host: env.host, - port: env.port, - }; - } else { - if (parseArgs.config == undefined) { - console.error("BOT_TOKEN environment variable or --config argument required!"); - process.exit(1); - } - - const config = new Config(parseArgs.config); - config.consume(); - data = config.data(); - } - - const bot = new Bot(data.token); - - setupCommands(bot); - bot.catch((error) => { - console.error(error, error.ctx.api); - }); - - const app = express(); - - switch (data.mode) { - case "webhook": - setupWebhook(bot, data, app); - break; - case "polling": - await startPolling(bot); - break; - default: - throw new Error(`Invalid deployment mode: ${data.mode}`); - } -}; - -launch(); - From 6ad18017396847a4d26d8a2831626340490ea094 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 22:10:43 +0500 Subject: [PATCH 6/9] chore: flake lock generate --- flake.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 flake.lock diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..1f39180 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1761373498, + "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} From e78f9ccaff82f91635e57b52d0579bb5e2c6f034 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 22:14:47 +0500 Subject: [PATCH 7/9] fix: update main file flake lock --- flake.lock | 4 +-- src/main.ts | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/main.ts diff --git a/flake.lock b/flake.lock index 1f39180..d0c8490 100644 --- a/flake.lock +++ b/flake.lock @@ -22,13 +22,13 @@ "locked": { "lastModified": 1761373498, "narHash": "sha256-Q/uhWNvd7V7k1H1ZPMy/vkx3F8C13ZcdrKjO7Jv7v0c=", - "owner": "NixOS", + "owner": "nixos", "repo": "nixpkgs", "rev": "6a08e6bb4e46ff7fcbb53d409b253f6bad8a28ce", "type": "github" }, "original": { - "owner": "NixOS", + "owner": "nixos", "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..4b4775a --- /dev/null +++ b/src/main.ts @@ -0,0 +1,85 @@ +import { Bot } from "grammy"; +import { setupCommands } from "./commands"; +import Config, { BotConfig } from "./config/config"; +import parseArgs from "./config/cli"; +import env from "./config/env"; +import express from "express"; + +function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { + console.info(`[INFO] bot is starting on ${config.mode}`); + + app.use(express.json()); + + app.post(`/${bot.token}`, async (req, res) => { + try { + await bot.handleUpdate(req.body); + res.sendStatus(200); + } catch (err) { + console.error(err); + res.sendStatus(500); + } + }); + + app.get("/", async (req, res) => { + try { + await bot.api.setWebhook(`${config.host}/${bot.token}`); + res.send("Done. Set"); + } catch (_) { + res.send("Couldn't succeed with installing webhook"); + } + }); + + app.listen(config.port, "127.0.0.1", () => { + console.info(`Server listening on port ${config.port}`); + }); +}; + +async function startPolling(bot: Bot): Promise { + await bot.start(); +} + +async function launch(): Promise { + const useEnv = env.token !== ""; + let data: BotConfig; + + if (useEnv) { + data = { + token: env.token, + mode: env.mode, + host: env.host, + port: env.port, + }; + } else { + if (parseArgs.config == undefined) { + console.error("BOT_TOKEN environment variable or --config argument required!"); + process.exit(1); + } + + const config = new Config(parseArgs.config); + config.consume(); + data = config.data(); + } + + const bot = new Bot(data.token); + + setupCommands(bot); + bot.catch((error) => { + console.error(error, error.ctx.api); + }); + + const app = express(); + + switch (data.mode) { + case "webhook": + setupWebhook(bot, data, app); + break; + case "polling": + await startPolling(bot); + break; + default: + throw new Error(`Invalid deployment mode: ${data.mode}`); + } +}; + +launch(); + From a60ce4efc5b5e80e84e6aa333c31a53340d36f35 Mon Sep 17 00:00:00 2001 From: warnigo Date: Sun, 26 Oct 2025 22:21:22 +0500 Subject: [PATCH 8/9] fix: fucking update config --- .env.example | 14 ++++-------- package.json | 3 +-- pnpm-lock.yaml | 7 ------ src/commands/text.ts | 4 ++-- src/config/cli.ts | 9 -------- src/config/config.ts | 49 ---------------------------------------- src/config/env.ts | 14 ------------ src/config/index.ts | 33 +++++++++++++++++++++++++-- src/main.ts | 37 ++++++------------------------ src/middleware/isHome.ts | 4 ++-- src/middleware/isUwU.ts | 4 ++-- 11 files changed, 49 insertions(+), 129 deletions(-) delete mode 100644 src/config/cli.ts delete mode 100644 src/config/config.ts delete mode 100644 src/config/env.ts diff --git a/.env.example b/.env.example index c6d03aa..de4ae43 100755 --- a/.env.example +++ b/.env.example @@ -1,15 +1,9 @@ -# Telegram Bot Configuration -BOT_TOKEN=your_bot_token_here - -# Bot Mode: polling or webhook +BOT_TOKEN= +# webhook or polling BOT_MODE=polling -# Server Configuration BOT_HOST=127.0.0.1 BOT_PORT=8000 -# Admin User ID (can be multiple IDs separated by comma) -ADMIN_USER_ID=756870298 - -# Home Chat ID (main group chat ID, start with -100) -HOME_CHAT_ID=-1001174263940 +ADMIN_USER_ID= +HOME_CHAT_ID= diff --git a/package.json b/package.json index ccd8c5d..fb0e7f2 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,7 @@ "dependencies": { "dotenv": "^16.4.5", "express": "^4.18.2", - "grammy": "^1.36.1", - "toml": "^3.0.0" + "grammy": "^1.36.1" }, "devDependencies": { "@types/express": "^4.17.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d417797..98b98cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ dependencies: grammy: specifier: ^1.36.1 version: 1.38.3 - toml: - specifier: ^3.0.0 - version: 3.0.0 devDependencies: '@types/express': @@ -928,10 +925,6 @@ packages: engines: {node: '>=0.6'} dev: false - /toml@3.0.0: - resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} - dev: false - /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false diff --git a/src/commands/text.ts b/src/commands/text.ts index 32a8dc4..31d1ec4 100644 --- a/src/commands/text.ts +++ b/src/commands/text.ts @@ -1,12 +1,12 @@ import { Composer, Context } from "grammy"; import topics from "../topics.json"; -import env from "../config/env"; +import { config } from "../config"; const composer = new Composer(); composer.on("message:text", async (ctx: Context): Promise => { if ( - ctx.chat!.id === env.homeChatId && + ctx.chat!.id === config.homeChatId && ctx.message!.message_thread_id === topics["neofetch"] ) { return await ctx.deleteMessage(); diff --git a/src/config/cli.ts b/src/config/cli.ts deleted file mode 100644 index f80d33c..0000000 --- a/src/config/cli.ts +++ /dev/null @@ -1,9 +0,0 @@ -const args: { [key: string]: string | undefined } = {}; - -for (let i = 0; i < process.argv.length; i++) { - if (process.argv[i].startsWith("--") && process.argv[i + 1]) { - args[process.argv[i].slice(2)] = process.argv[i + 1]; - } -} - -export default args; diff --git a/src/config/config.ts b/src/config/config.ts deleted file mode 100644 index d88b68c..0000000 --- a/src/config/config.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as fs from "fs"; -import { parse } from "toml"; - -export interface BotConfig { - port: number; - mode: "webhook" | "polling"; - host: string; - token: string; -} - -export default class Config { - private path: string; - private host: string; - private port: number; - private mode: "webhook" | "polling"; - private token: string; - - constructor(path: string) { - this.mode = "polling"; - this.token = ""; - this.host = "127.0.0.1"; - this.port = 8000; - this.path = path; - } - - consume(): void { - if (!fs.existsSync(this.path)) { - console.error("Config file does not exist:", this.path); - process.exit(1); - } - - const read = fs.readFileSync(this.path, "utf-8"); - const data = parse(read) as any; - - this.port = data.port as number; - this.mode = data.mode as "webhook" | "polling"; - this.host = data.host as string; - this.token = data.token as string; - } - - data(): BotConfig { - return { - host: this.host, - port: this.port, - mode: this.mode, - token: this.token, - }; - } -} diff --git a/src/config/env.ts b/src/config/env.ts deleted file mode 100644 index 8062865..0000000 --- a/src/config/env.ts +++ /dev/null @@ -1,14 +0,0 @@ -import dotenv from "dotenv"; - -dotenv.config(); - -export default { - token: process.env.BOT_TOKEN || "", - mode: (process.env.BOT_MODE as "webhook" | "polling") || "polling", - host: process.env.BOT_HOST || "127.0.0.1", - port: parseInt(process.env.BOT_PORT || "8000", 10), - adminUserId: parseInt(process.env.ADMIN_USER_ID || "0", 10), - homeChatId: parseInt(process.env.HOME_CHAT_ID || "0", 10), - adminUserIds: process.env.ADMIN_USER_ID?.split(",").map(id => parseInt(id.trim(), 10)) || [], -}; - diff --git a/src/config/index.ts b/src/config/index.ts index 38c6d92..23e650f 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,3 +1,32 @@ -export { default as Config, BotConfig } from "./config"; -export { default as parseArgs } from "./cli"; +import dotenv from "dotenv"; +dotenv.config(); + +interface BotConfig { + token: string; + mode: "webhook" | "polling"; + host: string; + port: number; + adminUserIds: number[]; + homeChatId: number; +} + +function loadConfig(): BotConfig { + const token = process.env.BOT_TOKEN; + if (!token) { + throw new Error("BOT_TOKEN environment variable is required!"); + } + + return { + token, + mode: (process.env.BOT_MODE as "webhook" | "polling") || "polling", + host: process.env.BOT_HOST || "127.0.0.1", + port: parseInt(process.env.BOT_PORT || "8000", 10), + adminUserIds: process.env.ADMIN_USER_ID + ? process.env.ADMIN_USER_ID.split(",").map(id => parseInt(id.trim(), 10)) + : [], + homeChatId: parseInt(process.env.HOME_CHAT_ID || "0", 10), + }; +} + +export const config = loadConfig(); diff --git a/src/main.ts b/src/main.ts index 4b4775a..54b5b97 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,10 @@ import { Bot } from "grammy"; import { setupCommands } from "./commands"; -import Config, { BotConfig } from "./config/config"; -import parseArgs from "./config/cli"; -import env from "./config/env"; +import { config } from "./config"; import express from "express"; -function setupWebhook(bot: Bot, config: BotConfig, app: express.Express): void { - console.info(`[INFO] bot is starting on ${config.mode}`); +function setupWebhook(bot: Bot, app: express.Express): void { + console.info(`[INFO] Bot is starting in ${config.mode} mode`); app.use(express.json()); @@ -39,28 +37,7 @@ async function startPolling(bot: Bot): Promise { } async function launch(): Promise { - const useEnv = env.token !== ""; - let data: BotConfig; - - if (useEnv) { - data = { - token: env.token, - mode: env.mode, - host: env.host, - port: env.port, - }; - } else { - if (parseArgs.config == undefined) { - console.error("BOT_TOKEN environment variable or --config argument required!"); - process.exit(1); - } - - const config = new Config(parseArgs.config); - config.consume(); - data = config.data(); - } - - const bot = new Bot(data.token); + const bot = new Bot(config.token); setupCommands(bot); bot.catch((error) => { @@ -69,15 +46,15 @@ async function launch(): Promise { const app = express(); - switch (data.mode) { + switch (config.mode) { case "webhook": - setupWebhook(bot, data, app); + setupWebhook(bot, app); break; case "polling": await startPolling(bot); break; default: - throw new Error(`Invalid deployment mode: ${data.mode}`); + throw new Error(`Invalid deployment mode: ${config.mode}`); } }; diff --git a/src/middleware/isHome.ts b/src/middleware/isHome.ts index d597d99..6a8aa62 100644 --- a/src/middleware/isHome.ts +++ b/src/middleware/isHome.ts @@ -1,6 +1,6 @@ import { Context, NextFunction, InlineKeyboard } from "grammy"; import { replyWithTopic } from "../handlers/reply"; -import env from "../config/env"; +import { config } from "../config"; const keyboard = new InlineKeyboard().url( `Guruhimizga o'ting`, @@ -8,7 +8,7 @@ const keyboard = new InlineKeyboard().url( ); export default async (ctx: Context, next: NextFunction) => { - if (ctx.chat!.id !== env.homeChatId) { + if (ctx.chat!.id !== config.homeChatId) { return await replyWithTopic( ctx, `⚠️ Bu komanda faqat o'zimizni guruh uchun`, diff --git a/src/middleware/isUwU.ts b/src/middleware/isUwU.ts index bd9124b..106dd15 100644 --- a/src/middleware/isUwU.ts +++ b/src/middleware/isUwU.ts @@ -1,9 +1,9 @@ import { Context, NextFunction } from "grammy"; import { replyWithTopic } from "../handlers/reply"; -import env from "../config/env"; +import { config } from "../config"; export default async (ctx: Context, next: NextFunction) => { - if (!env.adminUserIds.includes(ctx.message!.from!.id!)) { + if (!config.adminUserIds.includes(ctx.message!.from!.id!)) { return await replyWithTopic(ctx, `⚠️ Bu komanda faqat Xinux Asoschisi uchun!`); } await next(); From e3e70afa48f272c47b00b79f04cf637a6205e94e Mon Sep 17 00:00:00 2001 From: warnigo Date: Tue, 28 Oct 2025 10:07:08 +0500 Subject: [PATCH 9/9] fix: remove honor command and typo nomalization some --- src/commands/honor.ts | 28 ------ src/commands/index.ts | 3 - src/commands/start.ts | 8 +- src/config/index.ts | 6 +- src/main.ts | 46 +-------- src/services/package-search.ts | 176 ++++++++++++++++++--------------- 6 files changed, 104 insertions(+), 163 deletions(-) delete mode 100644 src/commands/honor.ts diff --git a/src/commands/honor.ts b/src/commands/honor.ts deleted file mode 100644 index 9965c2f..0000000 --- a/src/commands/honor.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Composer, Context } from "grammy"; -import isAdmin from "../middleware/isAdmin"; -import isReply from "../middleware/isReply"; -import isGroup from "../middleware/isGroup"; - -const composer = new Composer(); - -composer.command("honor", isAdmin, isReply, isGroup, async (ctx: Context) => { - const userFirstName = ctx.message?.reply_to_message?.from?.first_name - ? ctx.message?.reply_to_message?.from?.first_name - : ""; - const userlastName = ctx.message?.reply_to_message?.from?.last_name - ? ctx.message?.reply_to_message?.from?.last_name - : ""; - const username = ctx.message?.reply_to_message?.from?.username - ? ctx.message?.reply_to_message?.from?.username - : ""; - let url: string; - - if (userFirstName || userlastName) { - url = - `https://og.xinux.uz/api/honor?full_name=${userFirstName}%20${userlastName}`; - } else url = `https://og.xinux.uz/api/honor?full_name=${username}`; - - await ctx.reply(url); -}); - -export default composer; diff --git a/src/commands/index.ts b/src/commands/index.ts index e7a3f23..63782b1 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -3,7 +3,6 @@ import help from "./help"; import about from "./about"; import rules from "./rules"; import which from "./which"; -import honor from "./honor"; import warrior from "./warrior"; import inline from "./inline"; import groups from "./groups"; @@ -15,7 +14,6 @@ import text from "./text"; export function setupCommands(bot: any): void { bot .use(start) - .use(honor) .use(help) .use(groups) .use(inline) @@ -28,4 +26,3 @@ export function setupCommands(bot: any): void { .use(code) .use(text); } - diff --git a/src/commands/start.ts b/src/commands/start.ts index 092de4d..9932251 100644 --- a/src/commands/start.ts +++ b/src/commands/start.ts @@ -6,13 +6,13 @@ export const message: string = `Assalomu alaykum, hurmatli administrator! \n` + `\n` + `Sizni ko'rib turganimdan bag'oyatda xursandman. ` + - `Men Xinux Jamiyati tomonidan yaratilgan bot hisoblanib, ` + - `Xinux Jamiyati foydalanuvchilari uchun foydali resurslarni yetkazish, saqlash va ` + + `Men Ecma.uz hamjamiyati tomonidan yaratilgan bot hisoblanib, ` + + `Ecma hamjamiyati foydalanuvchilari uchun foydali resurslarni yetkazish, saqlash va ` + `ularni saralash uchun xizmat qilaman.`; export const keyboard = new InlineKeyboard() - .url("Jamiyat", "https://t.me/xinuxuz") - .url("Web Sahifa", "https://xinux.uz"); + .url("React hamjamiyati", "https://t.me/react_uz") + .url("Node.js hamjamiyati", "https://t.me/nodejs_uz"); composer.command("start", async (ctx: Context): Promise => { if (ctx.message?.message_thread_id) { diff --git a/src/config/index.ts b/src/config/index.ts index 23e650f..614dc27 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -4,7 +4,6 @@ dotenv.config(); interface BotConfig { token: string; - mode: "webhook" | "polling"; host: string; port: number; adminUserIds: number[]; @@ -19,11 +18,12 @@ function loadConfig(): BotConfig { return { token, - mode: (process.env.BOT_MODE as "webhook" | "polling") || "polling", host: process.env.BOT_HOST || "127.0.0.1", port: parseInt(process.env.BOT_PORT || "8000", 10), adminUserIds: process.env.ADMIN_USER_ID - ? process.env.ADMIN_USER_ID.split(",").map(id => parseInt(id.trim(), 10)) + ? process.env.ADMIN_USER_ID.split(",").map((id) => + parseInt(id.trim(), 10), + ) : [], homeChatId: parseInt(process.env.HOME_CHAT_ID || "0", 10), }; diff --git a/src/main.ts b/src/main.ts index 54b5b97..5682be8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,36 +1,6 @@ import { Bot } from "grammy"; import { setupCommands } from "./commands"; import { config } from "./config"; -import express from "express"; - -function setupWebhook(bot: Bot, app: express.Express): void { - console.info(`[INFO] Bot is starting in ${config.mode} mode`); - - app.use(express.json()); - - app.post(`/${bot.token}`, async (req, res) => { - try { - await bot.handleUpdate(req.body); - res.sendStatus(200); - } catch (err) { - console.error(err); - res.sendStatus(500); - } - }); - - app.get("/", async (req, res) => { - try { - await bot.api.setWebhook(`${config.host}/${bot.token}`); - res.send("Done. Set"); - } catch (_) { - res.send("Couldn't succeed with installing webhook"); - } - }); - - app.listen(config.port, "127.0.0.1", () => { - console.info(`Server listening on port ${config.port}`); - }); -}; async function startPolling(bot: Bot): Promise { await bot.start(); @@ -44,19 +14,7 @@ async function launch(): Promise { console.error(error, error.ctx.api); }); - const app = express(); - - switch (config.mode) { - case "webhook": - setupWebhook(bot, app); - break; - case "polling": - await startPolling(bot); - break; - default: - throw new Error(`Invalid deployment mode: ${config.mode}`); - } -}; + await startPolling(bot); +} launch(); - diff --git a/src/services/package-search.ts b/src/services/package-search.ts index 7611eba..a32c838 100644 --- a/src/services/package-search.ts +++ b/src/services/package-search.ts @@ -20,7 +20,6 @@ export interface Package { export class SearchService { static async search(query: string): Promise { - // Implement Arch Linux package search return []; } } @@ -49,10 +48,10 @@ export class PacmanSearch { description: item.desc, reply_markup: new InlineKeyboard().url(`Web Sahifasi`, normalize(item)), input_message_content: { - message_text: `Nomi: ${item.name}` + + message_text: + `Nomi: ${item.name}` + `\n` + - (item.version && - "Versiyasi: " + item.version + `\n`) + + (item.version && "Versiyasi: " + item.version + `\n`) + (item.desc && "Ma'lumot: " + item.desc + `\n`) + (item.repo ? "Repozitoriya: " + item.repo + `\n` : "") + (item.updated && @@ -69,47 +68,53 @@ export class PacmanSearch { } public getNotFound(query: string): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "404", - title: "Xatolik yuz berdi!", - description: `Ushbu ${query} ga oid natija topilmadi!`, - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "foobar", - ), - input_message_content: { - message_text: `"${query}" ga oid natija mavjud emas!` + - `\n` + - `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring.`, - parse_mode: "HTML", + return [ + { + type: "article" as const, + id: "404", + title: "Xatolik yuz berdi!", + description: `Ushbu ${query} ga oid natija topilmadi!`, + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "foobar", + ), + input_message_content: { + message_text: + `"${query}" ga oid natija mavjud emas!` + + `\n` + + `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan paketingiz yozib qidirib ko'ring.`, + parse_mode: "HTML", + }, }, - }]; + ]; } public getEmptyQuery(): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "102", - title: "Qidirishni boshlang!", - description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "foobar", - ), - input_message_content: { - message_text: `Salom foydalanuvchi!` + - `\n` + - `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + - `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + - `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + - `\n` + - `@xeonittebot \/tldr <sahifa nomi>` + - `\n` + - `yozasiz`, - parse_mode: "HTML", + return [ + { + type: "article" as const, + id: "102", + title: "Qidirishni boshlang!", + description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "foobar", + ), + input_message_content: { + message_text: + `Salom foydalanuvchi!` + + `\n` + + `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + + `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + + `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + + `\n` + + `@xeonittebot \/tldr <sahifa nomi>` + + `\n` + + `yozasiz`, + parse_mode: "HTML", + }, }, - }]; + ]; } } @@ -126,11 +131,13 @@ export class TealdeerSearch { public async query(type: string, page: string): Promise { const matches: string[] = []; - const response = await fetch(`https://api.github.com/repos/tldr-pages/tldr/contents/pages/${type}`); + const response = await fetch( + `https://api.github.com/repos/tldr-pages/tldr/contents/pages/${type}`, + ); if (response.status != 200) return []; - const jsonData = await response.json() as any[]; + const jsonData = (await response.json()) as any[]; jsonData.forEach((file) => { const fileName = file.name.slice(0, -3); @@ -147,7 +154,9 @@ export class TealdeerSearch { } public async getPage(type: string, page: string): Promise { - const response = await fetch(`https://raw.githubusercontent.com/tldr-pages/tldr/main/pages/${type}/${page}.md`); + const response = await fetch( + `https://raw.githubusercontent.com/tldr-pages/tldr/main/pages/${type}/${page}.md`, + ); const responseText = await response.text(); const lines = responseText.split("\n").map((line) => { if (line.startsWith(">")) { @@ -201,48 +210,53 @@ export class TealdeerSearch { } public getNotFound(query: string): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "404tldr", - title: "Xatolik yuz berdi!", - description: `Ushbu ${query} ga oid sahifa topilmadi!`, - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "ls", - ), - input_message_content: { - message_text: `"${query}" ga oid natija mavjud emas!` + - `\n` + - `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan tldr sahifa` + - `nomini yozib qidirib ko'ring.`, - parse_mode: "HTML", + return [ + { + type: "article" as const, + id: "404tldr", + title: "Xatolik yuz berdi!", + description: `Ushbu ${query} ga oid sahifa topilmadi!`, + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "ls", + ), + input_message_content: { + message_text: + `"${query}" ga oid natija mavjud emas!` + + `\n` + + `Iltimos, boshqattan ushbu qidirmoqchi bo'lgan tldr sahifa` + + `nomini yozib qidirib ko'ring.`, + parse_mode: "HTML", + }, }, - }]; + ]; } public getEmptyQuery(): InlineQueryResult[] { - return [{ - type: "article" as const, - id: "102", - title: "Qidirishni boshlang!", - description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", - reply_markup: new InlineKeyboard().switchInlineCurrent( - "Qayta urinib ko'ramizmi?", - "ls", - ), - input_message_content: { - message_text: `Salom foydalanuvchi!` + - `\n` + - `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + - `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + - `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + - `\n` + - `@xeonittebot \/tldr <sahifa nomi>` + - `\n` + - `yozasiz`, - parse_mode: "HTML", + return [ + { + type: "article" as const, + id: "102", + title: "Qidirishni boshlang!", + description: "Qidirmoqchi bo'lgan tldr sahifa nomini yozing!", + reply_markup: new InlineKeyboard().switchInlineCurrent( + "Qayta urinib ko'ramizmi?", + "ls", + ), + input_message_content: { + message_text: + `Salom foydalanuvchi!` + + `\n` + + `Siz inline rejim ishga tushurdingiz. Ushbu qulaylik yordamida siz ` + + `tldr sahifasiga kirmasdan turib telegramdan tldr sahifalarini ` + + `qidirish imkoniga ega bo'lasiz! Qidirishni boshlash uchun ` + + `\n` + + `@xeonittebot \/tldr <sahifa nomi>` + + `\n` + + `yozasiz`, + parse_mode: "HTML", + }, }, - }]; + ]; } } -