Updated env

This commit is contained in:
2025-03-02 21:09:43 +01:00
parent 8d2fba1c21
commit 0f4d317935
17 changed files with 72 additions and 52 deletions

View File

@@ -40,6 +40,7 @@
"@discord-player/extractor": "^7.1.0", "@discord-player/extractor": "^7.1.0",
"@swc/cli": "^0.6.0", "@swc/cli": "^0.6.0",
"@swc/core": "^1.11.5", "@swc/core": "^1.11.5",
"@t3-oss/env-core": "^0.12.0",
"anilist": "^0.12.4", "anilist": "^0.12.4",
"axios": "^1.8.1", "axios": "^1.8.1",
"chalk": "^5.4.1", "chalk": "^5.4.1",

22
pnpm-lock.yaml generated
View File

@@ -25,6 +25,9 @@ importers:
'@swc/core': '@swc/core':
specifier: ^1.11.5 specifier: ^1.11.5
version: 1.11.5 version: 1.11.5
'@t3-oss/env-core':
specifier: ^0.12.0
version: 0.12.0(typescript@5.8.2)(zod@3.24.2)
anilist: anilist:
specifier: ^0.12.4 specifier: ^0.12.4
version: 0.12.4 version: 0.12.4
@@ -1063,6 +1066,20 @@ packages:
resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
'@t3-oss/env-core@0.12.0':
resolution: {integrity: sha512-lOPj8d9nJJTt81mMuN9GMk8x5veOt7q9m11OSnCBJhwp1QrL/qR+M8Y467ULBSm9SunosryWNbmQQbgoiMgcdw==}
peerDependencies:
typescript: '>=5.0.0'
valibot: ^1.0.0-beta.7 || ^1.0.0
zod: ^3.24.0
peerDependenciesMeta:
typescript:
optional: true
valibot:
optional: true
zod:
optional: true
'@tokenizer/token@0.3.0': '@tokenizer/token@0.3.0':
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
@@ -3785,6 +3802,11 @@ snapshots:
dependencies: dependencies:
defer-to-connect: 2.0.1 defer-to-connect: 2.0.1
'@t3-oss/env-core@0.12.0(typescript@5.8.2)(zod@3.24.2)':
optionalDependencies:
typescript: 5.8.2
zod: 3.24.2
'@tokenizer/token@0.3.0': {} '@tokenizer/token@0.3.0': {}
'@tootallnate/once@1.1.2': '@tootallnate/once@1.1.2':

View File

