Switched to t3-env to manage environment vars

This commit is contained in:
Atridad Lahiji 2023-08-31 12:46:46 -06:00
parent e0f638ef93
commit 17854b4ad4
No known key found for this signature in database
3 changed files with 54 additions and 102 deletions

View file

@ -18,6 +18,7 @@
"@neondatabase/serverless": "^0.6.0",
"@paralleldrive/cuid2": "^2.2.2",
"@react-email/components": "^0.0.7",
"@t3-oss/env-nextjs": "^0.6.1",
"@tanstack/react-query": "^4.33.0",
"@trpc/client": "10.38.1",
"@trpc/next": "10.38.1",

31
pnpm-lock.yaml generated
View file

@ -20,6 +20,9 @@ dependencies:
'@react-email/components':
specifier: ^0.0.7
version: 0.0.7
'@t3-oss/env-nextjs':
specifier: ^0.6.1
version: 0.6.1(typescript@5.2.2)(zod@3.22.2)
'@tanstack/react-query':
specifier: ^4.33.0
version: 4.33.0(react-dom@18.2.0)(react@18.2.0)
@ -1293,6 +1296,27 @@ packages:
defer-to-connect: 2.0.1
dev: false
/@t3-oss/env-core@0.6.1(typescript@5.2.2)(zod@3.22.2):
resolution: {integrity: sha512-KQD7qEDJtkWIWWmTVjNvk0wnHpkvAQ6CRbUxbWMFNG/fiosBQDQvtRpBNu6USxBscJCoC4z6y7P9MN52/mLOzw==}
peerDependencies:
typescript: '>=4.7.2'
zod: ^3.0.0
dependencies:
typescript: 5.2.2
zod: 3.22.2
dev: false
/@t3-oss/env-nextjs@0.6.1(typescript@5.2.2)(zod@3.22.2):
resolution: {integrity: sha512-z1dIC++Vxj9kmzX5nSPfcrCSkszy3dTEPC4Ssx7Ap5AqR3c2Qa7S0xf8axn6coy7D/vCXDAAnHYnCMDhtcY3SQ==}
peerDependencies:
typescript: '>=4.7.2'
zod: ^3.0.0
dependencies:
'@t3-oss/env-core': 0.6.1(typescript@5.2.2)(zod@3.22.2)
typescript: 5.2.2
zod: 3.22.2
dev: false
/@tanstack/query-core@4.33.0:
resolution: {integrity: sha512-qYu73ptvnzRh6se2nyBIDHGBQvPY1XXl3yR769B7B6mIDD7s+EZhdlWHQ67JI6UOTFRaI7wupnTnwJ3gE0Mr/g==}
dev: false
@ -1919,7 +1943,7 @@ packages:
dependencies:
browserslist: 4.21.10
caniuse-lite: 1.0.30001525
fraction.js: 4.3.2
fraction.js: 4.3.4
normalize-range: 0.1.2
picocolors: 1.0.0
postcss: 8.4.29
@ -3328,8 +3352,8 @@ packages:
mime-types: 2.1.35
dev: false
/fraction.js@4.3.2:
resolution: {integrity: sha512-9VLF466MqX1OUP7/d9r7/Vsvu6Hpp+taXBLmiR5x6mEYfT0BDkGVBt5TyA1aDu1WzIE1sF8F66evOFaz7iAEGQ==}
/fraction.js@4.3.4:
resolution: {integrity: sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==}
dev: false
/fs-constants@1.0.0:
@ -5863,7 +5887,6 @@ packages:
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
/unbox-primitive@1.0.2:
resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}

View file

