Skip to content

Commit

Permalink
fix: clarify some comments and rename some files in env (t3-oss#245)
Browse files Browse the repository at this point in the history
* fix: clarify some comments and rename some files in env

* fix: filenames in installer

* fix: import in next.config

* fix: import after filechange

* fix: forgotten rename

Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
  • Loading branch information
juliusmarminge and nexxeln authored Jul 24, 2022
1 parent 5b97367 commit 2048783
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 112 deletions.
12 changes: 6 additions & 6 deletions src/installers/envVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ export const envVariablesInstaller: Installer = async ({

switch (true) {
case usingAuth && usingPrisma:
envFile = "env-prisma-auth.mjs";
envFile = "auth-prisma-schema.mjs";
break;
case usingAuth:
envFile = "env-auth.mjs";
envFile = "auth-schema.mjs";
break;
case usingPrisma:
envFile = "env-prisma.mjs";
envFile = "prisma-schema.mjs";
break;
}

if (!envFile) return;

const envSchemaSrc = path.join(envAssetDir, envFile);
const envSchemaDest = path.join(projectDir, "src/env/env-schema.mjs");
const envSchemaDest = path.join(projectDir, "src/env/schema.mjs");

const envExample = path.join(projectDir, ".env-example");
const envExampleSrc = path.join(projectDir, ".env-example");
const envDest = path.join(projectDir, ".env");

await Promise.all([
fs.copy(envSchemaSrc, envSchemaDest, { overwrite: true }),
fs.rename(envExample, envDest),
fs.rename(envExampleSrc, envDest),
]);
};
33 changes: 33 additions & 0 deletions template/addons/env/auth-prisma-schema.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// @ts-check
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.
*/
export const serverSchema = z.object({
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]),
NEXTAUTH_SECRET: z.string(),
NEXTAUTH_URL: z.string().url(),
DISCORD_CLIENT_ID: z.string(),
DISCORD_CLIENT_SECRET: z.string(),
});

/**
* 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_`.
*/
export const clientSchema = z.object({
// NEXT_PUBLIC_BAR: z.string(),
});

/**
* You can't destruct `process.env` as a regular object, so you have to do
* it manually here. This is because Next.js evaluates this at build time,
* and only used environment variables are included in the build.
*/
export const clientEnv = {
// NEXT_PUBLIC_BAR: process.env.NEXT_PUBLIC_BAR,
};
31 changes: 31 additions & 0 deletions template/addons/env/auth-schema.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// @ts-check
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.
*/
export const serverSchema = z.object({
NEXTAUTH_SECRET: z.string(),
NEXTAUTH_URL: z.string().url(),
DISCORD_CLIENT_ID: z.string(),
DISCORD_CLIENT_SECRET: z.string(),
});

/**
* 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_`.
*/
export const clientSchema = z.object({
// NEXT_PUBLIC_BAR: z.string(),
});

/**
* You can't destruct `process.env` as a regular object, so you have to do
* it manually here. This is because Next.js evaluates this at build time,
* and only used environment variables are included in the build.
*/
export const clientEnv = {
// NEXT_PUBLIC_BAR: process.env.NEXT_PUBLIC_BAR,
};
25 changes: 0 additions & 25 deletions template/addons/env/env-auth.mjs

This file was deleted.

27 changes: 0 additions & 27 deletions template/addons/env/env-prisma-auth.mjs

This file was deleted.

23 changes: 0 additions & 23 deletions template/addons/env/env-prisma.mjs

This file was deleted.

29 changes: 29 additions & 0 deletions template/addons/env/prisma-schema.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @ts-check
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.
*/
export const serverSchema = z.object({
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(["development", "test", "production"]),
});

/**
* 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_`.
*/
export const clientSchema = z.object({
// NEXT_PUBLIC_BAR: z.string(),
});

