Skip to content

Commit

Permalink
added zod for .env validation and fixed logger
Browse files Browse the repository at this point in the history
  • Loading branch information
GhomKrosmonaute committed Jun 26, 2024
1 parent 6c85d41 commit 9987d58
Show file tree
Hide file tree
Showing 18 changed files with 128 additions and 38 deletions.
19 changes: 14 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"dependencies": {
"@discordjs/rest": "^0.5.0",
"@ghom/handler": "^3.1.0",
"@ghom/logger": "^2.0.0",
"@ghom/logger": "^2.0.1",
"@ghom/orm": "^1.7.0",
"boxen": "^7.0.0",
"chalk": "^5.0.1",
Expand All @@ -56,7 +56,8 @@
"sqlite3": "^5.0.8",
"tims": "^2.1.0",
"types-package-json": "^2.0.39",
"yargs-parser": "^21.0.1"
"yargs-parser": "^21.0.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@esbuild/linux-x64": "^0.20.1",
Expand Down
2 changes: 2 additions & 0 deletions src/app.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export * as command from "./app/command.ts"
export * as logger from "./app/logger.ts"
export * as slash from "./app/slash.ts"
export * as util from "./app/util.ts"

export { default as env } from "./app/env.ts"
7 changes: 4 additions & 3 deletions src/app/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import yargsParser from "yargs-parser"

import * as handler from "@ghom/handler"

import env from "./env.ts"

import * as util from "./util.ts"
import * as logger from "./logger.ts"
import * as argument from "./argument.ts"
import * as config from "./config.ts"

import { filename } from "dirname-filename-esm"

const __filename = filename(import.meta)

export const commandHandler = new handler.Handler(
Expand Down Expand Up @@ -476,7 +477,7 @@ export async function prepareCommand(
if (util.scrap(cmd.options.guildOwnerOnly, message))
if (
message.guild.ownerId !== message.member.id &&
process.env.BOT_OWNER !== message.member.id
env.BOT_OWNER !== message.member.id
)
return util.getSystemMessage("error", {
author: {
Expand Down Expand Up @@ -569,7 +570,7 @@ export async function prepareCommand(
})

if (await util.scrap(cmd.options.botOwnerOnly, message))
if (process.env.BOT_OWNER !== message.author.id)
if (env.BOT_OWNER !== message.author.id)
return util.getSystemMessage("error", {
author: {
name: "You must be my owner.",
Expand Down
3 changes: 2 additions & 1 deletion src/app/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { ORM } from "@ghom/orm"
import { logger } from "@ghom/logger"
import env from "./env.ts"
import path from "path"
import fs from "fs"

Expand All @@ -16,7 +17,7 @@ export const orm = new ORM({
useNullAsDefault: true,
connection: {
filename: path.join(dataDirectory, "sqlite3.db"),
timezone: process.env.BOT_TIMEZONE || "UTC",
timezone: env.BOT_TIMEZONE || "UTC",
},
},
logger,
Expand Down
82 changes: 82 additions & 0 deletions src/app/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import "dotenv/config"

import { z, ZodError } from "zod"
import fs from "fs"
import path from "path"
import chalk from "chalk"

import * as logger from "./logger.ts"

const localeList: { key: string; name: string }[] = JSON.parse(
fs.readFileSync(
path.join(process.cwd(), "node_modules", "dayjs", "locale.json"),
"utf-8",
),
)

const localeKeys = localeList.map((locale) => locale.key) as [
string,
...string[],
]

const timezones = Intl.supportedValuesOf("timeZone") as [string, ...string[]]

const envSchema = z.object({
BOT_TOKEN: z.string({
message: `You need to add your ${chalk.bold("BOT_TOKEN")} in the .env file. You can found this token on this page in the "Bot" tab: ${
process.env.BOT_ID
? `https://discord.com/developers/applications/${process.env.BOT_ID}/information`
: "https://discord.com/developers/applications"
}`,
}),
BOT_PREFIX: z.string({
message: `You need to add a ${chalk.bold("BOT_PREFIX")} in the .env file, for example: BOT_PREFIX="!"`,
}),
BOT_OWNER: z.string({
message: `You need to add your ${chalk.bold("BOT_OWNER")} Discord ID in the .env file, for example: BOT_OWNER="123456789012345678"`,
}),
BOT_ID: z.string({
message: `You need to add the ${chalk.bold("BOT_ID")} in the .env file. You can found this ID on this page in the "General Information" tab: ${
process.env.BOT_ID
? `https://discord.com/developers/applications/${process.env.BOT_ID}/information`
: "https://discord.com/developers/applications"
}`,
}),
BOT_MODE: z.enum(["factory", "test", "development", "production"], {
message: `You need to add a ${chalk.bold("BOT_MODE")} in the .env file, for example: BOT_MODE="development"`,
}),
BOT_LOCALE: z
.enum(localeKeys, {
message: `Your ${chalk.bold("BOT_LOCALE")} in the .env file is not valid. You can choose between this list:\n=> ${localeKeys.join(", ")}`,
})
.optional(),
BOT_TIMEZONE: z
.enum(timezones, {
message: `Your ${chalk.bold("BOT_TIMEZONE")} in the .env file is not valid. You can choose between this list:\n=> ${timezones.join(", ")}`,
})
.optional(),
DB_PORT: z.coerce
.number({
message: `The ${chalk.bold("DB_PORT")} must be a valid port number between 0 and 65535`,
})
.max(
65535,
`The ${chalk.bold("DB_PORT")} must be a valid port number between 0 and 65535`,
)
.optional(),
DB_HOST: z.string().optional(),
DB_USER: z.string().optional(),
DB_PASSWORD: z.string().optional(),
DB_DATABASE: z.string().optional(),
})

let env: z.infer<typeof envSchema>
try {
env = envSchema.parse(process.env)
} catch (error) {
const { errors } = error as ZodError
errors.forEach((err) => logger.error(err.message, ".env"))
process.exit(1)
}

export default env
1 change: 0 additions & 1 deletion src/app/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as config from "./config.ts"
import * as util from "./util.ts"

import { filename } from "dirname-filename-esm"

const __filename = filename(import.meta)

export type PaginatorKey = "previous" | "next" | "start" | "end"
Expand Down
14 changes: 7 additions & 7 deletions src/app/slash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import path from "path"
import chalk from "chalk"

import * as handler from "@ghom/handler"

import env from "./env.ts"

import * as logger from "./logger.ts"
import * as config from "./config.ts"
import * as util from "./util.ts"
Expand Down Expand Up @@ -253,13 +256,13 @@ export function validateSlashCommand(command: ISlashCommand) {
}

export async function registerSlashCommands(guildId?: string) {
const api = new rest.REST({ version: "10" }).setToken(process.env.BOT_TOKEN!)
const api = new rest.REST({ version: "10" }).setToken(env.BOT_TOKEN)

try {
const data = (await api.put(
guildId
? v10.Routes.applicationGuildCommands(process.env.BOT_ID!, guildId)
: v10.Routes.applicationCommands(process.env.BOT_ID!),
? v10.Routes.applicationGuildCommands(env.BOT_ID, guildId)
: v10.Routes.applicationCommands(env.BOT_ID),
{
body: slashCommands.map((cmd) => cmd.builder.toJSON()),
},
Expand Down Expand Up @@ -287,10 +290,7 @@ export async function prepareSlashCommand(
options: {},
}

if (
command.options.botOwnerOnly &&
interaction.user.id !== process.env.BOT_OWNER
)
if (command.options.botOwnerOnly && interaction.user.id !== env.BOT_OWNER)
return new discord.EmbedBuilder()
.setColor("Red")
.setDescription("This command can only be used by the bot owner")
Expand Down
6 changes: 4 additions & 2 deletions src/app/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import relative from "dayjs/plugin/relativeTime.js"
import timezone from "dayjs/plugin/timezone.js"
import toObject from "dayjs/plugin/toObject.js"

import env from "./env.ts"

import * as logger from "./logger.ts"
import * as config from "./config.ts"
import * as client from "./client.ts"
Expand Down Expand Up @@ -84,7 +86,7 @@ export async function checkUpdates() {
}
}

const locale = process.env.BOT_LOCALE
const locale = env.BOT_LOCALE

import(`dayjs/locale/${locale ?? "en"}.js`)
.then(() => dayjs.locale(locale ?? "en"))
Expand All @@ -102,7 +104,7 @@ dayjs.extend(timezone)
dayjs.extend(toObject)
dayjs.utc(1)

if (process.env.BOT_TIMEZONE) dayjs.tz.setDefault(process.env.BOT_TIMEZONE)
if (env.BOT_TIMEZONE) dayjs.tz.setDefault(env.BOT_TIMEZONE)

export { dayjs }

Expand Down
2 changes: 1 addition & 1 deletion src/commands/info.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default new app.Command({
lang: "yml",
content: [
`author: ${
message.client.users.resolve(process.env.BOT_OWNER!)!.username
message.client.users.resolve(app.env.BOT_OWNER)!.username
}`,
`uptime: ${time.duration(app.uptime(), {
format: "second",
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as app from "#app"
export const config: app.Config = {
ignoreBots: true,
getPrefix() {
return process.env.BOT_PREFIX!
return app.env.BOT_PREFIX!
},
client: {
intents: [
Expand Down
11 changes: 2 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import { filename } from "dirname-filename-esm"

const __filename = filename(import.meta)

import "dotenv/config.js"

for (const key of ["BOT_TOKEN", "BOT_PREFIX", "BOT_OWNER", "BOT_ID"]) {
if (!process.env[key] || /^{{.+}}$/.test(process.env[key] as string)) {
throw new Error(`You need to add "${key}" value in your .env file.`)
}
}
import env from "./app/env.ts"

const app = await import("#app")

Expand All @@ -19,7 +12,7 @@ try {
await app.listenerHandler.init()
await app.initPagination()
await app.checkUpdates()
await app.ClientSingleton.get().login(process.env.BOT_TOKEN)
await app.ClientSingleton.get().login(env.BOT_TOKEN)
} catch (error: any) {
app.error(error, __filename, true)
process.exit(1)
Expand Down
4 changes: 2 additions & 2 deletions src/listeners/command.messageCreate.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const listener: app.Listener<"messageCreate"> = {
.catch()

message.usedAsDefault = false
message.isFromBotOwner = message.author.id === process.env.BOT_OWNER!
message.isFromBotOwner = message.author.id === app.env.BOT_OWNER

app.emitMessage(message.channel, message)
app.emitMessage(message.author, message)
Expand Down Expand Up @@ -61,7 +61,7 @@ const listener: app.Listener<"messageCreate"> = {
if (
key !== "turn" &&
!app.cache.ensure<boolean>("turn", true) &&
message.author.id !== process.env.BOT_OWNER
message.author.id !== app.env.BOT_OWNER
)
return

Expand Down
2 changes: 1 addition & 1 deletion src/listeners/log.afterReady.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const listener: app.Listener<"afterReady"> = {
app.log(
`ok i'm ready! ${chalk.blue(
"My default prefix is",
)} ${chalk.bgBlueBright.black(process.env.BOT_PREFIX)}`,
)} ${chalk.bgBlueBright.black(app.env.BOT_PREFIX)}`,
)

figlet(app.packageJSON.name, (err, value) => {
Expand Down
3 changes: 0 additions & 3 deletions template.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# The Secret value of Discord Application
BOT_SECRET=

# The token of the bot
BOT_TOKEN=

Expand Down
1 change: 1 addition & 0 deletions templates/mysql2
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { ORM } from "@ghom/orm"
import { logger } from "@ghom/logger"
import env from "./env.ts"
import path from "path"

export const orm = new ORM({
Expand Down
1 change: 1 addition & 0 deletions templates/pg
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { ORM } from "@ghom/orm"
import { logger } from "@ghom/logger"
import env from "./env.ts"
import path from "path"

export const orm = new ORM({
Expand Down
1 change: 1 addition & 0 deletions templates/sqlite3
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { ORM } from "@ghom/orm"
import { logger } from "@ghom/logger"
import env from "./env.ts"
import path from "path"
import fs from "fs"

Expand Down

0 comments on commit 9987d58

Please sign in to comment.