@serverkgg/bridge 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/package.json +1 -1
  2. package/rules/package.md +5 -0
  3. package/src/bot/botCauses.test.ts +284 -0
  4. package/src/bot/botCauses.ts +58 -0
  5. package/src/bot/botDeploy.test.ts +260 -1
  6. package/src/bot/botDeploy.ts +125 -6
  7. package/src/bot/botState.ts +6 -0
  8. package/src/bot/detect/botInspectWarning.ts +3 -1
  9. package/src/bot/detect/botPackageManager.ts +3 -0
  10. package/src/bot/detect/corpus/alexmubarakshin-ts-telegraf-boilerplate.json +37 -0
  11. package/src/bot/detect/corpus/alsarmad-discord-quran-bot.json +40 -0
  12. package/src/bot/detect/corpus/anasty17-mirror-leech-telegram-bot.json +50 -0
  13. package/src/bot/detect/corpus/anidiotsguide-guidebot.json +36 -0
  14. package/src/bot/detect/corpus/anonymousx1025-anonxmusic.json +45 -0
  15. package/src/bot/detect/corpus/bot-base-telegram-bot-template.json +35 -0
  16. package/src/bot/detect/corpus/bracketed-templates-discordjs.json +40 -0
  17. package/src/bot/detect/corpus/cog-creators-red-discordbot.json +49 -0
  18. package/src/bot/detect/corpus/cranberriez-discord.ts-bot-template.json +35 -0
  19. package/src/bot/detect/corpus/crazycat256-nextcord-bot-template.json +38 -0
  20. package/src/bot/detect/corpus/discord-tickets-bot.json +45 -0
  21. package/src/bot/detect/corpus/edjopato-telegram-typescript-bot-template.json +37 -0
  22. package/src/bot/detect/corpus/haniali3161-bot-adhkar-telegram.json +33 -0
  23. package/src/bot/detect/corpus/hellosverre-discord-ts-template.json +34 -0
  24. package/src/bot/detect/corpus/kevinnovak-discord-bot-typescript-template.json +43 -0
  25. package/src/bot/detect/corpus/kkrypt0nn-python-discord-bot-template.json +41 -0
  26. package/src/bot/detect/corpus/kolezka-telegram-grammy-template.json +37 -0
  27. package/src/bot/detect/corpus/latand-tgbot_template_v3.json +37 -0
  28. package/src/bot/detect/corpus/mahmoudbm77-zekr-telegram-bot.json +36 -0
  29. package/src/bot/detect/corpus/mericcan41-discordjs-v14-template-ts.json +33 -0
  30. package/src/bot/detect/corpus/modmail-dev-modmail.json +52 -0
  31. package/src/bot/detect/corpus/nezdemkovski-telegram-bot-boilerplate.json +39 -0
  32. package/src/bot/detect/corpus/notchum-discord-bot-template.json +39 -0
  33. package/src/bot/detect/corpus/python-discord-bot.json +44 -0
  34. package/src/bot/detect/corpus/python-telegram-bot-rules-bot.json +39 -0
  35. package/src/bot/detect/corpus/rajdave69-pycord-bot-template.json +31 -0
  36. package/src/bot/detect/corpus/rapptz-robodanny.json +36 -0
  37. package/src/bot/detect/corpus/ry2x-typescript-discord.js-v.14-template.json +35 -0
  38. package/src/bot/detect/corpus/saiteja-madha-discord-js-bot.json +45 -0
  39. package/src/bot/detect/corpus/seegreatness-discord.js-for-heroku.json +37 -0
  40. package/src/bot/detect/corpus/serverk-discord-node.json +36 -0
  41. package/src/bot/detect/corpus/serverk-discord-python.json +35 -0
  42. package/src/bot/detect/corpus/serverk-telegram-node.json +36 -0
  43. package/src/bot/detect/corpus/serverk-telegram-python.json +35 -0
  44. package/src/bot/detect/corpus/shuruhatik-quran-radio-bot-discord.json +33 -0
  45. package/src/bot/detect/corpus/skyra-project-skyra.json +46 -0
  46. package/src/bot/detect/corpus/tgbot-collection-ytdlbot.json +41 -0
  47. package/src/bot/detect/corpus/zeriodev-music-bot.json +38 -0
  48. package/src/bot/detect/detect.corpus.test.ts +77 -0
  49. package/src/bot/detect/detect.test.ts +414 -17
  50. package/src/bot/detect/detect.ts +347 -36
  51. package/src/bot/detect/detectResult.ts +4 -0
  52. package/src/bot/detect/detectTable.test.ts +22 -6
  53. package/src/bot/detect/detectTable.ts +187 -19
  54. package/src/bot/detect/detectedVersion.ts +5 -0
  55. package/src/bot/detect/envExample.test.ts +55 -1
  56. package/src/bot/detect/envExample.ts +14 -0
  57. package/src/bot/detect/index.ts +1 -0
  58. package/src/bot/detect/keys.test.ts +32 -1
  59. package/src/bot/detect/keys.ts +15 -0
  60. package/src/bot/detect/serverkJson.test.ts +2 -0
  61. package/src/bot/detect/serverkJson.ts +4 -1
  62. package/src/bot/index.ts +1 -0
  63. package/src/cli/validate.test.ts +127 -1
  64. package/src/cli/validate.ts +42 -0
  65. package/src/manifest/manifest.ts +2 -1
  66. package/src/modules/bridge.ts +2 -0
  67. package/src/modules/bridgeModule.ts +5 -0
  68. package/src/protocol/bridgeCrash.ts +49 -0
  69. package/src/protocol/bridgeEvents.ts +9 -0
  70. package/src/protocol/bridgePreview.ts +1 -0
  71. package/src/rcon/rconAccess.ts +1 -1
  72. package/src/runtime/bridgeDriver.test.ts +45 -0
  73. package/src/runtime/bridgeDriver.ts +25 -0
  74. package/src/runtime/bridgeEvents.ts +2 -0
  75. package/src/runtime/bridgeRegistry.test.ts +32 -0
  76. package/src/runtime/bridgeSupervisor.test.ts +163 -3
  77. package/src/runtime/bridgeSupervisor.ts +42 -1
  78. package/src/runtime/serve.ts +26 -5
