Files
warmbly/qa/lib/env.ts
T

65 lines
2.6 KiB
TypeScript

import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
export const QA_DIR = join(dirname(fileURLToPath(import.meta.url)), "..");
export const ARTIFACTS = join(QA_DIR, ".artifacts");
export const RUN_DIR = join(ARTIFACTS, "run");
export const AUTH_DIR = join(ARTIFACTS, "auth");
export const STACK_DIR = join(ARTIFACTS, "stack");
export const VIDEO = {
width: 1920,
height: 1080,
fps: Number(process.env.QA_FPS ?? 30),
crf: Number(process.env.QA_CRF ?? 18),
preset: process.env.QA_PRESET ?? "slow",
};
type StackEnv = { webURL?: string; apiURL?: string; mailpitURL?: string; email?: string; password?: string; mode?: string };
function stackEnv(): StackEnv {
const file = join(STACK_DIR, "env.json");
if (!existsSync(file)) return {};
return JSON.parse(readFileSync(file, "utf8")) as StackEnv;
}
const stack = stackEnv();
export const env = {
webURL: trimSlash(process.env.QA_WEB_URL ?? stack.webURL ?? "http://localhost:5173"),
apiURL: trimSlash(process.env.QA_API_URL ?? stack.apiURL ?? "http://localhost:8080"),
mailpitURL: trimSlash(process.env.QA_MAILPIT_URL ?? stack.mailpitURL ?? "http://localhost:18025"),
email: process.env.QA_EMAIL ?? stack.email ?? "dev@warmbly.com",
password: process.env.QA_PASSWORD ?? stack.password ?? "password123",
// "external": QA_WEB_URL names a stack the harness did not start. "none": nothing to record.
mode: process.env.QA_WEB_URL ? "external" : (stack.mode ?? "none"),
turnstile: "warmbly-local-turnstile-bypass",
};
function trimSlash(url: string): string {
return url.replace(/\/+$/, "");
}
// The repo is public and recordings are uploaded to it, so only a local stack with seed data may be recorded.
export function assertLocal(url: string): void {
const host = new URL(url).hostname;
const allowed = (process.env.QA_ALLOW_HOST ?? "").split(",").filter(Boolean);
const local = ["localhost", "127.0.0.1", "[::1]", "::1"].includes(host) || host.endsWith(".localhost");
if (!local && !allowed.includes(host)) {
throw new Error(
`refusing to record ${url}: recordings are published to a public repo, so only a local dev stack is allowed ` +
`(set QA_ALLOW_HOST=${host} if this host is a dev machine running seed data)`,
);
}
}
// The stack's idle watchdog stops it after a stretch with no recording; every use resets the clock.
export function touchStack(): void {
if (existsSync(STACK_DIR)) writeFileSync(join(STACK_DIR, "last-used"), new Date().toISOString());
}
export function authFile(): string {
return join(AUTH_DIR, `${new URL(env.webURL).host.replace(/[^a-z0-9]+/gi, "_")}.json`);
}