@ -1,101 +1,29 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
/**
* Specify your server-side environment variables schema here. This way you can ensure the app isn't
* built with invalid env vars.
*/
const server = z.object({
DATABASE_URL: z.string().url(),
UPSTASH_REDIS_REST_URL: z.string().url(),
UPSTASH_REDIS_REST_TOKEN: z.string(),
UPSTASH_REDIS_EXPIRY_SECONDS: z.string(),
UPSTASH_RATELIMIT_REQUESTS: z.string(),
UPSTASH_RATELIMIT_SECONDS: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
ABLY_PRIVATE_KEY: z.string(),
APP_ENV: z.string(),
RESEND_API_KEY: z.string(),
UNKEY_ROOT_KEY: z.string(),
CLERK_SECRET_KEY: z.string(),
export const env = createEnv({
server: {
DATABASE_URL: z.string().url(),
UPSTASH_REDIS_REST_URL: z.string().url(),
UPSTASH_REDIS_REST_TOKEN: z.string(),
UPSTASH_REDIS_EXPIRY_SECONDS: z.string(),
UPSTASH_RATELIMIT_REQUESTS: z.string(),
UPSTASH_RATELIMIT_SECONDS: z.string(),
NODE_ENV: z.enum(["development", "test", "production"]),
ABLY_PRIVATE_KEY: z.string(),
APP_ENV: z.string(),
UNKEY_ROOT_KEY: z.string(),
CLERK_SECRET_KEY: z.string(),
},
client: {
NEXT_PUBLIC_ABLY_PUBLIC_KEY: z.string(),
NEXT_PUBLIC_APP_ENV: z.string(),
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(),
},
experimental__runtimeEnv: {
NEXT_PUBLIC_ABLY_PUBLIC_KEY: process.env.NEXT_PUBLIC_ABLY_PUBLIC_KEY,
NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV,
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
},
});
/**
* Specify your client-side environment variables schema here. This way you can ensure the app isn't
* built with invalid env vars. To expose them to the client, prefix them with `NEXT_PUBLIC_`.
*/
const client = z.object({
NEXT_PUBLIC_ABLY_PUBLIC_KEY: z.string(),
NEXT_PUBLIC_APP_ENV: z.string(),
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(),
});
/**
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
* middlewares) or client-side so we need to destruct manually.
*
* @type {Record<keyof z.infer<typeof server> | keyof z.infer<typeof client>, string | undefined>}
*/
const processEnv = {
DATABASE_URL: process.env.DATABASE_URL,
UPSTASH_REDIS_REST_URL: process.env.UPSTASH_REDIS_REST_URL,
UPSTASH_REDIS_REST_TOKEN: process.env.UPSTASH_REDIS_REST_TOKEN,
UPSTASH_REDIS_EXPIRY_SECONDS: process.env.UPSTASH_REDIS_EXPIRY_SECONDS,
UPSTASH_RATELIMIT_REQUESTS: process.env.UPSTASH_RATELIMIT_REQUESTS,
UPSTASH_RATELIMIT_SECONDS: process.env.UPSTASH_RATELIMIT_SECONDS,
NODE_ENV: process.env.NODE_ENV,
ABLY_PRIVATE_KEY: process.env.ABLY_PRIVATE_KEY,
NEXT_PUBLIC_ABLY_PUBLIC_KEY: process.env.NEXT_PUBLIC_ABLY_PUBLIC_KEY,
APP_ENV: process.env.APP_ENV,
NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV,
RESEND_API_KEY: process.env.RESEND_API_KEY,
UNKEY_ROOT_KEY: process.env.UNKEY_ROOT_KEY,
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY,
};
// Don't touch the part below
// --------------------------
const merged = server.merge(client);
/** @typedef {z.input<typeof merged>} MergedInput */
/** @typedef {z.infer<typeof merged>} MergedOutput */
/** @typedef {z.SafeParseReturnType<MergedInput, MergedOutput>} MergedSafeParseReturn */
let env = /** @type {MergedOutput} */ (process.env);
if (!!process.env.SKIP_ENV_VALIDATION == false) {
const isServer = typeof window === "undefined";
const parsed = /** @type {MergedSafeParseReturn} */ (
isServer
? merged.safeParse(processEnv) // on server we can validate all env vars
: client.safeParse(processEnv) // on client we can only validate the ones that are exposed
);
if (parsed.success === false) {
console.error(
"❌ Invalid environment variables:",
parsed.error.flatten().fieldErrors
);
throw new Error("Invalid environment variables");
}
env = new Proxy(parsed.data, {
get(target, prop) {
if (typeof prop !== "string") return undefined;
// Throw a descriptive error if a server-side env var is accessed on the client
// Otherwise it would just be returning `undefined` and be annoying to debug
if (!isServer && !prop.startsWith("NEXT_PUBLIC_"))
throw new Error(
process.env.NODE_ENV === "production"
? "❌ Attempted to access a server-side environment variable on the client"
: `❌ Attempted to access server-side environment variable '${prop}' on the client`
);
return target[/** @type {keyof typeof target} */ (prop)];
},
});
}
export { env };