/**
* You can't destruct `process.env` as a regular object, so you have to do
* it manually here. This is because Next.js evaluates this at build time,
* and only used environment variables are included in the build.
*/
export const clientEnv = {
// NEXT_PUBLIC_BAR: process.env.NEXT_PUBLIC_BAR,
};
2 changes: 1 addition & 1 deletion template/addons/next-auth/api-handler-prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import DiscordProvider from "next-auth/providers/discord";
// Prisma adapter for NextAuth, optional and can be removed
import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { prisma } from "../../../server/db/client";
import { env } from "../../../env/server-env.mjs";
import { env } from "../../../env/server.mjs";

export const authOptions: NextAuthOptions = {
// Include user.id on session
Expand Down
2 changes: 1 addition & 1 deletion template/addons/next-auth/api-handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import NextAuth, { type NextAuthOptions } from "next-auth";
import DiscordProvider from "next-auth/providers/discord";
import { env } from "../../../env/server-env.mjs";
import { env } from "../../../env/server.mjs";

export const authOptions: NextAuthOptions = {
// Include user.id on session
Expand Down
2 changes: 1 addition & 1 deletion template/addons/prisma/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// src/server/db/client.ts
import { PrismaClient } from "@prisma/client";
import { env } from "../../env/server-env.mjs";
import { env } from "../../env/server.mjs";

declare global {
var prisma: PrismaClient | undefined;
Expand Down
2 changes: 1 addition & 1 deletion template/base/next.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { env } from "./src/env/server-env.mjs";
import { env } from "./src/env/server.mjs";

/**
* Don't be scared of the generics here.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-check
import { clientEnv, clientEnvSchema } from "./env-schema.mjs";
import { clientEnv, clientSchema } from "./schema.mjs";

const _clientEnv = clientEnvSchema.safeParse(clientEnv);
const _clientEnv = clientSchema.safeParse(clientEnv);

export const formatErrors = (
/** @type {import('zod').ZodFormattedError<Map<string,string>,string>} */
Expand All @@ -22,6 +22,9 @@ if (!_clientEnv.success) {
throw new Error("Invalid environment variables");
}

/**
* Validate that client-side environment variables are exposed to the client.
*/
for (let key of Object.keys(_clientEnv.data)) {
if (!key.startsWith("NEXT_PUBLIC_")) {
console.warn("❌ Invalid public environment variable name:", key);
Expand Down
22 changes: 0 additions & 22 deletions template/base/src/env/env-schema.mjs

This file was deleted.

28 changes: 28 additions & 0 deletions template/base/src/env/schema.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// @ts-check
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.
*/
export const serverSchema = z.object({
// FOO: z.string(),
});

/**
* 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_`.
*/
export const clientSchema = z.object({
// NEXT_PUBLIC_BAR: z.string(),
});

/**
* You can't destruct `process.env` as a regular object, so you have to do
* it manually here. This is because Next.js evaluates this at build time,
* and only used environment variables are included in the build.
*/
export const clientEnv = {
// NEXT_PUBLIC_BAR: process.env.NEXT_PUBLIC_BAR,
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* This file is included in `/next.config.mjs` which ensures the app isn't built with invalid env vars.
* It has to be a `.mjs`-file to be imported there.
*/
import { serverEnvSchema } from "./env-schema.mjs";
import { env as clientEnv, formatErrors } from "./client-env.mjs";
import { serverSchema } from "./schema.mjs";
import { env as clientEnv, formatErrors } from "./client.mjs";

const _serverEnv = serverEnvSchema.safeParse(process.env);
const _serverEnv = serverSchema.safeParse(process.env);

if (!_serverEnv.success) {
console.error(
Expand All @@ -16,6 +16,9 @@ if (!_serverEnv.success) {
throw new Error("Invalid environment variables");
}

/**
* Validate that server-side environment variables are not exposed to the client.
*/
for (let key of Object.keys(_serverEnv.data)) {
if (key.startsWith("NEXT_PUBLIC_")) {
console.warn("❌ You are exposing a server-side env-variable:", key);
Expand Down

0 comments on commit 2048783

Please sign in to comment.