This commit is contained in:
2026-05-08 11:44:42 +08:00
parent b08127031c
commit abf1f1ebea
249 changed files with 39411 additions and 887 deletions

View File

@@ -43,6 +43,61 @@ resolve_client_host() {
echo "${host_name}"
}
load_api_server_env_files() {
local env_files=()
local key
local value
[[ -f "${REPO_ROOT}/.env" ]] && env_files+=("${REPO_ROOT}/.env")
[[ -f "${REPO_ROOT}/.env.local" ]] && env_files+=("${REPO_ROOT}/.env.local")
[[ -f "${REPO_ROOT}/.env.secrets.local" ]] && env_files+=("${REPO_ROOT}/.env.secrets.local")
if [[ "${#env_files[@]}" -eq 0 ]]; then
return
fi
# Node 只负责按 dotenv 子集解析文本;通过 NUL 分隔返回,避免让 env 文件内容参与 shell 求值。
while IFS= read -r -d '' key && IFS= read -r -d '' value; do
export "${key}=${value}"
done < <(
node - "${env_files[@]}" <<'NODE'
const fs = require('fs');
const shellEnvKeys = new Set(Object.keys(process.env));
const values = new Map();
for (const filePath of process.argv.slice(2)) {
if (!fs.existsSync(filePath)) {
continue;
}
const rawText = fs.readFileSync(filePath, 'utf8');
for (const rawLine of rawText.split(/\r?\n/u)) {
const line = rawLine.trim();
if (!line || line.startsWith('#')) {
continue;
}
const match = line.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/u);
if (!match) {
continue;
}
const [, key, rawValue] = match;
if (shellEnvKeys.has(key)) {
continue;
}
values.set(key, rawValue.replace(/^['"]|['"]$/gu, ''));
}
}
for (const [key, value] of values.entries()) {
process.stdout.write(`${key}\0${value}\0`);
}
NODE
)
}
cleanup() {
local index
@@ -535,6 +590,9 @@ if [[ "${SKIP_PUBLISH}" -ne 1 ]]; then
fi
echo "[dev:rust] 启动 api-server"
load_api_server_env_files
# `.env.local` 可以给单独 `dev:web` 配置代理目标,但完整栈的前端必须跟随本次 `--api-port`。
RUST_SERVER_TARGET="http://${API_TARGET_HOST}:${API_PORT}"
(
cd "${REPO_ROOT}"
GENARRATIVE_API_HOST="${API_HOST}" \