feat: add @tower/config package with env validation

This commit is contained in:
2026-05-27 13:43:47 +05:30
parent bc0017aafb
commit d3b48ea589
5 changed files with 102 additions and 0 deletions
+40
View File
@@ -0,0 +1,40 @@
import { validateEnv } from './index';
const validEnv = {
NODE_ENV: 'development',
DATABASE_URL: 'postgresql://tower:tower_dev@localhost:5432/tower_dev',
REDIS_URL: 'redis://localhost:6379',
JWT_SECRET: 'a_super_secret_key_that_is_at_least_32_chars_long',
} as unknown as NodeJS.ProcessEnv;
describe('validateEnv', () => {
it('returns parsed config for valid env', () => {
const result = validateEnv(validEnv);
expect(result.NODE_ENV).toBe('development');
expect(result.API_PORT).toBe(3001);
});
it('applies default API_PORT of 3001 when not set', () => {
const result = validateEnv(validEnv);
expect(result.API_PORT).toBe(3001);
});
it('throws when DATABASE_URL is missing', () => {
const { DATABASE_URL, ...withoutDb } = validEnv as Record<string, string>;
expect(() =>
validateEnv(withoutDb as unknown as NodeJS.ProcessEnv),
).toThrow('Invalid environment variables');
});
it('throws when JWT_SECRET is shorter than 32 chars', () => {
expect(() =>
validateEnv({ ...validEnv, JWT_SECRET: 'tooshort' } as unknown as NodeJS.ProcessEnv),
).toThrow('Invalid environment variables');
});
it('throws when DATABASE_URL is not a valid URL', () => {
expect(() =>
validateEnv({ ...validEnv, DATABASE_URL: 'not-a-url' } as unknown as NodeJS.ProcessEnv),
).toThrow('Invalid environment variables');
});
});
+23
View File
@@ -0,0 +1,23 @@
import { z } from 'zod';
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
DATABASE_URL: z.string().url(),
REDIS_URL: z.string().url(),
API_PORT: z.coerce.number().default(3001),
JWT_SECRET: z.string().min(32),
MEILI_URL: z.string().url().default('http://localhost:7700'),
MEILI_MASTER_KEY: z.string().default('tower_meili_dev_key'),
LOG_LEVEL: z.enum(['trace', 'debug', 'info', 'warn', 'error']).default('info'),
});
export type Env = z.infer<typeof envSchema>;
export function validateEnv(env: NodeJS.ProcessEnv = process.env): Env {
const result = envSchema.safeParse(env);
if (!result.success) {
console.error('Invalid environment variables:', result.error.format());
throw new Error('Invalid environment variables');
}
return result.data;
}