@@ -1,13 +1,15 @@
1
1
  import type { BridgeContext } from "../context";
2
2
  import type { BridgeValues } from "../core";
3
3
  import type { BridgeEventPattern } from "../modules";
4
- import { BridgeEventName } from "../protocol";
4
+ import { BridgeCrashPhase, type BridgeCrashReport, BridgeEventName } from "../protocol";
5
5
  import {
6
6
  BOT_STATE_DIR,
7
7
  BotDeploymentOutcome,
8
8
  BotDeploymentSource,
9
- type BotDeploymentStage,
9
+ BotDeploymentStage,
10
+ type BotDeploymentState,
10
11
  readDeploymentState,
12
+ writeDeploymentState,
11
13
  } from "./botState";
12
14
 
13
15
  export const DEPLOY_MARKER = `${BOT_STATE_DIR}/deploy-requested`;
@@ -23,6 +25,8 @@ export const DEPLOYMENT_DETAIL_LIMIT = 200;
23
25
 
24
26
  export const DEPLOYMENT_COMMIT_LENGTH = 12;
25
27
 
28
+ export const BOT_READY_GRACE_SECONDS = 20;
29
+
26
30
  export interface DeployRequest {
27
31
  deployment: string | null;
28
32
  ref: string | null;
@@ -77,6 +81,116 @@ export const deploymentEvent = (deployment: string, commit: string | null): Brid
77
81
  };
78
82
  };
79
83
 
84
+ export const deploymentFailedEvent = (deployment: string, stage: BotDeploymentStage, detail: string): BridgeValues => {
85
+ return {
86
+ kind: DEPLOYMENT_EVENT_KIND,
87
+ deployment,
88
+ outcome: BotDeploymentOutcome.Failed,
89
+ stage,
90
+ detail,
91
+ };
92
+ };
93
+
94
+ type ReadinessContext = Pick<BridgeContext, "files" | "log" | "emit">;
95
+
96
+ const commitOf = (state: BotDeploymentState) => {
97
+ return state.source === BotDeploymentSource.Git ? state.commit : null;
98
+ };
99
+
100
+ export const pendingDeploymentOf = (
101
+ state: BotDeploymentState | null,
102
+ launchedAt: number,
103
+ ): BotDeploymentState | null => {
104
+ if (
105
+ state === null
106
+ || state.deployment === null
107
+ || state.outcome !== BotDeploymentOutcome.Ready
108
+ || state.settled === true
109
+ ) {
110
+ return null;
111
+ }
112
+
113
+ if (state.settled === false) {
114
+ return state;
115
+ }
116
+
117
+ const finishedAt = Date.parse(state.finishedAt);
118
+
119
+ return Number.isFinite(finishedAt) && finishedAt >= launchedAt ? state : null;
120
+ };
121
+
122
+ export const createBotReadiness = () => {
123
+ let launchedAt = Number.POSITIVE_INFINITY;
124
+ let pending: Promise<BotDeploymentState | null> = Promise.resolve(null);
125
+
126
+ const take = async () => {
127
+ const state = await pending;
128
+
129
+ pending = Promise.resolve(null);
130
+
131
+ return state;
132
+ };
133
+
134
+ return {
135
+ launching(at: number = Date.now()) {
136
+ launchedAt = at;
137
+ pending = Promise.resolve(null);
138
+ },
139
+
140
+ async ready(context: ReadinessContext) {
141
+ const read = async () => {
142
+ return pendingDeploymentOf(await readDeploymentState(context.files), launchedAt);
143
+ };
144
+
145
+ pending = read();
146
+
147
+ await pending;
148
+ },
149
+
150
+ async stable(context: ReadinessContext) {
151
+ const state = await take();
152
+
153
+ if (state === null || state.deployment === null) {
154
+ return;
155
+ }
156
+
157
+ context.emit(BridgeEventName.ServerUpdated, deploymentEvent(state.deployment, commitOf(state)));
158
+
159
+ await writeDeploymentState(context.files, {
160
+ ...state,
161
+ settled: true,
162
+ });
163
+ },
164
+
165
+ async exit(context: ReadinessContext, report: BridgeCrashReport) {
166
+ const state = await take();
167
+
168
+ if (state === null || state.deployment === null || report.phase !== BridgeCrashPhase.Booting) {
169
+ return;
170
+ }
171
+
172
+ context.log.warn("the bot exited before it was ready, the deployment failed", {
173
+ deployment: state.deployment,
174
+ cause: report.cause,
175
+ });
176
+
177
+ context.emit(
178
+ BridgeEventName.ServerUpdated,
179
+ deploymentFailedEvent(state.deployment, BotDeploymentStage.Start, report.cause),
180
+ );
181
+
182
+ await writeDeploymentState(context.files, {
183
+ ...state,
184
+ outcome: BotDeploymentOutcome.Failed,
185
+ stage: BotDeploymentStage.Start,
186
+ detail: report.cause,
187
+ finishedAt: new Date().toISOString(),
188
+ settled: true,
189
+ });
190
+ },
191
+ };
192
+ };
193
+
80
194
  export const deployPending = async (context: Pick<BridgeContext, "files" | "server">) => {
81
195
  return context.server.running && (await context.files.exists(DEPLOY_MARKER));
82
196
  };
