Files
memind/scripts/setup-local-test-dns.mjs
T
Your Name b0f5d6a51c Extract memind_adm admin server, add local dev tooling, and remove image-generation.
Split platform admin and ops APIs into standalone admin-server.mjs with network guards; simplify billing to RMB token pricing, refactor user auth, and add rsync deploy plus local-test scripts and docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 16:39:39 -07: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 统一入口');