From f038485cb798533d664424a44ee8dbf6b8453524 Mon Sep 17 00:00:00 2001 From: sianida26 Date: Wed, 29 May 2024 16:50:46 +0700 Subject: [PATCH] Added env check on compile time --- apps/backend/drizzle.config.ts | 7 ++----- apps/backend/package.json | 3 ++- apps/backend/src/appEnv.ts | 20 ++++++++++++++++++++ apps/backend/src/drizzle/index.ts | 3 ++- apps/backend/src/drizzle/migration.ts | 3 ++- apps/backend/src/index.ts | 5 +++-- apps/backend/src/routes/auth/route.ts | 3 ++- apps/backend/src/utils/authUtils.ts | 7 +++---- apps/backend/tsconfig.json | 7 +++++-- 9 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 apps/backend/src/appEnv.ts diff --git a/apps/backend/drizzle.config.ts b/apps/backend/drizzle.config.ts index 8361b20..cc3e359 100644 --- a/apps/backend/drizzle.config.ts +++ b/apps/backend/drizzle.config.ts @@ -1,11 +1,8 @@ import "dotenv/config"; import type { Config } from "drizzle-kit"; +import appEnv from "./src/appEnv"; -const databaseUrl = process.env.DATABASE_URL; - -if (!databaseUrl) { - throw new Error("DATABASE_URL is not set"); -} +const databaseUrl = appEnv.DATABASE_URL; export default { schema: "./src/drizzle/schema/*", diff --git a/apps/backend/package.json b/apps/backend/package.json index f86532c..ba6f66b 100644 --- a/apps/backend/package.json +++ b/apps/backend/package.json @@ -6,7 +6,8 @@ "db:push": "drizzle-kit push", "db:seed": "tsx src/drizzle/seed.ts", "db:migrate": "tsx src/drizzle/migration.ts", - "db:studio": "drizzle-kit studio" + "db:studio": "drizzle-kit studio", + "start": "tsc -p tsconfig.json && tsx src/index.ts" }, "dependencies": { "@hono/node-server": "^1.11.1", diff --git a/apps/backend/src/appEnv.ts b/apps/backend/src/appEnv.ts new file mode 100644 index 0000000..bedf2a1 --- /dev/null +++ b/apps/backend/src/appEnv.ts @@ -0,0 +1,20 @@ +import dotenv from "dotenv"; +import { z } from "zod"; + +dotenv.config(); + +const envSchema = z.object({ + APP_PORT: z.coerce.number().int(), + DATABASE_URL: z.string(), + ACCESS_TOKEN_SECRET: z.string(), + REFRESH_TOKEN_SECRET: z.string(), + COOKIE_SECRET: z.string(), +}); + +const parsedEnv = envSchema.safeParse(process.env); + +if (!parsedEnv.success) { + throw new Error(parsedEnv.error.toString()); +} + +export default parsedEnv.data; diff --git a/apps/backend/src/drizzle/index.ts b/apps/backend/src/drizzle/index.ts index c157f56..f32ff98 100644 --- a/apps/backend/src/drizzle/index.ts +++ b/apps/backend/src/drizzle/index.ts @@ -7,10 +7,11 @@ import * as rolesSchema from "./schema/roles"; import * as permissionsToRolesSchema from "./schema/permissionsToRoles"; import * as permissionsToUsersSchema from "./schema/permissionsToUsers"; import * as rolesToUsersSchema from "./schema/rolesToUsers"; +import appEnv from "../appEnv"; configDotenv(); -const dbUrl = process.env.DATABASE_URL; +const dbUrl = appEnv.DATABASE_URL; if (!dbUrl) throw new Error("DATABASE_URL is not set"); diff --git a/apps/backend/src/drizzle/migration.ts b/apps/backend/src/drizzle/migration.ts index 757dc93..7f8a9ce 100644 --- a/apps/backend/src/drizzle/migration.ts +++ b/apps/backend/src/drizzle/migration.ts @@ -2,10 +2,11 @@ import { configDotenv } from "dotenv"; import { drizzle } from "drizzle-orm/postgres-js"; import { migrate } from "drizzle-orm/postgres-js/migrator"; import postgres from "postgres"; +import appEnv from "../appEnv"; configDotenv(); -const dbUrl = process.env.DATABASE_URL; +const dbUrl = appEnv.DATABASE_URL; if (!dbUrl) throw new Error("DATABASE_URL is not set"); diff --git a/apps/backend/src/index.ts b/apps/backend/src/index.ts index bfc9bf2..c0fbe56 100644 --- a/apps/backend/src/index.ts +++ b/apps/backend/src/index.ts @@ -14,6 +14,7 @@ import { logger } from "hono/logger"; import DashboardError from "./errors/DashboardError"; import HonoEnv from "./types/HonoEnv"; import devRoutes from "./routes/dev/route"; +import appEnv from "./appEnv"; configDotenv(); @@ -27,7 +28,7 @@ const routes = app }) ) .use(async (c, next) => { - const cookieSecret = process.env.COOKIE_SECRET; + const cookieSecret = appEnv.COOKIE_SECRET; if (!cookieSecret) throw new HTTPException(500, { @@ -108,7 +109,7 @@ const routes = app } }); -const port = +(process.env.APP_PORT ?? 3000); +const port = appEnv.APP_PORT; console.log(`Server is running on port ${port}`); serve({ diff --git a/apps/backend/src/routes/auth/route.ts b/apps/backend/src/routes/auth/route.ts index 9fe4820..89b1405 100644 --- a/apps/backend/src/routes/auth/route.ts +++ b/apps/backend/src/routes/auth/route.ts @@ -21,6 +21,7 @@ import { permissionsSchema } from "../../drizzle/schema/permissions"; import { SpecificPermissionCode } from "../../data/permissions"; import authInfo from "../../middlewares/authInfo"; import { unauthorized } from "../../errors/DashboardError"; +import appEnv from "../../appEnv"; const authRoutes = new Hono() .post( @@ -98,7 +99,7 @@ const authRoutes = new Hono() uid: user[0].users.id, }); - const cookieSecret = process.env.COOKIE_SECRET; + const cookieSecret = appEnv.COOKIE_SECRET; if (!cookieSecret) throw new HTTPException(500, { diff --git a/apps/backend/src/utils/authUtils.ts b/apps/backend/src/utils/authUtils.ts index d45e74a..99019f4 100644 --- a/apps/backend/src/utils/authUtils.ts +++ b/apps/backend/src/utils/authUtils.ts @@ -1,10 +1,9 @@ import jwt from "jsonwebtoken"; +import appEnv from "../appEnv"; // Environment variables for secrets, defaulting to a random secret if not set. -const accessTokenSecret = - process.env.ACCESS_TOKEN_SECRET ?? "some-random-secret"; -const refreshTokenSecret = - process.env.REFRESH_TOKEN_SECRET ?? "some-very-random-secret"; +const accessTokenSecret = appEnv.ACCESS_TOKEN_SECRET; +const refreshTokenSecret = appEnv.REFRESH_TOKEN_SECRET; // Algorithm to be used for JWT encoding. const algorithm: jwt.Algorithm = "HS256"; diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index 3c73f74..53199e3 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -6,6 +6,9 @@ "strict": true, "types": ["node"], "jsx": "react-jsx", - "jsxImportSource": "hono/jsx" - } + "jsxImportSource": "hono/jsx", + "noEmit": true, + "skipLibCheck": true + }, + "include": ["src/**/*"] }