@@ -2,7 +2,7 @@ import { REST, Routes } from "discord.js"
import env from "../src/utils/Env" import env from "../src/utils/Env"
import { log } from "../src/utils/Logger.js" import { log } from "../src/utils/Logger.js"
const rest = new REST({ version: "10" }).setToken(env.dev.devtoken) const rest = new REST({ version: "10" }).setToken(env.dev.DEVTOKEN)
try { try {
log("Started deleting application (/) commands.", "info") log("Started deleting application (/) commands.", "info")

View File

@@ -3,7 +3,7 @@ import fs from "node:fs"
import { ICommand } from "../src/interfaces" import { ICommand } from "../src/interfaces"
import env from "../src/utils/Env" import env from "../src/utils/Env"
import { log } from "../src/utils/Logger.js" import { log } from "../src/utils/Logger.js"
const rest = new REST({ version: "10" }).setToken(env.prod.token) const rest = new REST({ version: "10" }).setToken(env.prod.TOKEN)
const commands: RESTPutAPIApplicationCommandsJSONBody = [] const commands: RESTPutAPIApplicationCommandsJSONBody = []
const commandFiles = fs.readdirSync("./src/commands").filter(file => file.endsWith(".ts")) const commandFiles = fs.readdirSync("./src/commands").filter(file => file.endsWith(".ts"))

View File

@@ -3,7 +3,7 @@ import fs from "fs"
import { ICommand } from "../src/interfaces" import { ICommand } from "../src/interfaces"
import env from "../src/utils/Env" import env from "../src/utils/Env"
import { log } from "../src/utils/Logger.js" import { log } from "../src/utils/Logger.js"
const rest = new REST({ version: "10" }).setToken(env.dev.devtoken) const rest = new REST({ version: "10" }).setToken(env.dev.DEVTOKEN)
const commands: RESTPutAPIApplicationCommandsJSONBody = [] const commands: RESTPutAPIApplicationCommandsJSONBody = []
const commandFiles = fs.readdirSync("./src/commands/").filter(file => file.endsWith(".ts")) const commandFiles = fs.readdirSync("./src/commands/").filter(file => file.endsWith(".ts"))

View File

@@ -24,7 +24,7 @@ export default {
const user = (interaction.options.getUser("user") || interaction.user) as User const user = (interaction.options.getUser("user") || interaction.user) as User
let size: number let size: number
if (user.id === env.prod.dev) { if (user.id === env.prod.DEV) {
size = Math.floor(Math.random() * 30) + 1 size = Math.floor(Math.random() * 30) + 1
} else { } else {
size = Math.floor(Math.random() * 10) + 1 size = Math.floor(Math.random() * 10) + 1

View File

@@ -6,7 +6,7 @@ import env from "~/utils/Env.js"
const cmd: SubCommand = async (interaction) => { const cmd: SubCommand = async (interaction) => {
await interaction.deferReply() await interaction.deferReply()
if (interaction.user.id !== env.prod.dev) { if (interaction.user.id !== env.prod.DEV) {
await interaction.editReply("You are not allowed to use this command.") await interaction.editReply("You are not allowed to use this command.")
return return
} }

View File

@@ -11,7 +11,7 @@ const cmd: SubCommand = async (interaction) => {
const discordMember = interaction.member as GuildMember const discordMember = interaction.member as GuildMember
if (discordMember.user.id !== env.prod.dev) { if (discordMember.user.id !== env.prod.DEV) {
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
description: "You do not have permission to use this command.", description: "You do not have permission to use this command.",

View File

@@ -24,7 +24,7 @@ const cmd: SubCommand = async (interaction) => {
return return
} }
if (discordMember.user.id !== env.prod.dev) { if (discordMember.user.id !== env.prod.DEV) {
await interaction.editReply({ await interaction.editReply({
embeds: [{ embeds: [{
description: "You do not have permission to use this command.", description: "You do not have permission to use this command.",

View File

@@ -41,6 +41,8 @@ export default {
const timeString = interaction.options.getString("time")! const timeString = interaction.options.getString("time")!
const reason = interaction.options.getString("reason") || "No reason provided" const reason = interaction.options.getString("reason") || "No reason provided"
const mod = interaction.member! as GuildMember const mod = interaction.member! as GuildMember
// FIXME: report error to ms manitainer
// @ts-expect-error: i'll file a bu report later
const time = ms(timeString) const time = ms(timeString)
if (!time) { if (!time) {

View File

@@ -30,7 +30,7 @@ export default {
if (interaction.customId === "staffapply") { if (interaction.customId === "staffapply") {
await interaction.deferReply({ flags: MessageFlags.Ephemeral }) await interaction.deferReply({ flags: MessageFlags.Ephemeral })
if (user.user.id !== env.prod.dev) { if (user.user.id !== env.prod.DEV) {
if (status === "0") { if (status === "0") {
await interaction.editReply("Staff applications are currently closed.") await interaction.editReply("Staff applications are currently closed.")
return return

View File

@@ -4,7 +4,7 @@ import * as schema from "./schema.js"
const db = drizzle({ const db = drizzle({
connection: { connection: {
url: env.prod.postgresURI url: env.prod.POSTGRESURI
}, },
schema: schema schema: schema
}) })

View File

@@ -49,7 +49,7 @@ export default async function autoDeployCommands(fileType: FileType, client: Ext
}).sort((a, b) => a.name > b.name ? 1 : -1) }).sort((a, b) => a.name > b.name ? 1 : -1)
client.on("ready", async (c) => { client.on("ready", async (c) => {
const guildclient = c.guilds.cache.get(env.dev.guildid)! const guildclient = c.guilds.cache.get(env.dev.GUILDID)!
const currentCommands = await guildclient.commands.fetch() const currentCommands = await guildclient.commands.fetch()
if (!currentCommands) return if (!currentCommands) return

View File

@@ -34,15 +34,15 @@ export class ExtendedClient extends Client {
let token: string let token: string
if (process.env.NODE_ENV === "dev" && process.env.TYPESCRIPT === "true") { if (process.env.NODE_ENV === "dev" && process.env.TYPESCRIPT === "true") {
log("Running in development mode. [tsx]", "info", { type: "preset", color: "lavender" }) log("Running in development mode. [tsx]", "info", { type: "preset", color: "lavender" })
token = env.dev.devtoken token = env.dev.DEVTOKEN
autoDeployCommands("ts", this) autoDeployCommands("ts", this)
} else if (process.env.NODE_ENV === "dev" && !process.env.TYPESCRIPT) { } else if (process.env.NODE_ENV === "dev" && !process.env.TYPESCRIPT) {
log("Running in development mode.", "info", { type: "preset", color: "lavender" }) log("Running in development mode.", "info", { type: "preset", color: "lavender" })
token = env.dev.devtoken token = env.dev.DEVTOKEN
autoDeployCommands("js", this) autoDeployCommands("js", this)
} else { } else {
log("Running in production mode.", "info", { type: "preset", color: "green" }) log("Running in production mode.", "info", { type: "preset", color: "green" })
token = env.prod.token token = env.prod.TOKEN
} }
this.login(token) this.login(token)

View File

@@ -1,47 +1,42 @@
import { createEnv } from "@t3-oss/env-core"
import { z } from "zod" import { z } from "zod"
import { MissingEnvVarsError } from "./Classes/EnvVarError.js" import { MissingEnvVarsError } from "./Classes/EnvVarError.js"
const prodEnvSchema = z.object({ const prodEnv = createEnv({
token: z.string({ message: "Missing or invalid TOKEN" }), server: {
dev: z.string({ message: "Missing or invalid DEV" }), TOKEN: z.string({ message: "TOKEN" }).min(1),
hypixelapikey: z.string({ message: "Missing or invalid HYPIXELAPIKEY" }), DEV: z.string({ message: "DEV" }).min(1),
redisURI: z.string({ message: "Missing or invalid REDISURI" }), HYPIXELAPIKEY: z.string({ message: "HYPIXELAPIKEY" }).min(1),
postgresURI: z.string({ message: "Missing or invalid POSTGRESURI" }) REDISURI: z.string({ message: "REDISURI" }).min(1),
}) POSTGRESURI: z.string({ message: "POSTGRESURI" }).min(1)
},
runtimeEnv: process.env,
onValidationError: (e) => {
const allErrors = e.map(err => err.message).join(" ")
const devEnvSchema = z.object({ throw new MissingEnvVarsError(`[PROD]: ${allErrors}`)
devtoken: z.string({ message: "Missing or invalid DEVTOKEN" }),
clientid: z.string({ message: "Missing or invalid CLIENTID" }),
devid: z.string({ message: "Missing or invalid DEVID" }),
guildid: z.string({ message: "Missing or invalid GUILDID" })
})
const parsedProdEnv = prodEnvSchema.safeParse({
token: process.env.TOKEN,
dev: process.env.DEV,
hypixelapikey: process.env.HYPIXELAPIKEY,
redisURI: process.env.REDISURI,
postgresURI: process.env.POSTGRESURI
})
const parsedDevEnv = devEnvSchema.safeParse({
devtoken: process.env.DEVTOKEN,
clientid: process.env.CLIENTID,
devid: process.env.DEVID,
guildid: process.env.GUILDID
})
if (!parsedProdEnv.success) {
throw new MissingEnvVarsError(parsedProdEnv.error.errors[0].message)
} }
})
if (!parsedDevEnv.success && process.env.NODE_ENV === "dev") { const devEnv = createEnv({
throw new MissingEnvVarsError(parsedDevEnv.error.errors[0].message) server: {
DEVTOKEN: z.string({ message: "DEVTOKEN" }).min(1),
CLIENTID: z.string({ message: "CLIENTID" }).min(1),
DEVID: z.string({ message: "DEVID" }).min(1),
GUILDID: z.string({ message: "GUILDID" }).min(1)
},
runtimeEnv: process.env,
skipValidation: process.env.NODE_ENV !== "dev",
onValidationError: (e) => {
const allErrors = e.map(err => err.message).join(" ")
throw new MissingEnvVarsError(`[DEV]: ${allErrors}`)
} }
})
const env = { const env = {
prod: parsedProdEnv.data, prod: prodEnv,
dev: parsedDevEnv.data dev: devEnv
} as { prod: z.infer<typeof prodEnvSchema>, dev: z.infer<typeof devEnvSchema> } }
export default env export default env

View File

@@ -1,7 +1,7 @@
import axios from "axios" import axios from "axios"
import { IGuild, IGuildData, IPlayer, IPlayerData } from "~/typings" import { IGuild, IGuildData, IPlayer, IPlayerData } from "~/typings"
import env from "~/utils/Env.js" import env from "~/utils/Env.js"
const apikey = env.prod.hypixelapikey const apikey = env.prod.HYPIXELAPIKEY
const mojang = "https://api.mojang.com/users/profiles/minecraft/" const mojang = "https://api.mojang.com/users/profiles/minecraft/"
const mojanguuid = "https://sessionserver.mojang.com/session/minecraft/profile/" const mojanguuid = "https://sessionserver.mojang.com/session/minecraft/profile/"
const hypixel = "https://api.hypixel.net/v2/player" const hypixel = "https://api.hypixel.net/v2/player"

View File

@@ -8,7 +8,7 @@ import loadAllEvents from "./Events/loadevents.js"
import { log } from "./Logger.js" import { log } from "./Logger.js"
const client = new Client() const client = new Client()
const redis = new Redis(env.prod.redisURI) const redis = new Redis(env.prod.REDISURI)
const player = new Player(client) const player = new Player(client)
let ft: "js" | "ts" let ft: "js" | "ts"