diff --git a/package.json b/package.json index a73bb34..1bb5326 100644 --- a/package.json +++ b/package.json @@ -10,13 +10,15 @@ "fmt": "dprint fmt src/**/*.{ts,tsx}" }, "dependencies": { + "@t3-oss/env-nextjs": "^0.13.8", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.523.0", "next": "15.3.4", "react": "^19.0.0", "react-dom": "^19.0.0", - "tailwind-merge": "^3.3.1" + "tailwind-merge": "^3.3.1", + "zod": "^3.25.67" }, "devDependencies": { "@eslint/eslintrc": "^3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8863872..2e952a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@t3-oss/env-nextjs': + specifier: ^0.13.8 + version: 0.13.8(typescript@5.8.3)(zod@3.25.67) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -29,6 +32,9 @@ importers: tailwind-merge: specifier: ^3.3.1 version: 3.3.1 + zod: + specifier: ^3.25.67 + version: 3.25.67 devDependencies: '@eslint/eslintrc': specifier: ^3 @@ -365,6 +371,40 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@t3-oss/env-core@0.13.8': + resolution: {integrity: sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw==} + peerDependencies: + arktype: ^2.1.0 + typescript: '>=5.0.0' + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0-beta.0 + peerDependenciesMeta: + arktype: + optional: true + typescript: + optional: true + valibot: + optional: true + zod: + optional: true + + '@t3-oss/env-nextjs@0.13.8': + resolution: {integrity: sha512-QmTLnsdQJ8BiQad2W2nvV6oUpH4oMZMqnFEjhVpzU0h3sI9hn8zb8crjWJ1Amq453mGZs6A4v4ihIeBFDOrLeQ==} + peerDependencies: + arktype: ^2.1.0 + typescript: '>=5.0.0' + valibot: ^1.0.0-beta.7 || ^1.0.0 + zod: ^3.24.0 || ^4.0.0-beta.0 + peerDependenciesMeta: + arktype: + optional: true + typescript: + optional: true + valibot: + optional: true + zod: + optional: true + '@tailwindcss/node@4.1.10': resolution: {integrity: sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==} @@ -1844,6 +1884,9 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zod@3.25.67: + resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -2093,6 +2136,18 @@ snapshots: dependencies: tslib: 2.8.1 + '@t3-oss/env-core@0.13.8(typescript@5.8.3)(zod@3.25.67)': + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.67 + + '@t3-oss/env-nextjs@0.13.8(typescript@5.8.3)(zod@3.25.67)': + dependencies: + '@t3-oss/env-core': 0.13.8(typescript@5.8.3)(zod@3.25.67) + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.67 + '@tailwindcss/node@4.1.10': dependencies: '@ampproject/remapping': 2.3.0 @@ -3842,3 +3897,5 @@ snapshots: yallist@5.0.0: {} yocto-queue@0.1.0: {} + + zod@3.25.67: {} diff --git a/src/lib/env/client.ts b/src/lib/env/client.ts new file mode 100644 index 0000000..45b1480 --- /dev/null +++ b/src/lib/env/client.ts @@ -0,0 +1,12 @@ +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + client: { + NEXT_PUBLIC_BASE_URL: z.string().url(), + }, + runtimeEnv: { + NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL, + }, + emptyStringAsUndefined: true, +}); diff --git a/src/lib/env/server.ts b/src/lib/env/server.ts new file mode 100644 index 0000000..fd22c21 --- /dev/null +++ b/src/lib/env/server.ts @@ -0,0 +1,24 @@ +import { createEnv } from "@t3-oss/env-nextjs"; +import { z } from "zod"; + +export const env = createEnv({ + server: { + PG_USER: z.string().min(1), + PG_PASSWORD: z.string().min(1), + PG_HOST: z.string().min(1), + PG_PORT: z.string().min(1), + PG_DATABASE: z.string().min(1), + }, + createFinalSchema: (schema) => { + return z.object(schema).transform(s => { + const { PG_USER, PG_PASSWORD, PG_HOST, PG_PORT, PG_DATABASE, ...other } = s + + return { + ...other, + DATABASE_URL: `postgres://${PG_USER}:${PG_PASSWORD}@${PG_HOST}:${PG_PORT}/${PG_DATABASE}`, + }; + }) + }, + experimental__runtimeEnv: process.env, + emptyStringAsUndefined: true, +});