Files
memind/scripts/setup-local-test-dns.mjs
T
john 54de1dd8e3 Add local test domain setup (test.*.tkmind.cn).
DNS/TLS/proxy scripts and docs/local-dev.md replace localhost URLs for H5, memind_adm, Plaza, and Ops during local dev.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 09:55:04 +08:00

121 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Map local test domains -> 127.0.0.1 for dev (macOS hosts + per-domain resolver).
*
* Usage:
* sudo node scripts/setup-local-test-dns.mjs
* sudo node scripts/setup-local-test-dns.mjs --remove
*/
import fs from 'node:fs';
import path from 'node:path';
import { execSync } from 'node:child_process';
import { DNS_MARKER, DNS_PORT, LOCAL_IP, TEST_HOSTS } from './local-test-config.mjs';
const remove = process.argv.includes('--remove');
const hostsPath = '/etc/hosts';
const resolverDir = '/etc/resolver';
const resolverBody = `nameserver 127.0.0.1\nport ${DNS_PORT}\n# ${DNS_MARKER}\n`;
function flushDnsCache() {
try {
execSync('dscacheutil -flushcache', { stdio: 'ignore' });
execSync('killall -HUP mDNSResponder', { stdio: 'ignore' });
} catch {
// best effort
}
}
function hostLine(host) {
return `${LOCAL_IP} ${host} # ${DNS_MARKER}`;
}
function removeHostLines(lines, host) {
return lines.filter(
(line) =>
!line.includes(DNS_MARKER) &&
!new RegExp(`\\s${host.replace('.', '\\.')}(\\s|$)`).test(line),
);
}
function hostReady(lines, host) {
return lines.some(
(line) =>
(line.includes(DNS_MARKER) && line.includes(host)) ||
new RegExp(`\\s${host.replace('.', '\\.')}(\\s|$)`).test(line),
);
}
if (remove) {
if (process.getuid?.() !== 0) {
console.log('需要 root 权限,请执行:');
console.log(` sudo node ${process.argv[1]} --remove`);
process.exit(1);
}
let lines = fs.readFileSync(hostsPath, 'utf8').split('\n');
for (const host of TEST_HOSTS) {
lines = removeHostLines(lines, host);
try {
if (fs.existsSync(path.join(resolverDir, host))) fs.unlinkSync(path.join(resolverDir, host));
} catch {
// ignore
}
}
execSync(`tee ${hostsPath}`, {
input: `${lines.join('\n').replace(/\n?$/, '\n')}`,
stdio: ['pipe', 'inherit', 'inherit'],
});
flushDnsCache();
console.log(`已移除本地测试域名:${TEST_HOSTS.join(', ')}`);
process.exit(0);
}
const currentLines = fs.readFileSync(hostsPath, 'utf8').split('\n');
const allReady = TEST_HOSTS.every((host) => {
const resolverPath = path.join(resolverDir, host);
const resolverReady =
fs.existsSync(resolverPath) && fs.readFileSync(resolverPath, 'utf8').trim() === resolverBody.trim();
return hostReady(currentLines, host) && resolverReady;
});
if (allReady) {
console.log(`本地测试域名已配置:${TEST_HOSTS.join(', ')}`);
process.exit(0);
}
if (process.getuid?.() !== 0) {
console.log('需要 root 权限写入 /etc/hosts 和 /etc/resolver,请执行:');
console.log(` sudo pnpm setup:local-dns`);
process.exit(1);
}
let lines = currentLines;
for (const host of TEST_HOSTS) {
if (!hostReady(lines, host)) {
lines = lines.filter((line) => !line.includes(DNS_MARKER) || !line.includes(host));
lines.push(hostLine(host));
console.log(`已添加 hosts${hostLine(host)}`);
} else {
console.log(`${host} 已在 /etc/hosts 中指向 ${LOCAL_IP}`);
}
}
execSync(`tee ${hostsPath}`, {
input: `${lines.join('\n').replace(/\n?$/, '\n')}`,
stdio: ['pipe', 'inherit', 'inherit'],
});
fs.mkdirSync(resolverDir, { recursive: true });
for (const host of TEST_HOSTS) {
const resolverPath = path.join(resolverDir, host);
fs.writeFileSync(resolverPath, resolverBody, 'utf8');
console.log(`已添加 resolver${resolverPath} -> 127.0.0.1:${DNS_PORT}`);
}
flushDnsCache();
console.log('');
console.log('下一步:');
console.log(' sudo pnpm setup:local-tls # 生成本地 HTTPS 证书');
console.log(' pnpm dev # 启动全栈');
console.log(' sudo pnpm dev:local-proxy # HTTPS :443 统一入口');