diff --git a/.example.env b/.example.env index fa92395..b5b6926 100644 --- a/.example.env +++ b/.example.env @@ -17,8 +17,11 @@ STREAMER_ID= # Twitch ID of the streaming user CHATTER_ID= # Twitch ID of the chatting user CHATTER_IS_STREAMER= # If the bot that activates on commands is on the same account as the streamer, set this to true. Make sure the STREAMER_ID and CHATTER_ID match in that case. -# Pocketbase config -# POCKETBASE_URL= # Pocketbase URL. Defaults to http://localhost:8090 +# Postgres config +POSTGRES_HOST= # Hostname + port of the postgres database +POSTGRES_USER= # Username for logging in on the postgres database +POSTGRES_PASSWORD= # Password for logging in on the postgres database +POSTGRES_DB=twitchbot # Database name. Recommended value: twitchbot # Redis/Valkey config # REDIS_URL= # Redis URL. Defaults to redis://localhost:6379 diff --git a/.gitignore b/.gitignore index 0907968..aed3994 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json .env.production.local .env.local +# Drizzle config files +*.config.ts + # caches .eslintcache .cache diff --git a/compose.yml b/compose.yml index 65df7ca..afe9a13 100644 --- a/compose.yml +++ b/compose.yml @@ -9,25 +9,12 @@ services: - ./db/redis:/data environment: - VALKEY_EXTRA_FLAGS=--save 60 1 - # pocketbase: - # container_name: qweribot-pocketbase - # build: - # context: ./pocketbase - # ports: - # - 8090:8090 - # restart: no - # volumes: - # - ./db/pocketbase:/pb/pb_data postgres: container_name: postgres image: postgres:latest restart: unless-stopped env_file: - .env.development - # environment: - # POSTGRES_USER: $$POSTGRES_USER - # POSTGRES_PASSWORD: $$POSTGRES_PASSWORD - # POSTGRES_DB: $$POSTGRES_DB ports: - "5432:5432" volumes: diff --git a/drizzle.config.ts b/drizzle.config.ts deleted file mode 100644 index cfe6eef..0000000 --- a/drizzle.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig } from "drizzle-kit"; - -const url = `postgresql://admin:abcdefgh@localhost:5432/twitchbot`; - -export default defineConfig({ - dialect: 'postgresql', - schema: './src/db/schema.ts', - dbCredentials: { url } -}); diff --git a/package.json b/package.json index 72c6fd4..7ed85a4 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,14 @@ "drizzle-kit": "^0.31.4", "pg": "^8.16.3" }, + "scripts": { + "start": "NODE_ENV=production bun src/index.ts", + "start-dev": "NODE_ENV=development bun src/index.ts", + "migrate": "drizzle-kit push --config=drizzle-prod.config.ts", + "migrate-dev": "drizzle-kit push --config=drizzle-dev.config.ts", + "studio": "drizzle-kit studio --config=drizzle-prod.config.ts", + "studio-dev": "drizzle-kit studio --config=drizzle-dev.config.ts" + }, "peerDependencies": { "typescript": "^5.8.3" }, diff --git a/src/commands/getloot.ts b/src/commands/getloot.ts index 2e53e29..16f37e8 100644 --- a/src/commands/getloot.ts +++ b/src/commands/getloot.ts @@ -1,7 +1,7 @@ import { redis } from "bun"; import { Command, sendMessage } from "commands"; import { getUserRecord, updateUserRecord } from "db/dbUser"; -import items, { type inventory, type items } from "items"; +import itemMap, { type inventory, type items } from "items"; import { buildTimeString } from "lib/dateManager"; import { timeout } from "lib/timeout"; import { isInvuln, removeInvuln } from "lib/invuln"; @@ -59,7 +59,7 @@ export default new Command({ if (Math.floor(Math.random() * 250) === 0) itemDiff.silverbullet! += 1; }; - for (const [item, amount] of Object.entries(itemDiff) as [items, number]) { + for (const [item, amount] of Object.entries(itemDiff) as [items, number][]) { if (userData.inventory[item]) userData.inventory[item] += amount; else userData.inventory[item] = amount; }; @@ -68,7 +68,7 @@ export default new Command({ for (const [item, amount] of Object.entries(itemDiff)) { if (amount === 0) continue; - const selection = items.get(item); + const selection = itemMap.get(item); if (!selection) continue; itemstrings.push(`${amount} ${selection.prettyName + (amount === 1 ? '' : selection.plural)}`); }; diff --git a/src/connectionCheck.ts b/src/connectionCheck.ts index 74807a3..856852b 100644 --- a/src/connectionCheck.ts +++ b/src/connectionCheck.ts @@ -1,10 +1,13 @@ import { RedisClient } from "bun"; +import db from "db/connection"; +import { users } from "db/schema"; import logger from "lib/logger"; export async function connectionCheck() { - let pbstatus = false; + let pgstatus = false; try { - pbstatus = true; + await db.select().from(users); // The query doesn't matter, only that it fails. This also fails if the migration hasn't taken place + pgstatus = true; } catch { }; const tempclient = new RedisClient(undefined, { connectionTimeout: 100, @@ -16,7 +19,7 @@ export async function connectionCheck() { redisstatus = true; } catch { }; logger.info(`Currently using the "${process.env.NODE_ENV ?? "production"}" database`); - pbstatus ? logger.ok(`Pocketbase status: good`) : logger.err(`Pocketbase status: bad`); + pgstatus ? logger.ok(`Postgresql status: good`) : logger.err(`Postgresql status: bad`); redisstatus ? logger.ok(`Redis/Valkey status: good`) : logger.err(`Redis/Valkey status: bad`); - if (!pbstatus || !redisstatus) process.exit(1); + if (!pgstatus || !redisstatus) process.exit(1); }; diff --git a/src/db/connection.ts b/src/db/connection.ts index 305f21b..793bdd1 100644 --- a/src/db/connection.ts +++ b/src/db/connection.ts @@ -1,18 +1,15 @@ import * as schema from "db/schema"; +import logger from "lib/logger"; -// const host = process.env.POSTGRES_HOST ?? ""; -// if (!host) { logger.enverr("POSTGRES_HOST"); process.exit(1); }; -// -// const user = process.env.POSTGRES_USER ?? ""; -// if (!user) { logger.enverr("POSTGRES_USER"); process.exit(1); }; -// const password = process.env.POSTGRES_PASSWORD ?? ""; -// if (!password) { logger.enverr("POSTGRES_USER"); process.exit(1); }; -// const database = process.env.POSTGRES_DB ?? "twitchbot"; -// -// const connection = { host, user, password, database }; -const url = `postgresql://admin:abcdefgh@localhost:5432/twitchbot`; +const host = process.env.POSTGRES_HOST ?? ""; +if (!host) { logger.enverr("POSTGRES_HOST"); process.exit(1); }; +const user = process.env.POSTGRES_USER ?? ""; +if (!user) { logger.enverr("POSTGRES_USER"); process.exit(1); }; +const password = process.env.POSTGRES_PASSWORD ?? ""; +if (!password) { logger.enverr("POSTGRES_USER"); process.exit(1); }; +const database = process.env.POSTGRES_DB ?? ""; +if (!database) { logger.enverr("POSTGRES_DB"); process.exit(1); }; +const url = `postgresql://${user}:${password}@${host}/${database}`; import { drizzle } from 'drizzle-orm/bun-sql'; -export default drizzle(url, { - schema -}); +export default drizzle(url, { schema }); diff --git a/src/lib/getStats.ts b/src/lib/getStats.ts index 43e5890..badd457 100644 --- a/src/lib/getStats.ts +++ b/src/lib/getStats.ts @@ -40,7 +40,12 @@ export async function getItemStats(target: User, thismonth: boolean) { ]); if (!items || !cheers) return; - const returnObj: inventory = {}; + const returnObj: inventory = { + blaster: 0, + silverbullet: 0, + grenade: 0, + tnt: 0, + }; for (const item of items) { if (!returnObj[item.item]) returnObj[item.item] = 0; @@ -48,8 +53,8 @@ export async function getItemStats(target: User, thismonth: boolean) { }; for (const cheer of cheers) { - if (!returnObj[cheer.cheer]) returnObj[cheer.cheer] = 0; - returnObj[cheer.cheer]! += 1 + if (!returnObj[cheer.event]) returnObj[cheer.event] = 0; + returnObj[cheer.event]! += 1 }; return returnObj;