import test from 'node:test' import assert from 'node:assert/strict' import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { ENV_OVERRIDES } from './env-overrides.js' const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url)) const BACKEND_ROOT = path.resolve(CURRENT_DIR, '../..') const WORKSPACE_ROOT = path.resolve(BACKEND_ROOT, '../..') const SPECIAL_RUNTIME_ENV_NAMES = [ 'APP_BASE_URL', 'CLAIM_BASE_URL', ] const DEPLOYMENT_ONLY_ENV_NAMES = [ 'APP_DOMAIN', 'BACKEND_PORT', 'CADDY_SITE_ADDR', 'CHOKIDAR_USEPOLLING', 'NPM_CONFIG_REGISTRY', 'POSTGRES_DB', 'POSTGRES_PASSWORD', 'POSTGRES_PORT', 'POSTGRES_USER', 'TZ', 'VITE_API_TARGET', 'VITE_ALLOWED_HOSTS', ] const KNOWN_ENV_NAMES = new Set([ ...ENV_OVERRIDES.map((override) => override.env), ...SPECIAL_RUNTIME_ENV_NAMES, ...DEPLOYMENT_ONLY_ENV_NAMES, ]) test('env example files only document known runtime or deployment variables', () => { const envFiles = [ path.join(WORKSPACE_ROOT, '.env.server.example'), path.join(WORKSPACE_ROOT, '.env.mac-docker.example'), ] const unknownNames = envFiles.flatMap((filePath) => { return extractExampleEnvNames(filePath) .filter((name) => !KNOWN_ENV_NAMES.has(name)) .map((name) => `${path.basename(filePath)}:${name}`) }) assert.deepEqual(unknownNames, []) }) test('compose environment keys only use known runtime or deployment variables', () => { const composeFiles = [ path.join(WORKSPACE_ROOT, 'docker-compose.yml'), path.join(WORKSPACE_ROOT, 'docker-compose.dev.yml'), ] const unknownNames = composeFiles.flatMap((filePath) => { return extractComposeEnvironmentKeys(filePath) .filter((name) => !KNOWN_ENV_NAMES.has(name)) .map((name) => `${path.basename(filePath)}:${name}`) }) assert.deepEqual(unknownNames, []) }) function extractExampleEnvNames(filePath: string): string[] { const text = fs.readFileSync(filePath, 'utf8') return [...text.matchAll(/^([A-Z][A-Z0-9_]*)=/gm)].map((match) => match[1]) } function extractComposeEnvironmentKeys(filePath: string): string[] { const text = fs.readFileSync(filePath, 'utf8') return [...text.matchAll(/^\s{6}([A-Z][A-Z0-9_]*):/gm)].map((match) => match[1]) }