From 820081150455007ecc520b3e84cb0691c0507466 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 20:40:51 +0200 Subject: [PATCH 1/7] feat: add zod environment variable testing --- package.json | 16 ++- src/index.ts | 5 +- src/lib/env.ts | 37 ++++++ tsconfig.json | 2 +- yarn.lock | 323 +++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 351 insertions(+), 32 deletions(-) create mode 100644 src/lib/env.ts diff --git a/package.json b/package.json index b7510b33..ce9c1740 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { - "name": "template", + "name": "gitcord", "version": "1.0.0", - "description": "A quick and easy to use template for TypeScript like projects ✏️", - "author": "ijsKoud ", + "description": "🪝Custom GitHub embeds for Discord", + "author": "Daan Klarenbeek ", "license": "MIT", "type": "module", "main": "dist/index.js", @@ -37,5 +37,13 @@ "engines": { "node": ">= v18.16.0" }, - "packageManager": "yarn@3.5.0" + "packageManager": "yarn@3.5.0", + "dependencies": { + "@snowcrystals/icicle": "^1.0.3", + "@snowcrystals/iglo": "^1.2.1", + "colorette": "2.0.19", + "discord.js": "^14.9.0", + "dotenv": "^16.0.3", + "zod": "^3.21.4" + } } diff --git a/src/index.ts b/src/index.ts index 019c0f4b..b8c7913f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,4 @@ -console.log("Hello World!"); +import { config } from "dotenv"; +config(); + +import "./lib/env.js"; diff --git a/src/lib/env.ts b/src/lib/env.ts new file mode 100644 index 00000000..5a60ea0c --- /dev/null +++ b/src/lib/env.ts @@ -0,0 +1,37 @@ +import { ZodError, z } from "zod"; +import { Logger } from "@snowcrystals/icicle"; +import { bold } from "colorette"; + +const logger = new Logger(); +// List of environment variables which are used by this application +const envSchema = z.object({ + DISCORD_BOT_TOKEN: z.string().nonempty() +}); + +try { + envSchema.parse(process.env); +} catch (err) { + if (!(err instanceof ZodError)) { + console.error(err); + process.exit(1); + } + + // Filter out missing ones + const missing = err.issues.filter((issue) => issue.message === "Required").map((issue) => bold(issue.path[0])); + logger.fatal(`The following environment variables are missing: ${missing}`); + + const failedTest = err.issues.filter((issue) => issue.message !== "Required"); + for (const failedItem of failedTest) { + // Environment variable + const path = failedItem.path[0]; + logger.fatal(`[${path}]: Failed the test with reason: ${failedItem.message}`); + } + + process.exit(1); +} + +declare global { + namespace NodeJS { + interface ProcessEnv extends z.infer {} + } +} diff --git a/tsconfig.json b/tsconfig.json index a5123db1..04c8e38e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@sapphire/ts-config/extra-strict-without-decorators", + "extends": "@sapphire/ts-config/extra-strict", "compilerOptions": { "outDir": "./dist", "noUnusedParameters": false, diff --git a/yarn.lock b/yarn.lock index d802b3ee..2f5a4cba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -245,6 +245,60 @@ __metadata: languageName: node linkType: hard +"@discordjs/builders@npm:^1.6.0": + version: 1.6.1 + resolution: "@discordjs/builders@npm:1.6.1" + dependencies: + "@discordjs/formatters": ^0.3.0 + "@discordjs/util": ^0.2.0 + "@sapphire/shapeshift": ^3.8.1 + discord-api-types: ^0.37.37 + fast-deep-equal: ^3.1.3 + ts-mixer: ^6.0.3 + tslib: ^2.5.0 + checksum: 057b5585d17e6273d99aa4cb356ca845d54785d95c0af05418f30eb933cf0b80043f7941effe7a593142c6817f47b893c5a973dfd95f3db24e0570666781e2d9 + languageName: node + linkType: hard + +"@discordjs/collection@npm:^1.5.0": + version: 1.5.0 + resolution: "@discordjs/collection@npm:1.5.0" + checksum: 072043743c5e5ef99033f1c227fd92f437a0665b8f0a5bfa26bacc6610963d03b54c45da0e0116ce30e4612efc52b2db0a0827f79091a135409237722db5400a + languageName: node + linkType: hard + +"@discordjs/formatters@npm:^0.3.0": + version: 0.3.0 + resolution: "@discordjs/formatters@npm:0.3.0" + dependencies: + discord-api-types: ^0.37.37 + checksum: cdf0d842f268a1b8c072522f58b0c77853e825964acb1e3b189f53d740d0d4ee4ed3b4be177ce4ab30a665bc1e6953348ab0d29b5fd52a0651e74eb63ad4be6d + languageName: node + linkType: hard + +"@discordjs/rest@npm:^1.7.0": + version: 1.7.0 + resolution: "@discordjs/rest@npm:1.7.0" + dependencies: + "@discordjs/collection": ^1.5.0 + "@discordjs/util": ^0.2.0 + "@sapphire/async-queue": ^1.5.0 + "@sapphire/snowflake": ^3.4.0 + discord-api-types: ^0.37.37 + file-type: ^18.2.1 + tslib: ^2.5.0 + undici: ^5.21.0 + checksum: 5d52ae02b77abafbcd70c650a9760625a7afab37875a7fc85404e1053e12745aeca819747ad4dbbaab78b1df0a33a050b980b1e91ba356c496bb0ea93d32e10f + languageName: node + linkType: hard + +"@discordjs/util@npm:^0.2.0": + version: 0.2.0 + resolution: "@discordjs/util@npm:0.2.0" + checksum: 1e6c02a2881c98ccee2ffd34f487b751e1f16bce007e0a3e9fa538170c1ddb3d68e2b1d88c84b3406191ba9dfec3a999a828603a142c359703fc53482269e7fa + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0": version: 4.2.0 resolution: "@eslint-community/eslint-utils@npm:4.2.0" @@ -390,6 +444,13 @@ __metadata: languageName: node linkType: hard +"@sapphire/async-queue@npm:^1.5.0": + version: 1.5.0 + resolution: "@sapphire/async-queue@npm:1.5.0" + checksum: 983dbd1fd1b1798496e5edb6a0db7e4d90015160e1028f20475eab0a92625513f1e8d938bc0305811a9cec461c94e01b1e4191615ff03ba49356f568f3255250 + languageName: node + linkType: hard + "@sapphire/eslint-config@npm:^4.4.1": version: 4.4.1 resolution: "@sapphire/eslint-config@npm:4.4.1" @@ -414,6 +475,30 @@ __metadata: languageName: node linkType: hard +"@sapphire/shapeshift@npm:^3.8.1": + version: 3.8.2 + resolution: "@sapphire/shapeshift@npm:3.8.2" + dependencies: + fast-deep-equal: ^3.1.3 + lodash: ^4.17.21 + checksum: 5b2b26ad13a4c8c4b03a9500541df6c070776cf0a49cb7c752df147f63afc76976bc0d4c6f5977cf2597062b810557d7069e99c8e039bf22bf54d5d88da58de5 + languageName: node + linkType: hard + +"@sapphire/snowflake@npm:^3.4.0": + version: 3.4.2 + resolution: "@sapphire/snowflake@npm:3.4.2" + checksum: 3bcd05608a63f012538aa0a45bc6abe5b19e15979a1012a9b3af1e0901f897e4df83c80d484c87bd1dece1124f5a14a2f86427190b1dca7f116ee34f13c96788 + languageName: node + linkType: hard + +"@sapphire/timestamp@npm:^1.0.1": + version: 1.0.1 + resolution: "@sapphire/timestamp@npm:1.0.1" + checksum: 40320946cb8fcbbb610b94019882eb39c900b9af87e4a2d173299efaa062921662d950780c273fd44f4ec9877983d725d28f0b999314f338f3bfc0ab3c45a8cb + languageName: node + linkType: hard + "@sapphire/ts-config@npm:^4.0.0": version: 4.0.0 resolution: "@sapphire/ts-config@npm:4.0.0" @@ -424,6 +509,34 @@ __metadata: languageName: node linkType: hard +"@snowcrystals/icicle@npm:1.0.3, @snowcrystals/icicle@npm:^1.0.3": + version: 1.0.3 + resolution: "@snowcrystals/icicle@npm:1.0.3" + dependencies: + "@sapphire/timestamp": ^1.0.1 + colorette: ^2.0.19 + checksum: 968d93d0b67b7b0129351b5db157af28f5f3fc796113318942330c4dd28fda131eb1d803811378bc9f790718c6b29fb7d536e534a993c970f57d78d9506072dc + languageName: node + linkType: hard + +"@snowcrystals/iglo@npm:^1.2.1": + version: 1.2.1 + resolution: "@snowcrystals/iglo@npm:1.2.1" + dependencies: + "@snowcrystals/icicle": 1.0.3 + discord.js: ^14.9.0 + lodash: ^4.17.21 + checksum: 9f1cfb41a549b39be5bea900b17886a2ecdb817c15205cf37f39841937179e686b8fee8d0fad59da2f2ec0903210bdcba6aa07bfaef8a41beb2ea4ddd338a138 + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 1d575d02d2a9f0c5a4ca5180635ebd2ad59e0f18b42a65f3d04844148b49b3db35cf00b6012a1af2d59c2ab3caca59451c5689f747ba8667ee586ad717ee58e1 + languageName: node + linkType: hard + "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" @@ -501,6 +614,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:^8.5.4": + version: 8.5.4 + resolution: "@types/ws@npm:8.5.4" + dependencies: + "@types/node": "*" + checksum: fefbad20d211929bb996285c4e6f699b12192548afedbe4930ab4384f8a94577c9cd421acaad163cacd36b88649509970a05a0b8f20615b30c501ed5269038d1 + languageName: node + linkType: hard + "@typescript-eslint/eslint-plugin@npm:^5.58.0": version: 5.58.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.58.0" @@ -1009,6 +1131,15 @@ __metadata: languageName: node linkType: hard +"busboy@npm:^1.6.0": + version: 1.6.0 + resolution: "busboy@npm:1.6.0" + dependencies: + streamsearch: ^1.1.0 + checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e + languageName: node + linkType: hard + "cacache@npm:^16.1.0": version: 16.1.3 resolution: "cacache@npm:16.1.3" @@ -1209,7 +1340,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.19": +"colorette@npm:2.0.19, colorette@npm:^2.0.19": version: 2.0.19 resolution: "colorette@npm:2.0.19" checksum: 888cf5493f781e5fcf54ce4d49e9d7d698f96ea2b2ef67906834bb319a392c667f9ec69f4a10e268d2946d13a9503d2d19b3abaaaf174e3451bfe91fb9d82427 @@ -1397,6 +1528,34 @@ __metadata: languageName: node linkType: hard +"discord-api-types@npm:^0.37.37": + version: 0.37.39 + resolution: "discord-api-types@npm:0.37.39" + checksum: 21346afd1e9987bba9b8e93c51b4a4279c10ffd3251806800385b19631c9f258f26524857b6f88da995285f35f0d956b3dde2e1ed6eb5233e5b2122754fbaee7 + languageName: node + linkType: hard + +"discord.js@npm:^14.9.0": + version: 14.9.0 + resolution: "discord.js@npm:14.9.0" + dependencies: + "@discordjs/builders": ^1.6.0 + "@discordjs/collection": ^1.5.0 + "@discordjs/formatters": ^0.3.0 + "@discordjs/rest": ^1.7.0 + "@discordjs/util": ^0.2.0 + "@sapphire/snowflake": ^3.4.0 + "@types/ws": ^8.5.4 + discord-api-types: ^0.37.37 + fast-deep-equal: ^3.1.3 + lodash.snakecase: ^4.1.1 + tslib: ^2.5.0 + undici: ^5.21.0 + ws: ^8.13.0 + checksum: 34589830f771b238975cbabb82531db78756b1b132b6b296ad845bc93755cfee34e65febb638e1b77e9e68d9ce2362cd4d4057123c37909e1354d670b747cb71 + languageName: node + linkType: hard + "doctrine@npm:^3.0.0": version: 3.0.0 resolution: "doctrine@npm:3.0.0" @@ -1415,6 +1574,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.0.3": + version: 16.0.3 + resolution: "dotenv@npm:16.0.3" + checksum: afcf03f373d7a6d62c7e9afea6328e62851d627a4e73f2e12d0a8deae1cd375892004f3021883f8aec85932cd2834b091f568ced92b4774625b321db83b827f8 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -1742,6 +1908,17 @@ __metadata: languageName: node linkType: hard +"file-type@npm:^18.2.1": + version: 18.2.1 + resolution: "file-type@npm:18.2.1" + dependencies: + readable-web-to-node-stream: ^3.0.2 + strtok3: ^7.0.0 + token-types: ^5.0.1 + checksum: bbc9381292e96a72ecd892f9f5e1a9a8d3f9717955841346e55891acfe099135bfa149f7dad51f35ee52b5e7e0a1a02d7375061b2800758011682c2e9d96953e + languageName: node + linkType: hard + "fill-range@npm:^7.0.1": version: 7.0.1 resolution: "fill-range@npm:7.0.1" @@ -1886,6 +2063,36 @@ __metadata: languageName: node linkType: hard +"gitcord@workspace:.": + version: 0.0.0-use.local + resolution: "gitcord@workspace:." + dependencies: + "@commitlint/cli": ^17.6.1 + "@commitlint/config-angular": ^17.6.1 + "@sapphire/eslint-config": ^4.4.1 + "@sapphire/prettier-config": ^1.4.5 + "@sapphire/ts-config": ^4.0.0 + "@snowcrystals/icicle": ^1.0.3 + "@snowcrystals/iglo": ^1.2.1 + "@types/node": ^18.15.11 + "@typescript-eslint/eslint-plugin": ^5.59.0 + "@typescript-eslint/parser": ^5.59.0 + colorette: 2.0.19 + discord.js: ^14.9.0 + dotenv: ^16.0.3 + eslint: ^8.38.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-prettier: ^4.2.1 + husky: ^8.0.3 + is-ci: ^3.0.1 + lint-staged: ^13.2.1 + nodemon: ^2.0.22 + prettier: ^2.8.7 + typescript: 5.0.4 + zod: ^3.21.4 + languageName: unknown + linkType: soft + "glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -2099,6 +2306,13 @@ __metadata: languageName: node linkType: hard +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e + languageName: node + linkType: hard + "ignore-by-default@npm:^1.0.1": version: 1.0.1 resolution: "ignore-by-default@npm:1.0.1" @@ -2542,7 +2756,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.15": +"lodash@npm:^4.17.15, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -3122,6 +3336,13 @@ __metadata: languageName: node linkType: hard +"peek-readable@npm:^5.0.0": + version: 5.0.0 + resolution: "peek-readable@npm:5.0.0" + checksum: bef5ceb50586eb42e14efba274ac57ffe97f0ed272df9239ce029f688f495d9bf74b2886fa27847c706a9db33acda4b7d23bbd09a2d21eb4c2a54da915117414 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -3258,6 +3479,15 @@ __metadata: languageName: node linkType: hard +"readable-web-to-node-stream@npm:^3.0.2": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: ^3.6.0 + checksum: 8c56cc62c68513425ddfa721954875b382768f83fa20e6b31e365ee00cbe7a3d6296f66f7f1107b16cd3416d33aa9f1680475376400d62a081a88f81f0ea7f9c + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -3612,6 +3842,13 @@ __metadata: languageName: node linkType: hard +"streamsearch@npm:^1.1.0": + version: 1.1.0 + resolution: "streamsearch@npm:1.1.0" + checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942 + languageName: node + linkType: hard + "string-argv@npm:^0.3.1": version: 0.3.1 resolution: "string-argv@npm:0.3.1" @@ -3698,6 +3935,16 @@ __metadata: languageName: node linkType: hard +"strtok3@npm:^7.0.0": + version: 7.0.0 + resolution: "strtok3@npm:7.0.0" + dependencies: + "@tokenizer/token": ^0.3.0 + peek-readable: ^5.0.0 + checksum: 2ebe7ad8f2aea611dec6742cf6a42e82764892a362907f7ce493faf334501bf981ce21c828dcc300457e6d460dc9c34d644ededb3b01dcb9e37559203cf1748c + languageName: node + linkType: hard + "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -3737,30 +3984,6 @@ __metadata: languageName: node linkType: hard -"template@workspace:.": - version: 0.0.0-use.local - resolution: "template@workspace:." - dependencies: - "@commitlint/cli": ^17.6.1 - "@commitlint/config-angular": ^17.6.1 - "@sapphire/eslint-config": ^4.4.1 - "@sapphire/prettier-config": ^1.4.5 - "@sapphire/ts-config": ^4.0.0 - "@types/node": ^18.15.11 - "@typescript-eslint/eslint-plugin": ^5.59.0 - "@typescript-eslint/parser": ^5.59.0 - eslint: ^8.38.0 - eslint-config-prettier: ^8.8.0 - eslint-plugin-prettier: ^4.2.1 - husky: ^8.0.3 - is-ci: ^3.0.1 - lint-staged: ^13.2.1 - nodemon: ^2.0.22 - prettier: ^2.8.7 - typescript: 5.0.4 - languageName: unknown - linkType: soft - "text-extensions@npm:^1.0.0": version: 1.9.0 resolution: "text-extensions@npm:1.9.0" @@ -3800,6 +4023,16 @@ __metadata: languageName: node linkType: hard +"token-types@npm:^5.0.1": + version: 5.0.1 + resolution: "token-types@npm:5.0.1" + dependencies: + "@tokenizer/token": ^0.3.0 + ieee754: ^1.2.1 + checksum: 32780123bc6ce8b6a2231d860445c994a02a720abf38df5583ea957aa6626873cd1c4dd8af62314da4cf16ede00c379a765707a3b06f04b8808c38efdae1c785 + languageName: node + linkType: hard + "touch@npm:^3.1.0": version: 3.1.0 resolution: "touch@npm:3.1.0" @@ -3818,6 +4051,13 @@ __metadata: languageName: node linkType: hard +"ts-mixer@npm:^6.0.3": + version: 6.0.3 + resolution: "ts-mixer@npm:6.0.3" + checksum: 7fbaba0a413bf817835a6a23d46bccf4192dd4d7345b6bae9d594c88acffac35bf4995ef3cce753090c8abcdf2afd16dba8899365584a1f960ccc2a15bf2e2d6 + languageName: node + linkType: hard + "ts-node@npm:^10.8.1": version: 10.8.1 resolution: "ts-node@npm:10.8.1" @@ -3979,6 +4219,15 @@ __metadata: languageName: node linkType: hard +"undici@npm:^5.21.0": + version: 5.21.2 + resolution: "undici@npm:5.21.2" + dependencies: + busboy: ^1.6.0 + checksum: baceaa9e610966631e86ad2869b657556dd465438eed55e8079cec2a306ecbeecfde2d6e37e43baf96a4c59588ebef50476131e96e018dcc0a7f5db7e6a06c85 + languageName: node + linkType: hard + "unique-filename@npm:^2.0.0": version: 2.0.1 resolution: "unique-filename@npm:2.0.1" @@ -4093,6 +4342,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.13.0": + version: 8.13.0 + resolution: "ws@npm:8.13.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 53e991bbf928faf5dc6efac9b8eb9ab6497c69feeb94f963d648b7a3530a720b19ec2e0ec037344257e05a4f35bd9ad04d9de6f289615ffb133282031b18c61c + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -4156,3 +4420,10 @@ __metadata: checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 languageName: node linkType: hard + +"zod@npm:^3.21.4": + version: 3.21.4 + resolution: "zod@npm:3.21.4" + checksum: f185ba87342ff16f7a06686767c2b2a7af41110c7edf7c1974095d8db7a73792696bcb4a00853de0d2edeb34a5b2ea6a55871bc864227dace682a0a28de33e1f + languageName: node + linkType: hard From b8afbd962ab6db3bad7f1689492d39d449504590 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 20:47:17 +0200 Subject: [PATCH 2/7] chore: update environment variable testing --- src/index.ts | 7 ++++++- src/lib/env.ts | 37 ++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index b8c7913f..9d688750 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,9 @@ import { config } from "dotenv"; config(); -import "./lib/env.js"; +import parse from "./lib/env.js"; +parse(); + +import GitCordClient from "./lib/GitCordClient.js"; +const client = new GitCordClient(); +client.start(); diff --git a/src/lib/env.ts b/src/lib/env.ts index 5a60ea0c..666ebeec 100644 --- a/src/lib/env.ts +++ b/src/lib/env.ts @@ -8,26 +8,29 @@ const envSchema = z.object({ DISCORD_BOT_TOKEN: z.string().nonempty() }); -try { - envSchema.parse(process.env); -} catch (err) { - if (!(err instanceof ZodError)) { - console.error(err); - process.exit(1); - } +/** Parses process.env to check if all required environment variables are present and valid */ +export default function parse() { + try { + envSchema.parse(process.env); + } catch (err) { + if (!(err instanceof ZodError)) { + console.error(err); + process.exit(1); + } - // Filter out missing ones - const missing = err.issues.filter((issue) => issue.message === "Required").map((issue) => bold(issue.path[0])); - logger.fatal(`The following environment variables are missing: ${missing}`); + // Filter out missing ones + const missing = err.issues.filter((issue) => issue.message === "Required").map((issue) => bold(issue.path[0])); + logger.fatal(`The following environment variables are missing: ${missing}`); - const failedTest = err.issues.filter((issue) => issue.message !== "Required"); - for (const failedItem of failedTest) { - // Environment variable - const path = failedItem.path[0]; - logger.fatal(`[${path}]: Failed the test with reason: ${failedItem.message}`); - } + const failedTest = err.issues.filter((issue) => issue.message !== "Required"); + for (const failedItem of failedTest) { + // Environment variable + const path = failedItem.path[0]; + logger.fatal(`[${path}]: Failed the test with reason: ${failedItem.message}`); + } - process.exit(1); + process.exit(1); + } } declare global { From fd5de8c26cc9868d3df6ff429e9cced76ea3de5e Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 20:51:09 +0200 Subject: [PATCH 3/7] feat: add discord client initialization --- src/lib/GitCordClient.ts | 17 +++++++++++++++++ src/lib/constants.ts | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/lib/GitCordClient.ts create mode 100644 src/lib/constants.ts diff --git a/src/lib/GitCordClient.ts b/src/lib/GitCordClient.ts new file mode 100644 index 00000000..d0b3b2c5 --- /dev/null +++ b/src/lib/GitCordClient.ts @@ -0,0 +1,17 @@ +import { IgloClient } from "@snowcrystals/iglo"; +import { BOT_COMMANDS_DIR, BOT_LISTENER_DIR } from "./constants.js"; + +export default class GitCordClient extends IgloClient { + public constructor() { + super({ + client: { intents: ["GuildWebhooks", "Guilds"], allowedMentions: { repliedUser: true, roles: [], users: [] } }, + paths: { commands: BOT_COMMANDS_DIR, events: BOT_LISTENER_DIR, interactions: BOT_LISTENER_DIR }, + logger: { defaultFormat: { infix: "[BOT]" } } + }); + } + + /** Starts the Discord bot and it's processes */ + public start() { + void this.login(process.env.DISCORD_BOT_TOKEN); + } +} diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 00000000..ad8cecb3 --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,10 @@ +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +// === Discord bot directory constants === +export const BASE_BOT_DIR = join(__dirname, "..", "bot"); +export const BOT_COMMANDS_DIR = join(BASE_BOT_DIR, "commands"); +export const BOT_LISTENER_DIR = join(BASE_BOT_DIR, "listeners"); +export const BOT_INTERACTIONS_DIR = join(BASE_BOT_DIR, "interactions"); From 6621f66586272e7f8ea4774102e5f4cfb11c0b22 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 20:52:40 +0200 Subject: [PATCH 4/7] feat: add ready event listener --- src/bot/listeners/ReadyListener.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/bot/listeners/ReadyListener.ts diff --git a/src/bot/listeners/ReadyListener.ts b/src/bot/listeners/ReadyListener.ts new file mode 100644 index 00000000..66220e4a --- /dev/null +++ b/src/bot/listeners/ReadyListener.ts @@ -0,0 +1,10 @@ +import { ApplyOptions, EventListener, type EventListenerOptions } from "@snowcrystals/iglo"; +import { bold } from "colorette"; + +@ApplyOptions({ name: "ready", once: true }) +export default class extends EventListener { + public override run() { + const username = bold(this.client.user!.tag); + this.client.logger.info(`${username} is up and running!`); + } +} From 031e820ead26741ef72bbb88bb6bb6c5ad20e871 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 20:55:54 +0200 Subject: [PATCH 5/7] fix(GitCordClient): incorrectly initializing of client --- src/lib/GitCordClient.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/GitCordClient.ts b/src/lib/GitCordClient.ts index d0b3b2c5..105281cf 100644 --- a/src/lib/GitCordClient.ts +++ b/src/lib/GitCordClient.ts @@ -1,17 +1,18 @@ import { IgloClient } from "@snowcrystals/iglo"; -import { BOT_COMMANDS_DIR, BOT_LISTENER_DIR } from "./constants.js"; +import { BOT_COMMANDS_DIR, BOT_INTERACTIONS_DIR, BOT_LISTENER_DIR } from "./constants.js"; export default class GitCordClient extends IgloClient { public constructor() { super({ client: { intents: ["GuildWebhooks", "Guilds"], allowedMentions: { repliedUser: true, roles: [], users: [] } }, - paths: { commands: BOT_COMMANDS_DIR, events: BOT_LISTENER_DIR, interactions: BOT_LISTENER_DIR }, + paths: { commands: BOT_COMMANDS_DIR, events: BOT_LISTENER_DIR, interactions: BOT_INTERACTIONS_DIR }, logger: { defaultFormat: { infix: "[BOT]" } } }); } /** Starts the Discord bot and it's processes */ public start() { - void this.login(process.env.DISCORD_BOT_TOKEN); + void this.run(process.env.DISCORD_BOT_TOKEN); + console.log(this.listenerCount("ready")); } } From e17d6226fe5b9ba8ac2a382d53438ea9c9b51d98 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 21:01:37 +0200 Subject: [PATCH 6/7] feat(Client): add status message --- src/bot/listeners/ReadyListener.ts | 7 ++++++- src/lib/GitCordClient.ts | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/bot/listeners/ReadyListener.ts b/src/bot/listeners/ReadyListener.ts index 66220e4a..eac17e79 100644 --- a/src/bot/listeners/ReadyListener.ts +++ b/src/bot/listeners/ReadyListener.ts @@ -1,10 +1,15 @@ import { ApplyOptions, EventListener, type EventListenerOptions } from "@snowcrystals/iglo"; import { bold } from "colorette"; +import { ActivityType } from "discord.js"; @ApplyOptions({ name: "ready", once: true }) export default class extends EventListener { public override run() { - const username = bold(this.client.user!.tag); + if (!this.client.isReady()) return; + + const username = bold(this.client.user.tag); this.client.logger.info(`${username} is up and running!`); + + this.client.user.setPresence({ activities: [{ name: "GitHub webhooks", type: ActivityType.Listening }] }); } } diff --git a/src/lib/GitCordClient.ts b/src/lib/GitCordClient.ts index 105281cf..f8f1b3b0 100644 --- a/src/lib/GitCordClient.ts +++ b/src/lib/GitCordClient.ts @@ -13,6 +13,5 @@ export default class GitCordClient extends IgloClient { /** Starts the Discord bot and it's processes */ public start() { void this.run(process.env.DISCORD_BOT_TOKEN); - console.log(this.listenerCount("ready")); } } From c6e3c86bacc1df84da9722bf717f8fae7cdfe859 Mon Sep 17 00:00:00 2001 From: Daan Klarenbeek Date: Tue, 18 Apr 2023 21:03:17 +0200 Subject: [PATCH 7/7] fix: typo 's --- src/lib/GitCordClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/GitCordClient.ts b/src/lib/GitCordClient.ts index f8f1b3b0..6527bd43 100644 --- a/src/lib/GitCordClient.ts +++ b/src/lib/GitCordClient.ts @@ -10,7 +10,7 @@ export default class GitCordClient extends IgloClient { }); } - /** Starts the Discord bot and it's processes */ + /** Starts the Discord bot and its processes */ public start() { void this.run(process.env.DISCORD_BOT_TOKEN); }