Files
tanshu 1f41398370 Make dev mode one command and add VS Code config
npm run dev now runs scripts/dev-env.ts first, which creates .dev/site.env with
a known dev password and a random session secret, so a fresh clone serves a
working admin without anyone hand-building a hash. Adds .vscode launch
configurations and tasks for the dev server, one test file, and check-site, and
brings scripts/ under typecheck, which it had been missing.
2026-09-22 21:47:11 +05:30

58 lines
1.7 KiB
TypeScript

/**
* Prepares a local development Site so `npm run dev` has a working admin
* without anyone hand-building a password hash.
*
* Development only: the file it writes is gitignored, holds a fixed well-known
* password, and the dev server runs with SECURE_COOKIES=false over http.
*/
import { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
import { randomBytes } from 'node:crypto';
import path from 'node:path';
import { hashPassword } from '../src/auth.ts';
const DEV_PASSWORD = process.env['DEV_ADMIN_PASSWORD'] ?? 'menu-dev-password';
const root = path.resolve(process.env['MENU_ROOT'] ?? '.dev');
const envFile = path.join(root, 'site.env');
async function exists(target: string): Promise<boolean> {
try {
await readFile(target);
return true;
} catch {
return false;
}
}
async function hasContent(dir: string): Promise<boolean> {
try {
return (await readdir(dir)).length > 0;
} catch {
return false;
}
}
if (await exists(envFile)) {
console.log(`${envFile} already exists — using it (delete the file to reset the dev password)`);
} else {
await mkdir(root, { recursive: true });
const hash = await hashPassword(DEV_PASSWORD);
const secret = randomBytes(32).toString('base64url');
await writeFile(
envFile,
[
'# Development only, created by scripts/dev-env.ts. Gitignored.',
`ADMIN_PASSWORD_HASH=${hash}`,
`SESSION_SECRET=${secret}`,
'',
].join('\n'),
{ mode: 0o600 },
);
console.log(`wrote ${envFile}`);
console.log(` admin password: ${DEV_PASSWORD} (override with DEV_ADMIN_PASSWORD=...)`);
}
if (!(await hasContent(path.join(root, 'data', 'published')))) {
console.log('no published menus yet — run `npm run seed` for placeholder ones');
}