Can't set env variables in package.json scripts?

So essentially I'm trying to run some test scripts (playwright for example) and I want to assign an env var like APP_ENV=test or something like that when I do, this way I can swap the database to a local testing db src/server/db/index.ts 1:
import * as schema from "./schema";
import { sql } from "@vercel/postgres";
import postgres from "postgres";
import {
drizzle as VercelDrizzle,
type VercelPgClient,
type VercelPgDatabase,
} from "drizzle-orm/vercel-postgres";
import {
drizzle as LocalDrizzle,
type PostgresJsDatabase,
} from "drizzle-orm/postgres-js";
import { env } from "@/env";

// https://www.thisdot.co/blog/configure-your-project-with-drizzle-for-local-and-deployed-databases
// Reconfigured for test (local) and production (vercel+supabase) databases following this guide as a baseline

// Define a type that represents the structure of the database schema.
type MySchema = typeof schema;

// Define a variable 'db' that can be either a VercelPgDatabase or a PostgresJsDatabase,
// both typed with the schema structure.
let db: VercelPgDatabase<MySchema> | PostgresJsDatabase<MySchema>;

console.log("NODE_ENV: ", process.env.NODE_ENV);
// This shows that playwright tests are coming through as NODE_ENV=development
console.log("APP_ENV: ", process.env.APP_ENV);
console.log("ENVIRONMENT: ", process.env.ENVIRONMENT);

// Check custom APP_ENV variable to determine which database to use
// This can be refactored later to separate production and development if necessary
if (process.env.APP_ENV === "test") {
// In the test environment, use a local Postgres database.
// The TEST_DATABASE_URL environment variable should contain the connection string.
const migrationClient = postgres(process.env.TEST_DATABASE_URL!); // removed 'as string' from end
// Initialize the database with the local Postgres client and the defined schema.
db = LocalDrizzle(migrationClient, { schema });
//db = LocalDrizzle(migrationClient);
console.log("Using Local Postgres for Testing");
} else {
// In production or development, use Vercel Postgres with the defined schema.
db = VercelDrizzle(sql as VercelPgClient, { schema });
//db = VercelDrizzle(sql);
console.log("Using Vercel Postgres (supabase)");
}
import * as schema from "./schema";
import { sql } from "@vercel/postgres";
import postgres from "postgres";
import {
drizzle as VercelDrizzle,
type VercelPgClient,
type VercelPgDatabase,
} from "drizzle-orm/vercel-postgres";
import {
drizzle as LocalDrizzle,
type PostgresJsDatabase,
} from "drizzle-orm/postgres-js";
import { env } from "@/env";

// https://www.thisdot.co/blog/configure-your-project-with-drizzle-for-local-and-deployed-databases
// Reconfigured for test (local) and production (vercel+supabase) databases following this guide as a baseline

// Define a type that represents the structure of the database schema.
type MySchema = typeof schema;

// Define a variable 'db' that can be either a VercelPgDatabase or a PostgresJsDatabase,
// both typed with the schema structure.
let db: VercelPgDatabase<MySchema> | PostgresJsDatabase<MySchema>;

console.log("NODE_ENV: ", process.env.NODE_ENV);
// This shows that playwright tests are coming through as NODE_ENV=development
console.log("APP_ENV: ", process.env.APP_ENV);
console.log("ENVIRONMENT: ", process.env.ENVIRONMENT);

// Check custom APP_ENV variable to determine which database to use
// This can be refactored later to separate production and development if necessary
if (process.env.APP_ENV === "test") {
// In the test environment, use a local Postgres database.
// The TEST_DATABASE_URL environment variable should contain the connection string.
const migrationClient = postgres(process.env.TEST_DATABASE_URL!); // removed 'as string' from end
// Initialize the database with the local Postgres client and the defined schema.
db = LocalDrizzle(migrationClient, { schema });
//db = LocalDrizzle(migrationClient);
console.log("Using Local Postgres for Testing");
} else {
// In production or development, use Vercel Postgres with the defined schema.
db = VercelDrizzle(sql as VercelPgClient, { schema });
//db = VercelDrizzle(sql);
console.log("Using Vercel Postgres (supabase)");
}
I've seen several instances as I've been googling of people simply adding things to scripts like:
"scripts": {
"test": "APP_ENV=test ENVIRONMENT=test playwright test",
}
"scripts": {
"test": "APP_ENV=test ENVIRONMENT=test playwright test",
}
Example: https://stackoverflow.com/a/77810676/630988 But for some reason when I try and do this it doesn't work, my log results always show undefined as well if I don't have something pre-set in .env, and when something is pre set it never changes to test. Note: I should mention I'm using Mac OSX, and I've also tried using cross-env and that also didn't work. So I'm not sure if the src/env.js file has something to do with this, but I've tried adding stuff in there as well and had no difference in results. I'm also not entirely sure how I could use that SKIP_ENV_VALIDATION or if it would even help. https://github.com/t3-oss/t3-env
Stack Overflow
How to have both production and test databases in Drizzle ORM?
I'm developing an application with Drizzle ORM (pg). I would like to have two identical databases (or schemas)? One for testing/development/debugging and another for production. What is the best...
GitHub
GitHub - t3-oss/t3-env
Contribute to t3-oss/t3-env development by creating an account on GitHub.
1 Reply
hopesix
hopesix4mo ago
src/env.js 1:
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars.
*/
server: {
DATABASE_URL: z
.string()
.url()
.refine(
(str) => !str.includes("YOUR_PSQL_URL_HERE"),
"You forgot to change the default URL",
),
TEST_DATABASE_URL: z
.string()
.url()
.refine(
(str) => !str.includes("YOUR_TEST_PSQL_URL_HERE"),
"You forgot to change the test URL",
),
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
// APP_ENV: z.string(),
// ENVIRONMENT: 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_`.
*/
client: {
// NEXT_PUBLIC_CLIENTVAR: 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.
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
TEST_DATABASE_URL: process.env.TEST_DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
// APP_ENV: process.env.APP_ENV,
// ENVIRONMENT: process.env.ENVIRONMENT,
// NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
* useful for Docker builds.
*/
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
/**
* Makes it so that empty strings are treated as undefined.
* `SOME_VAR: z.string()` and `SOME_VAR=''` will throw an error.
*/
emptyStringAsUndefined: true,
});
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
/**
* Specify your server-side environment variables schema here. This way you can ensure the app
* isn't built with invalid env vars.
*/
server: {
DATABASE_URL: z
.string()
.url()
.refine(
(str) => !str.includes("YOUR_PSQL_URL_HERE"),
"You forgot to change the default URL",
),
TEST_DATABASE_URL: z
.string()
.url()
.refine(
(str) => !str.includes("YOUR_TEST_PSQL_URL_HERE"),
"You forgot to change the test URL",
),
NODE_ENV: z
.enum(["development", "test", "production"])
.default("development"),
// APP_ENV: z.string(),
// ENVIRONMENT: 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_`.
*/
client: {
// NEXT_PUBLIC_CLIENTVAR: 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.
*/
runtimeEnv: {
DATABASE_URL: process.env.DATABASE_URL,
TEST_DATABASE_URL: process.env.TEST_DATABASE_URL,
NODE_ENV: process.env.NODE_ENV,
// APP_ENV: process.env.APP_ENV,
// ENVIRONMENT: process.env.ENVIRONMENT,
// NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
},
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially
* useful for Docker builds.
*/
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
/**
* Makes it so that empty strings are treated as undefined.
* `SOME_VAR: z.string()` and `SOME_VAR=''` will throw an error.
*/
emptyStringAsUndefined: true,
});