oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.31k stars 2.69k forks source link

Set environment variables in code & custom .env for tests #6993

Open Creative-Difficulty opened 10 months ago

Creative-Difficulty commented 10 months ago

What version of Bun is running?

1.0.11+f7f6233ea

What platform is your computer?

Darwin 23.1.0 arm64 arm

What steps can reproduce the bug?

  1. Create a program, which reads from a .env file and a function, which parses the variables in the .env file:

import { randomBytes } from "node:crypto"; import { logger } from "./logger.js"; import z from 'zod';

export const envSchema = z.object({ PORT: z.coerce.number({ invalid_type_error: "The Port must be a number." }).max(65535, { message: "This port is not available for use, please reconfigure Oxygen to use a port between 1 and 65535." }).min(1, { message: "This port is not available for use, please reconfigure Oxygen to use a port between 1 and 65535." }).default(9495), JWTSECRET: z.string({ invalid_type_error: "The Secret must be string" }).min(256, { message: "Please reconfigure Oxygen to use a secret which is longer than 256 characters." }), NODE_ENV: z.enum(["development", "production", "test"]).default("development") });

export async function parseEnv(envPath: string): Promise<Zod.ZodError | void> { if(await (Bun.file(envPath)).exists() === false && process.env.NODE_ENV !== "test") { logger.error("Cannot access .env configuration file, creating a new one with default configuration..."); let defaultJWTSecret = randomBytes(512).toString("hex"); await Bun.write(envPath, # The string, with which all of the JSONWebTokens are encrypted\n# Defaults to 512 random bytes if left blank\n# WARNING: If this variable is changed all API Keys will be invalidated and you will have to reset the database (-c)\nJWTSECRET=${defaultJWTSecret}\n# Set this to valid Port (1-65535)\nPORT=9495); process.env.PORT = 9495; process.env.JWTSECRET = defaultJWTSecret; logger.info("Done!"); }

const parsedEnv = envSchema.safeParse(process.env);

if(process.env.NODE_ENV === "test" && parsedEnv.success === false) {
    return JSON.parse(parsedEnv.error.message);
}

if(parsedEnv.success === false) {
    JSON.parse(parsedEnv.error.message).forEach((errorMessage: { message: string }) => {
        // Opened issue at https://github.com/colinhacks/zod/issues/2883 (workaround implemented)
        logger.error(errorMessage.message);
        process.exit(1); 
    });
}

}

3. Create tests, which test the env parsing function:
```ts

import path from "node:path";
import { parseEnv } from "../src/lib/parseEnv.js";
import { expect, test, beforeAll } from "bun:test";
import { randomBytes } from "node:crypto";
import * as fs from "fs/promises";

const portToTest = Math.floor(Math.random() * (65535 - 1 + 1) + 1);
export const jwtSecretToTest = randomBytes(512).toString("hex");

beforeAll(async () => {
    const envFileExists = await Bun.file(path.join(process.cwd(), ".env")).exists();
    if(envFileExists) {
        await fs.rename(path.join(process.cwd(), ".env"), path.join(process.cwd(), "temp.txt"));
    }
    process.env.PORT = portToTest;
    console.log(process.env.PORT);
    console.log(portToTest);
});
  1. See that the tests don't work and settings env variables by code also doesn't.
  2. Renaming the original (production) .env file during runtime also doesn't work, beacuse the .env files are loaded before the program runs
  3. So the "solution" is to DELETE ALL OTHER .ENV FILES BEFORE RUNTIME?????????
  4. bruh pls fix, my tests won't run it's impossible to even do process.env.PORT = portToTest;????????

What is the expected behavior?

It works like in NodeJS

What do you see instead?

It doesn't work

Additional information

No response

hilja commented 10 months ago

I'm getting something similar when trying to validate env schema with zod:

Invalid env vars: {
  NODE_ENV: [ "Required" ]
}
Creative-Difficulty commented 10 months ago

@weyert @Jarred-Sumner @dylan-conway pls fix

Creative-Difficulty commented 9 months ago

@Jarred-Sumner