Files
TREK/server/tests/unit/app-config/env-reference.test.ts
T
Maurice a6f635f3e0 docs(server): keep the managed-hosting switches out of the env reference
The env reference parity test forced TREK_MANAGED, MAPBOX_ACCESS_TOKEN,
CARTO_API_KEY and PLACES_API_BASE into server/.env.example with how-to text.
They are managed hosting only and stay out of the public docs, the same way
TREK_DB_FILE and APP_VERSION do, so they move to NOT_OPERATOR_SETTINGS with
that reason and their lines leave the self-hoster reference again. The
variables themselves and their behaviour are unchanged.
2026-10-08 18:41:01 +02:00

62 lines
2.7 KiB
TypeScript

/**
* server/.env.example is the env-var reference (root CLAUDE.md), and the Zod
* schema in env.schema.ts is what the server actually validates. Nothing tied
* the two together, so about forty variables the server reads were missing
* from the reference. These cases fail on drift in either direction.
*/
import { describe, it, expect } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import { envSchema } from '../../../src/app-config/env.schema';
const ENV_EXAMPLE = path.join(__dirname, '..', '..', '..', '.env.example');
/**
* Schema entries a self-hoster never sets, with the reason. Everything else in
* the schema has a line in .env.example, commented out when it is optional.
* The managed-hosting switches are here on purpose: they stay out of every
* public reference, like TREK_DB_FILE and APP_VERSION.
*/
const NOT_OPERATOR_SETTINGS: Record<string, string> = {
PATH: 'the OS search path, validated only so the kitinerary probe can resolve its binary',
Path: 'the Windows spelling of PATH',
APP_VERSION: 'set by the image build; the VERSION file wins over it',
TREK_DB_FILE: 'points the Playwright harness at a throwaway database',
TREK_MANAGED: 'managed hosting only, deliberately undocumented for self-hosters',
MAPBOX_ACCESS_TOKEN: 'managed hosting only (read with TREK_MANAGED), deliberately undocumented for self-hosters',
CARTO_API_KEY: 'managed hosting only (read with TREK_MANAGED), deliberately undocumented for self-hosters',
PLACES_API_BASE: "managed hosting's egress gateway for the Places calls, deliberately undocumented for self-hosters",
};
/** Every variable named on a `KEY=` line, set or commented out. */
function documentedVariables(): Set<string> {
const names = new Set<string>();
for (const line of fs.readFileSync(ENV_EXAMPLE, 'utf8').split(/\r?\n/)) {
const match = /^#?\s*([A-Za-z][A-Za-z0-9_]*)=/.exec(line);
if (match) names.add(match[1]);
}
return names;
}
const schemaKeys = Object.keys(envSchema.shape);
const documented = documentedVariables();
describe('server/.env.example against the validated schema', () => {
it('ENV-REF-001: documents every variable the schema validates', () => {
const missing = schemaKeys.filter((key) => !documented.has(key) && !(key in NOT_OPERATOR_SETTINGS));
expect(missing).toEqual([]);
});
it('ENV-REF-002: names no variable the server does not validate', () => {
const schema = new Set(schemaKeys);
expect([...documented].filter((key) => !schema.has(key))).toEqual([]);
});
it('ENV-REF-003: the exceptions are real schema entries that the reference leaves out', () => {
for (const key of Object.keys(NOT_OPERATOR_SETTINGS)) {
expect(schemaKeys).toContain(key);
expect(documented.has(key)).toBe(false);
}
});
});