@@ -94,14 +208,19 @@ const alreadyLive = async (context: DeployContext, request: DeployRequest) => {
94
208
  return false;
95
209
  }
96
210
 
211
+ if (state.settled === false) {
212
+ context.log("the deployment is running but has not proven itself yet, its outcome follows", {
213
+ deployment: request.deployment,
214
+ });
215
+
216
+ return true;
217
+ }
218
+
97
219
  context.log("the deployment is already live, nothing to do", {
98
220
  deployment: request.deployment,
99
221
  });
100
222
 
101
- context.emit(
102
- BridgeEventName.ServerUpdated,
103
- deploymentEvent(request.deployment, state.source === BotDeploymentSource.Git ? state.commit : null),
104
- );
223
+ context.emit(BridgeEventName.ServerUpdated, deploymentEvent(request.deployment, commitOf(state)));
105
224
 
106
225
  return true;
107
226
  };
@@ -20,6 +20,7 @@ export enum BotDeploymentStage {
20
20
  Sync = "sync",
21
21
  Snapshot = "snapshot",
22
22
  Install = "install",
23
+ Build = "build",
23
24
  Start = "start",
24
25
  }
25
26
 
@@ -33,6 +34,7 @@ export const botDeploymentStateSchema = z.object({
33
34
  stage: z.enum(BotDeploymentStage).nullable(),
34
35
  detail: z.string().nullable(),
35
36
  finishedAt: z.string(),
37
+ settled: z.boolean().optional(),
36
38
  });
37
39
 
38
40
  export type BotDeploymentState = z.infer<typeof botDeploymentStateSchema>;
@@ -52,3 +54,7 @@ export const readDeploymentState = async (
52
54
  return null;
53
55
  }
54
56
  };
