fix: env names from prod to production
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Committed development defaults. Override them in an ignored .env.dev,
|
||||
# .env.test, .env.prod, or .env.local file.
|
||||
NODE_ENV=dev
|
||||
NODE_ENV=development
|
||||
|
||||
# API
|
||||
BASANGO_API_HOST=127.0.0.1
|
||||
|
||||
@@ -33,7 +33,7 @@ db-rebuild: ## Rebuild the local PostgreSQL database and run migrations
|
||||
deploy: ## Install, build, migrate, and reload the production applications
|
||||
$(BUN) install --frozen-lockfile
|
||||
$(BUN) run build:dashboard
|
||||
NODE_ENV=prod $(BUN) run migrate
|
||||
NODE_ENV=production $(BUN) run migrate
|
||||
$(PM2) startOrReload ecosystem.config.js
|
||||
$(PM2) save
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"auth:create-admin": "bun run src/scripts/create-admin.ts",
|
||||
"dev": "NODE_ENV=dev bun run --hot src/index.ts",
|
||||
"start": "NODE_ENV=prod bun run src/index.ts",
|
||||
"dev": "NODE_ENV=development bun run --hot src/index.ts",
|
||||
"start": "NODE_ENV=production bun run src/index.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"type": "module"
|
||||
|
||||
@@ -9,7 +9,7 @@ import { v7 as uuidv7 } from "uuid";
|
||||
|
||||
import { sendPasswordResetEmail } from "#api/utils/password-reset-email";
|
||||
|
||||
const isProduction = env.NODE_ENV === "prod";
|
||||
const isProduction = env.NODE_ENV === "production";
|
||||
const baseURL = env.BETTER_AUTH_URL?.trim() ?? `http://localhost:${config.api.server.port}`;
|
||||
const cookieDomain = env.BETTER_AUTH_COOKIE_DOMAIN?.trim();
|
||||
const secret =
|
||||
|
||||
@@ -25,7 +25,7 @@ export async function sendPasswordResetEmail(input: PasswordResetEmail): Promise
|
||||
const apiKey = env.BASANGO_RESEND_API_KEY?.trim();
|
||||
|
||||
if (!apiKey) {
|
||||
if (env.NODE_ENV === "prod") {
|
||||
if (env.NODE_ENV === "production") {
|
||||
throw new Error("BASANGO_RESEND_API_KEY is required to send password reset emails.");
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
"name": "@basango/dashboard",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vite build --mode prod",
|
||||
"build": "vite build --mode production",
|
||||
"clean": "rm -rf .output .tanstack node_modules",
|
||||
"dev": "vite dev --mode dev",
|
||||
"start": "NODE_ENV=prod node .output/server/index.mjs",
|
||||
"dev": "vite dev --mode development",
|
||||
"start": "NODE_ENV=production node .output/server/index.mjs",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"type": "module"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { normalizeNodeEnvironment, readEnvFiles } from "@basango/domain/config/environment";
|
||||
import { readEnvFiles } from "@basango/domain/config/environment";
|
||||
import tailwindcss from "@tailwindcss/vite";
|
||||
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
||||
import viteReact from "@vitejs/plugin-react";
|
||||
@@ -6,13 +6,9 @@ import { nitro } from "nitro/vite";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
const nodeEnvironment = normalizeNodeEnvironment(mode);
|
||||
applyPublicEnvironment(nodeEnvironment);
|
||||
applyPublicEnvironment(mode);
|
||||
|
||||
return {
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(nodeEnvironment),
|
||||
},
|
||||
envDir: false,
|
||||
plugins: [
|
||||
tanstackStart({
|
||||
|
||||
+4
-4
@@ -16,9 +16,9 @@ Environment files are loaded from lowest to highest priority:
|
||||
Only `.env` is committed. Every `.env.*` file is ignored by Git. Never put production credentials
|
||||
or personal secrets in `.env`.
|
||||
|
||||
`NODE_ENV` accepts exactly `dev`, `test`, or `prod`, selecting `.env.dev`, `.env.test`, or
|
||||
`.env.prod` respectively. The longer `development` and `production` values are intentionally
|
||||
rejected so every TypeScript application uses the same vocabulary.
|
||||
`NODE_ENV` accepts exactly `development`, `test`, or `production`. These select `.env.dev`,
|
||||
`.env.test`, or `.env.prod` respectively. The file suffixes stay concise while `NODE_ENV` follows
|
||||
the values expected by Node.js and React tooling.
|
||||
|
||||
The API, Drizzle commands, and dashboard build share this ordering. The dashboard exposes only
|
||||
variables prefixed with `VITE_` to browser code. If the mobile application gains public runtime
|
||||
@@ -38,7 +38,7 @@ superseded by `.env.local`.
|
||||
|
||||
## Production
|
||||
|
||||
On the server, set `NODE_ENV=prod` and create `.env.prod` for production-wide values. Put
|
||||
On the server, set `NODE_ENV=production` and create `.env.prod` for production-wide values. Put
|
||||
host-specific credentials in `.env.local`. For example:
|
||||
|
||||
```dotenv
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ module.exports = {
|
||||
env: {
|
||||
BASANGO_API_HOST: "127.0.0.1",
|
||||
BASANGO_API_PORT: "3080",
|
||||
NODE_ENV: "prod",
|
||||
NODE_ENV: "production",
|
||||
},
|
||||
max_restarts: 5,
|
||||
name: "api.basango.ngandu.dev",
|
||||
@@ -22,7 +22,7 @@ module.exports = {
|
||||
cwd: path.join(__dirname, "apps", "dashboard"),
|
||||
env: {
|
||||
HOST: "127.0.0.1",
|
||||
NODE_ENV: "prod",
|
||||
NODE_ENV: "production",
|
||||
PORT: "3001",
|
||||
VITE_PUBLIC_API_URL: "https://api.basango.ngandu.dev",
|
||||
VITE_PUBLIC_URL: "https://dashboard.basango.ngandu.dev",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Pool } from "pg";
|
||||
|
||||
import * as schema from "#db/schema";
|
||||
|
||||
const isDevelopment = env.NODE_ENV === "dev";
|
||||
const isDevelopment = env.NODE_ENV === "development";
|
||||
|
||||
const pool = new Pool({
|
||||
allowExitOnIdle: true,
|
||||
|
||||
@@ -15,14 +15,14 @@ afterEach(() => {
|
||||
|
||||
describe("normalizeNodeEnvironment", () => {
|
||||
test.each([
|
||||
["dev", "dev"],
|
||||
["development", "development"],
|
||||
["test", "test"],
|
||||
["prod", "prod"],
|
||||
["production", "production"],
|
||||
] as const)("normalizes %s to %s", (value, expected) => {
|
||||
expect(normalizeNodeEnvironment(value)).toBe(expected);
|
||||
});
|
||||
|
||||
test.each(["development", "production"])("rejects unsupported value %s", (value) => {
|
||||
test.each(["dev", "prod"])("rejects unsupported value %s", (value) => {
|
||||
expect(() => normalizeNodeEnvironment(value)).toThrow(`Unsupported NODE_ENV: ${value}`);
|
||||
});
|
||||
});
|
||||
@@ -35,7 +35,7 @@ describe("environment files", () => {
|
||||
".env.prod": "VALUE=production\nMODE_ONLY=yes\n",
|
||||
});
|
||||
|
||||
expect(readEnvFiles({ cwd: directory, nodeEnvironment: "prod" })).toEqual({
|
||||
expect(readEnvFiles({ cwd: directory, nodeEnvironment: "production" })).toEqual({
|
||||
BASE_ONLY: "yes",
|
||||
LOCAL_ONLY: "yes",
|
||||
MODE_ONLY: "yes",
|
||||
@@ -44,9 +44,9 @@ describe("environment files", () => {
|
||||
});
|
||||
|
||||
test.each([
|
||||
["dev", ".env.dev"],
|
||||
["development", ".env.dev"],
|
||||
["test", ".env.test"],
|
||||
["prod", ".env.prod"],
|
||||
["production", ".env.prod"],
|
||||
] as const)("selects %s mode file", (mode, expectedFile) => {
|
||||
const directory = createEnvironmentDirectory({ ".env": "VALUE=base\n" });
|
||||
const files = resolveEnvFiles({ cwd: directory, nodeEnvironment: mode });
|
||||
@@ -60,7 +60,7 @@ describe("environment files", () => {
|
||||
|
||||
test("uses NODE_ENV from the base file when no mode is provided", () => {
|
||||
const directory = createEnvironmentDirectory({
|
||||
".env": "NODE_ENV=prod\nVALUE=base\n",
|
||||
".env": "NODE_ENV=production\nVALUE=base\n",
|
||||
".env.prod": "VALUE=production\n",
|
||||
});
|
||||
const previousNodeEnvironment = process.env.NODE_ENV;
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { parseEnv } from "node:util";
|
||||
|
||||
export type NodeEnvironment = "dev" | "test" | "prod";
|
||||
export type NodeEnvironment = "development" | "test" | "production";
|
||||
|
||||
export interface EnvironmentFileOptions {
|
||||
cwd?: string;
|
||||
@@ -15,16 +15,22 @@ interface EnvironmentFile {
|
||||
path: string;
|
||||
}
|
||||
|
||||
const environmentFileSuffixes: Record<NodeEnvironment, string> = {
|
||||
development: "dev",
|
||||
production: "prod",
|
||||
test: "test",
|
||||
};
|
||||
|
||||
export function normalizeNodeEnvironment(value?: string): NodeEnvironment {
|
||||
switch (value?.trim().toLowerCase()) {
|
||||
case undefined:
|
||||
case "":
|
||||
case "dev":
|
||||
return "dev";
|
||||
case "development":
|
||||
return "development";
|
||||
case "test":
|
||||
return "test";
|
||||
case "prod":
|
||||
return "prod";
|
||||
case "production":
|
||||
return "production";
|
||||
default:
|
||||
throw new Error(`Unsupported NODE_ENV: ${value}`);
|
||||
}
|
||||
@@ -60,7 +66,7 @@ export function resolveEnvFiles(options: EnvironmentFileOptions = {}): Environme
|
||||
const directory = path.dirname(envPath);
|
||||
const paths = [
|
||||
envPath,
|
||||
path.join(directory, `.env.${nodeEnvironment}`),
|
||||
path.join(directory, `.env.${environmentFileSuffixes[nodeEnvironment]}`),
|
||||
path.join(directory, ".env.local"),
|
||||
];
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ export * from "./encryption";
|
||||
export * from "./logger";
|
||||
export * from "./shared";
|
||||
|
||||
const nodeEnvironmentSchema = z.enum(["dev", "test", "prod"]).default("dev");
|
||||
const nodeEnvironmentSchema = z.enum(["development", "test", "production"]).default("development");
|
||||
|
||||
export const { env, config } = await defineConfig({
|
||||
cwd: fileURLToPath(new URL("../..", import.meta.url)),
|
||||
|
||||
@@ -98,7 +98,7 @@ const createPinoLogger = (): LoggerLike => {
|
||||
|
||||
return createLogger({
|
||||
level: config.logger.level,
|
||||
...(env.NODE_ENV !== "prod" &&
|
||||
...(env.NODE_ENV !== "production" &&
|
||||
env.BASANGO_LOGGER_PRETTY === "true" && {
|
||||
transport: {
|
||||
options: {
|
||||
|
||||
Reference in New Issue
Block a user