57
+
58
+ export const writeDeploymentState = async (files: Pick<BridgeFiles, "write">, state: BotDeploymentState) => {
59
+ await files.write(DEPLOYMENT_STATE_FILE, `${JSON.stringify(state, null, "\t")}\n`);
60
+ };
@@ -1,11 +1,13 @@
1
1
  export enum BotInspectWarning {
2
2
  NoLockfile = "no-lockfile",
3
+ NodeVersionUnmet = "node-version-unmet",
4
+ LockfileNotHonoured = "lockfile-not-honoured",
3
5
  NoStart = "no-start",
4
6
  NoManifest = "no-manifest",
5
- TypescriptEntry = "typescript-entry",
6
7
  EnvCommitted = "env-committed",
7
8
  NodeModulesCommitted = "node-modules-committed",
8
9
  VenvCommitted = "venv-committed",
10
+ DatabaseCommitted = "database-committed",
9
11
  UnpinnedRequirements = "unpinned-requirements",
10
12
  TwoRuntimes = "two-runtimes",
11
13
  TwoPlatforms = "two-platforms",
@@ -2,5 +2,8 @@ export enum BotPackageManager {
2
2
  Npm = "npm",
3
3
  Pnpm = "pnpm",
4
4
  Yarn = "yarn",
5
+ Bun = "bun",
5
6
  Pip = "pip",
7
+ Uv = "uv",
8
+ Pipenv = "pipenv",
6
9
  }
@@ -0,0 +1,37 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/AlexMubarakshin/ts-telegraf-boilerplate",
4
+ "branch": "main",
5
+ "commit": "97cb2ceebb3c3c87c779801b67ae731ed5ea958d",
6
+ "stars": 14
7
+ },
8
+ "files": [
9
+ ".env.example",
10
+ ".eslintrc.js",
11
+ ".gitignore",
12
+ ".prettierrc",
13
+ "Readme.md",
14
+ "babel.config.js",
15
+ "package.json",
16
+ "src/index.ts",
17
+ "tsconfig.json",
18
+ "yarn.lock"
19
+ ],
20
+ "contents": {
21
+ ".env.example": "BOT_TOKEN=\n\nSERVER_PORT=3000\n\nLOGS_OUTPUT=logs.log",
22
+ "package.json": "{\n \"name\": \"ts-telegraf-boilerplate\",\n \"version\": \"1.0.0\",\n \"description\": \"A personal TypeScript-based boilerplate for Telegram bot development using Telegraf\",\n \"main\": \"index.js\",\n \"repository\": \"https://github.com/AlexMubarakshin/ts-telegraf-boilerplate\",\n \"author\": \"Alex Mubarakshin\",\n \"license\": \"MIT\",\n \"scripts\": {\n \"build\": \"tsc\",\n \"eslint:lint\": \"eslint . --ext .ts\",\n \"eslint:fix\": \"eslint . --ext .ts --fix\",\n \"lint\": \"yarn prettier:check && yarn eslint:lint && yarn type-check\",\n \"prettier:check\": \"npm exec prettier -- --check './src/**/*.{js,jsx,ts,tsx,scss,css}'\",\n \"prettier:fix\": \"npm exec prettier -- --write './src/**/*.{js,jsx,ts,tsx}'\",\n \"start\": \"node dist/index.js\",\n \"start:inspect\": \"node --inspect dist/index.js\",\n \"type-check\": \"tsc --noEmit --skipLibCheck\",\n \"test\": \"jest\"\n },\n \"dependencies\": {\n \"dotenv\": \"16.3.1\",\n \"eslint-plugin-prettier\": \"5.0.0\",\n \"telegraf\": \"4.14.0\",\n \"winston\": \"3.10.0\"\n },\n \"devDependencies\": {\n \"@babel/core\": \"7.23.0\",\n \"@babel/preset-env\": \"7.22.20\",\n \"@babel/preset-typescript\": \"7.23.0\",\n \"@types/jest\": \"29.5.5\",\n \"@typescript-eslint/eslint-plugin\": \"6.7.3\",\n \"@typescript-eslint/parser\": \"6.7.3\",\n \"babel-jest\": \"29.7.0\",\n \"eslint\": \"8.50.0\",\n \"eslint-plugin-import-helpers\": \"1.3.1\",\n \"jest\": \"29.7.0\",\n \"prettier\": \"3.0.3\",\n \"typescript\": \"5.2.2\"\n }\n}\n"
23
+ },
24
+ "expected": {
25
+ "runtime": "node",
26
+ "packageManager": "yarn",
27
+ "framework": "telegraf",
28
+ "platform": "telegram",
29
+ "install": "corepack yarn install --frozen-lockfile",
30
+ "build": "corepack yarn run build",
31
+ "start": "node dist/index.js",
32
+ "nodeVersion": null,
33
+ "pythonVersion": null,
34
+ "tokenKey": "BOT_TOKEN",
35
+ "warnings": []
36
+ }
37
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/Alsarmad/discord-quran-bot",
4
+ "branch": "master",
5
+ "commit": "ce4706ed9a8805552eacb2d673de636aeef22e9b",
6
+ "stars": 7
7
+ },
8
+ "files": [
9
+ ".env.example",
10
+ ".gitignore",
11
+ "LICENSE",
12
+ "Procfile",
13
+ "README.md",
14
+ "app.json",
15
+ "package.json",
16
+ "src/index.ts",
17
+ "tsconfig.json"
18
+ ],
19
+ "contents": {
20
+ ".env.example": "DISCORD_TOKEN=your-discord-token-here\nSTATUS=",
21
+ "Procfile": "worker: node dist/index",
22
+ "package.json": "{\n \"name\": \"quran-bot\",\n \"version\": \"1.0.0\",\n \"description\": \"A Discord bot that can play Qur'an recitations in voice/stage channel.\",\n \"main\": \"dist/index.js\",\n \"scripts\": {\n \"build\": \"tsc\",\n \"start\": \"npm run build && node dist/index\"\n },\n \"author\": \"TheMaestroo\",\n \"dependencies\": {\n \"@discordjs/voice\": \"^0.14.0\",\n \"arabic2franko\": \"^1.0.3\",\n \"discord.js\": \"^13.1.0\",\n \"dotenv\": \"^16.0.3\",\n \"ffmpeg-static\": \"^5.1.0\",\n \"fuse.js\": \"^6.4.6\",\n \"libsodium-wrappers\": \"^0.7.9\",\n \"ms\": \"^3.0.0-canary.1\",\n \"node-fetch\": \"^3.3.0\"\n },\n \"devDependencies\": {\n \"@types/node-fetch\": \"^2.5.10\",\n \"typescript\": \"^4.4.3\"\n },\n \"engines\": {\n \"node\": \"16.x\"\n }\n}\n"
23
+ },
24
+ "expected": {
25
+ "runtime": "node",
26
+ "packageManager": "npm",
27
+ "framework": "discord-js",
28
+ "platform": "discord",
29
+ "install": "npm install",
30
+ "build": "npm run build",
31
+ "start": "node dist/index",
32
+ "nodeVersion": "16",
33
+ "pythonVersion": null,
34
+ "tokenKey": "DISCORD_TOKEN",
35
+ "warnings": [
36
+ "no-lockfile",
37
+ "node-version-unmet"
38
+ ]
39
+ }
40
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/anasty17/mirror-leech-telegram-bot",
4
+ "branch": "master",
5
+ "commit": "795effa69fe6b89af4183bc518195b7a2fffdf54",
6
+ "stars": 4320
7
+ },
8
+ "files": [
9
+ ".dockerignore",
10
+ ".gitignore",
11
+ "Dockerfile",
12
+ "LICENSE",
13
+ "README.md",
14
+ "_config.yml",
15
+ "add_to_team_drive.py",
16
+ "aria-nox-nzb.sh",
17
+ "bot/__main__.py",
18
+ "captain-definition",
19
+ "config_sample.py",
20
+ "docker-compose.yml",
21
+ "driveid.py",
22
+ "gen_sa_accounts.py",
23
+ "generate_drive_token.py",
24
+ "generate_string_session.py",
25
+ "pytest.ini",
26
+ "requirements-cli.txt",
27
+ "requirements-dev.txt",
28
+ "requirements.txt",
29
+ "start.sh",
30
+ "update.py"
31
+ ],
32
+ "contents": {
33
+ "requirements.txt": "asyncio\naiofiles\naioshutil\nanytree\napscheduler\naioaria2\naioqbt\ncloudscraper\ndnspython\nfastapi\nfeedparser\ngoogle-api-python-client\ngoogle-auth-httplib2\ngoogle-auth-oauthlib\ngunicorn\nhttpx\njinja2\nlxml\nnatsort\npar2cmdline-turbo\npillow\npsutil\npymongo\nkurigram\npython-magic\nrequests\ntelegraph\ntenacity\ntgcrypto\nurllib3\nuvicorn\nuvloop\nxattr\ngallery-dl\nyt-dlp[default,curl-cffi]\n"
34
+ },
35
+ "expected": {
36
+ "runtime": "python",
37
+ "packageManager": "pip",
38
+ "framework": null,
39
+ "platform": null,
40
+ "install": "uv pip install -r requirements.txt",
41
+ "build": null,
42
+ "start": "python -m bot",
43
+ "nodeVersion": null,
44
+ "pythonVersion": null,
45
+ "tokenKey": null,
46
+ "warnings": [
47
+ "unpinned-requirements"
48
+ ]
49
+ }
50
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/AnIdiotsGuide/guidebot",
4
+ "branch": "master",
5
+ "commit": "725fc1460ca276282c27a775b5f9915154983ecc",
6
+ "stars": 471
7
+ },
8
+ "files": [
9
+ ".env-example",
10
+ ".eslintrc.json",
11
+ ".gitignore",
12
+ "LICENSE",
13
+ "README.md",
14
+ "config.js.example",
15
+ "index.js",
16
+ "package-lock.json",
17
+ "package.json",
18
+ "yarn.lock"
19
+ ],
20
+ "contents": {
21
+ "package.json": "{\n \"name\": \"guidebot\",\n \"version\": \"2.1.0\",\n \"description\": \"A boilerplate example bot with command handler and reloadable commands. Updated and Maintained by the Idiot's Guide Community\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"start\": \"node index.js\"\n },\n \"engines\": {\n \"node\": \">=16\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/AnIdiotsGuide/guidebot.git\"\n },\n \"author\": \"Evelyne Lachance <eslachance@gmail.com> (http://evie.codes)\",\n \"contributors\": [\n \"York (http://anidiots.guide)\"\n ],\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/AnIdiotsGuide/guidebot/issues\"\n },\n \"homepage\": \"https://github.com/AnIdiotsGuide/guidebot#readme\",\n \"dependencies\": {\n \"@discordjs/builders\": \"^0.2.0\",\n \"@sapphire/time-utilities\": \"^1.3.8\",\n \"colorette\": \"^1.3.0\",\n \"discord.js\": \"^13.0.1\",\n \"dotenv\": \"^10.0.0\",\n \"enmap\": \"^5.8.5\"\n },\n \"devDependencies\": {\n \"eslint\": \"^7.30.0\",\n \"eslint-config-airbnb-base\": \"^14.2.1\",\n \"eslint-config-standard\": \"^16.0.3\",\n \"eslint-plugin-import\": \"^2.23.4\",\n \"eslint-plugin-node\": \"^11.1.0\",\n \"eslint-plugin-promise\": \"^5.1.0\"\n }\n}\n"
22
+ },
23
+ "expected": {
24
+ "runtime": "node",
25
+ "packageManager": "yarn",
26
+ "framework": "discord-js",
27
+ "platform": "discord",
28
+ "install": "corepack yarn install --frozen-lockfile",
29
+ "build": null,
30
+ "start": "node index.js",
31
+ "nodeVersion": "16",
32
+ "pythonVersion": null,
33
+ "tokenKey": null,
34
+ "warnings": []
35
+ }
36
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/AnonymousX1025/AnonXMusic",
4
+ "branch": "master",
5
+ "commit": "16e898dcdb271523464315ac1a33ede65adbaf86",
6
+ "stars": 301
7
+ },
8
+ "files": [
9
+ ".dockerignore",
10
+ ".gitignore",
11
+ ".python-version",
12
+ "Dockerfile",
13
+ "LICENSE",
14
+ "Procfile",
15
+ "anony/__main__.py",
16
+ "app.json",
17
+ "config.py",
18
+ "heroku.yml",
19
+ "pyproject.toml",
20
+ "requirements.txt",
21
+ "sample.env",
22
+ "setup",
23
+ "start",
24
+ "uv.lock"
25
+ ],
26
+ "contents": {
27
+ ".python-version": "3.13\n",
28
+ "Procfile": "worker: bash start\n",
29
+ "pyproject.toml": "[project]\nname = \"anonxmusic\"\nversion = \"3.0.3\"\ndescription = \"Telegram Group Calls Streaming bot with some useful features.\"\nreadme = \".github/README.md\"\nrequires-python = \">=3.10\"\n\ndependencies = [\n \"aiohttp~=3.14.3\",\n \"kurigram>=2.2.25\",\n \"ntgcalls==3.0.0rc1\",\n \"pillow~=12.3.0\",\n \"psutil~=7.2.2\",\n \"py-tgcalls==3.0.0rc1\",\n \"py-yt-search~=0.8.0\",\n \"pymongo>=4.17.0\",\n \"pytgcrypto>=1.2.12\",\n \"python-dotenv~=1.2.3\",\n \"yt-dlp[default]>=2026.8.19\",\n]\n",
30
+ "requirements.txt": "aiohttp~=3.14.3\nkurigram>=2.2.25\nntgcalls==3.0.0rc1\npillow~=12.3.0\npsutil~=7.2.2\npy-tgcalls==3.0.0rc1\npy-yt-search~=0.8.0\npymongo>=4.17.0\npytgcrypto>=1.2.12\npython-dotenv~=1.2.3\nyt-dlp[default]>=2026.8.19\n"
31
+ },
32
+ "expected": {
33
+ "runtime": "python",
34
+ "packageManager": "pip",
35
+ "framework": null,
36
+ "platform": null,
37
+ "install": "uv pip install -r requirements.txt",
38
+ "build": null,
39
+ "start": "bash start",
40
+ "nodeVersion": null,
41
+ "pythonVersion": "3.13",
42
+ "tokenKey": null,
43
+ "warnings": []
44
+ }
45
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/bot-base/telegram-bot-template",
4
+ "branch": "main",
5
+ "commit": "0de2bcd599d1986861ee41342cf754c850cb1425",
6
+ "stars": 445
7
+ },
8
+ "files": [
9
+ ".env.example",
10
+ ".gitignore",
11
+ "README.md",
12
+ "eslint.config.js",
13
+ "package-lock.json",
14
+ "package.json",
15
+ "src/main.ts",
16
+ "tsconfig.json"
17
+ ],
18
+ "contents": {
19
+ ".env.example": "BOT_TOKEN=\nBOT_MODE=polling\nLOG_LEVEL=debug\nDEBUG=true\nBOT_WEBHOOK=https://www.example.com/webhook\nBOT_WEBHOOK_SECRET=RANDOM_SECRET_VALUE\nSERVER_HOST=localhost\nSERVER_PORT=3000\nBOT_ADMINS=[1]",
20
+ "package.json": "{\n \"name\": \"telegram-bot-template\",\n \"type\": \"module\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"description\": \"Telegram bot starter template\",\n \"imports\": {\n \"#root/*\": \"./build/src/*\"\n },\n \"author\": \"deptyped <deptyped@gmail.com>\",\n \"license\": \"MIT\",\n \"engines\": {\n \"node\": \">=20.0.0\",\n \"npm\": \">=8.0.0\"\n },\n \"scripts\": {\n \"lint\": \"eslint .\",\n \"format\": \"eslint . --fix\",\n \"typecheck\": \"tsc\",\n \"build\": \"tsc --noEmit false\",\n \"dev\": \"tsc-watch --onSuccess \\\"tsx ./src/main.ts\\\"\",\n \"start\": \"tsc && tsx ./src/main.ts\",\n \"start:force\": \"tsx ./src/main.ts\",\n \"prepare\": \"husky || true\"\n },\n \"dependencies\": {\n \"@grammyjs/auto-chat-action\": \"0.1.1\",\n \"@grammyjs/commands\": \"1.0.8\",\n \"@grammyjs/hydrate\": \"1.4.1\",\n \"@grammyjs/i18n\": \"1.1.2\",\n \"@grammyjs/parse-mode\": \"1.11.1\",\n \"@grammyjs/runner\": \"2.0.3\",\n \"@grammyjs/types\": \"3.20.0\",\n \"@hono/node-server\": \"1.14.2\",\n \"callback-data\": \"1.1.1\",\n \"grammy\": \"1.36.1\",\n \"hono\": \"4.10.3\",\n \"iso-639-1\": \"3.1.5\",\n \"pino\": \"9.9.0\",\n \"pino-pretty\": \"13.0.0\",\n \"tsx\": \"4.20.4\",\n \"valibot\": \"0.42.1\"\n },\n \"devDependencies\": {\n \"@antfu/eslint-config\": \"4.12.0\",\n \"@types/node\": \"^22.15.21\",\n \"eslint\": \"^9.27.0\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^15.5.1\",\n \"tsc-watch\": \"^6.3.1\",\n \"typescript\": \"^5.9.2\"\n },\n \"lint-staged\": {\n \"*.ts\": \"eslint\"\n }\n}\n"
21
+ },
22
+ "expected": {
23
+ "runtime": "node",
24
+ "packageManager": "npm",
25
+ "framework": "grammy",
26
+ "platform": "telegram",
27
+ "install": "npm ci",
28
+ "build": "npm run build",
29
+ "start": "tsc && tsx ./src/main.ts",
30
+ "nodeVersion": "20",
31
+ "pythonVersion": null,
32
+ "tokenKey": "BOT_TOKEN",
33
+ "warnings": []
34
+ }
35
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/Bracketed/templates-discordjs",
4
+ "branch": "master",
5
+ "commit": "691dd94ed81e79268f15694ce249774e189a8827",
6
+ "stars": 1
7
+ },
8
+ "files": [
9
+ ".env",
10
+ ".gitignore",
11
+ ".gitmodules",
12
+ ".yarnrc.yml",
13
+ "README.md",
14
+ "biome.json",
15
+ "entrypoint.sh",
16
+ "package.json",
17
+ "renovate.json",
18
+ "tsconfig.json",
19
+ "tsup.config.ts",
20
+ "yarn.lock"
21
+ ],
22
+ "contents": {
23
+ "package.json": "{\n\t\"name\": \"@ninjaninja140/discord-ts-template\",\n\t\"packageManager\": \"yarn@4.12.0\",\n\t\"private\": true,\n\t\"main\": \"dist/Entrypoint.mjs\",\n\t\"type\": \"module\",\n\t\"author\": {\n\t\t\"name\": \"ninjaninja140\",\n\t\t\"url\": \"https://github.com/ninjaninja140\"\n\t},\n\t\"homepage\": \"https://bracketed.co.uk\",\n\t\"repository\": {\n\t\t\"url\": \"https://github.com/ninjaninja140/templates-discordjs-typescript\"\n\t},\n\t\"dependencies\": {\n\t\t\"@sapphire/framework\": \"^5.5.0\",\n\t\t\"@sapphire/plugin-logger\": \"^4.1.0\",\n\t\t\"@sapphire/plugin-utilities-store\": \"^2.0.3\",\n\t\t\"discord.js\": \"14.25.1\",\n\t\t\"dotenv\": \"^17.2.3\"\n\t},\n\t\"devDependencies\": {\n\t\t\"@biomejs/biome\": \"^2.3.11\",\n\t\t\"@bracketed/tsup-configuration\": \"^1.0.5\",\n\t\t\"@bracketed/typescript-config\": \"^4.7.1\",\n\t\t\"@sapphire/cli\": \"^1.9.3\",\n\t\t\"@swc/core\": \"^1.15.8\",\n\t\t\"@types/node\": \"^25.0.3\",\n\t\t\"esbuild\": \"^0.27.2\",\n\t\t\"esbuild-fix-imports-plugin\": \"^1.0.23\",\n\t\t\"esbuild-plugin-copy\": \"^2.1.1\",\n\t\t\"esbuild-plugin-file-path-extensions\": \"^2.1.4\",\n\t\t\"esbuild-plugin-version-injector\": \"^1.2.1\",\n\t\t\"tsc-alias\": \"^1.8.16\",\n\t\t\"tsconfig-paths\": \"^4.2.0\",\n\t\t\"tsup\": \"^8.5.1\",\n\t\t\"typescript\": \"^5.9.3\"\n\t},\n\t\"scripts\": {\n\t\t\"start\": \"node dist/Entrypoint.mjs\",\n\t\t\"build\": \"tsup\",\n\t\t\"update\": \"yarn upgrade-interactive\"\n\t}\n}\n"
24
+ },
25
+ "expected": {
26
+ "runtime": "node",
27
+ "packageManager": "yarn",
28
+ "framework": "discord-js",
29
+ "platform": "discord",
30
+ "install": "corepack yarn install --immutable",
31
+ "build": "corepack yarn run build",
32
+ "start": "node dist/Entrypoint.mjs",
33
+ "nodeVersion": null,
34
+ "pythonVersion": null,
35
+ "tokenKey": null,
36
+ "warnings": [
37
+ "env-committed"
38
+ ]
39
+ }
40
+ }
@@ -0,0 +1,49 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/Cog-Creators/Red-DiscordBot",
4
+ "branch": "V3/develop",
5
+ "commit": "111a8b885238898bd41ac2e1b93ef91b654d9cf0",
6
+ "stars": 5727
7
+ },
8
+ "files": [
9
+ ".bandit.yml",
10
+ ".cherry_picker.toml",
11
+ ".codeclimate.yml",
12
+ ".git-blame-ignore-revs",
13
+ ".git_archive_info.txt",
14
+ ".gitattributes",
15
+ ".gitignore",
16
+ ".pylintrc",
17
+ ".readthedocs.yml",
18
+ "CHANGES.rst",
19
+ "CONTRIBUTING.md",
20
+ "LICENSE",
21
+ "MANIFEST.in",
22
+ "Makefile",
23
+ "README.md",
24
+ "SECURITY.md",
25
+ "crowdin.yml",
26
+ "make.bat",
27
+ "make.ps1",
28
+ "pyproject.toml",
29
+ "redbot/__main__.py",
30
+ "setup.py",
31
+ "tox.ini"
32
+ ],
33
+ "contents": {
34
+ "pyproject.toml": "[build-system]\nrequires = [\"setuptools>=64\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"Red-DiscordBot\"\ndescription = \"A highly customisable Discord bot\"\nreadme = \"README.md\"\nauthors = [{ name = \"Cog Creators\" }]\nclassifiers = [\n \"Development Status :: 5 - Production/Stable\",\n \"Framework :: AsyncIO\",\n \"Intended Audience :: Developers\",\n \"Intended Audience :: End Users/Desktop\",\n \"License :: OSI Approved :: GNU General Public License v3 (GPLv3)\",\n \"Natural Language :: English\",\n \"Operating System :: MacOS :: MacOS X\",\n \"Operating System :: Microsoft :: Windows\",\n \"Operating System :: POSIX :: Linux\",\n \"Programming Language :: Python :: 3 :: Only\",\n \"Programming Language :: Python :: 3.8\",\n \"Programming Language :: Python :: 3.9\",\n \"Programming Language :: Python :: 3.10\",\n \"Programming Language :: Python :: 3.11\",\n \"Topic :: Communications :: Chat\",\n]\ndynamic = [\"version\", \"requires-python\", \"dependencies\", \"optional-dependencies\"]\n\n[project.urls]\n\"Homepage\" = \"https://github.com/Cog-Creators/Red-DiscordBot\"\n\"Discord Server\" = \"https://discord.gg/red\"\n\"Documentation\" = \"https://docs.discord.red\"\n\"Donate on Patreon\" = \"https://www.patreon.com/Red_Devs\"\n\"Issue Tracker\" = \"https://github.com/Cog-Creators/Red-DiscordBot/issues\"\n\"Source Code\" = \"https://github.com/Cog-Creators/Red-DiscordBot\"\n\"Changelog\" = \"https://docs.discord.red/en/stable/changelog.html\"\n\n[project.scripts]\nredbot = \"redbot.__main__:main\"\nredbot-setup = \"redbot.setup:run_cli\"\n\n[project.entry-points.pytest11]\nred-discordbot = \"redbot.pytest\"\n\n[tool.black]\nline-length = 99\nrequired-version = '23'\ntarget-version = ['py38']\ninclude = '\\.py$'\nforce-exclude = '''\n/(\n redbot\\/vendored\n)/\n'''\n\n[tool.pytest.ini_options]\nasyncio_mode = 'auto'\n"
35
+ },
36
+ "expected": {
37
+ "runtime": "python",
38
+ "packageManager": "pip",
39
+ "framework": null,
40
+ "platform": null,
41
+ "install": "uv pip install .",
42
+ "build": null,
43
+ "start": "python -m redbot",
44
+ "nodeVersion": null,
45
+ "pythonVersion": null,
46
+ "tokenKey": null,
47
+ "warnings": []
48
+ }
49
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/cranberriez/discord.ts-bot-template",
4
+ "branch": "main",
5
+ "commit": "bb6934973ff4c505d9fde2466c2d4471b0e5069b",
6
+ "stars": 0
7
+ },
8
+ "files": [
9
+ ".gitignore",
10
+ "README.md",
11
+ "bun.lock",
12
+ "config.example.jsonc",
13
+ "eslint.config.js",
14
+ "package.json",
15
+ "pnpm-lock.yaml",
16
+ "src/index.ts",
17
+ "tsconfig.json"
18
+ ],
19
+ "contents": {
20
+ "package.json": "{\n \"name\": \"calendar-bot\",\n \"version\": \"1.0.0\",\n \"description\": \"Discord event management bot using Bun, TypeScript, and discord.js\",\n \"license\": \"ISC\",\n \"author\": \"Jacob\",\n \"type\": \"module\",\n \"main\": \"src/index.ts\",\n \"scripts\": {\n \"dev\": \"bun --hot run src/index.ts\",\n \"start\": \"bun run src/index.ts\",\n \"deploy\": \"bun run scripts/deploy-commands.ts\",\n \"lint\": \"eslint .\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"dependencies\": {\n \"discord.js\": \"^14.26.4\"\n },\n \"devDependencies\": {\n \"@discordjs/rest\": \"^2.5.0\",\n \"@eslint/js\": \"^9.0.0\",\n \"@types/bun\": \"^1.1.0\",\n \"@typescript-eslint/eslint-plugin\": \"^7.0.0\",\n \"@typescript-eslint/parser\": \"^7.0.0\",\n \"eslint\": \"^9.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"
21
+ },
22
+ "expected": {
23
+ "runtime": "node",
24
+ "packageManager": "pnpm",
25
+ "framework": "discord-js",
26
+ "platform": "discord",
27
+ "install": "corepack pnpm install --frozen-lockfile",
28
+ "build": null,
29
+ "start": "bun run src/index.ts",
30
+ "nodeVersion": null,
31
+ "pythonVersion": null,
32
+ "tokenKey": null,
33
+ "warnings": []
34
+ }
35
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "source": {
3
+ "url": "https://github.com/crazycat256/Nextcord-Bot-Template",
4
+ "branch": "main",
5
+ "commit": "661cd8cf6f2c7cc43dea2e18c866e3bd25e08a8e",
6
+ "stars": 5
7
+ },
8
+ "files": [
9
+ ".env.example",
10
+ ".gitattributes",
11
+ ".gitignore",
12
+ "LICENSE",
13
+ "README.md",
14
+ "bot.py",
15
+ "config.py",
16
+ "main.py",
17
+ "requirements.txt"
18
+ ],
19
+ "contents": {
20
+ ".env.example": "TOKEN = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # your token here",
21
+ "requirements.txt": "nextcord\npython-dotenv"
22
+ },
23
+ "expected": {
24
+ "runtime": "python",
25
+ "packageManager": "pip",
26
+ "framework": "nextcord",
27
+ "platform": "discord",
28
+ "install": "uv pip install -r requirements.txt",
29
+ "build": null,
30
+ "start": "python main.py",
31
+ "nodeVersion": null,
32
+ "pythonVersion": null,
33
+ "tokenKey": "TOKEN",
34
+ "warnings": [
35
+ "unpinned-requirements"
36
+ ]
37
+ }
38
+ }