diff --git a/AGENTS.md b/AGENTS.md
index 7698cac..bcc408b 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -20,7 +20,7 @@ This block is written and re-added by `next dev` — verify at `node_modules/nex
- 成功抓取文件通过原生 Route Handler 返回;Proxy 仅选择成功出口或准备并改写完整 TSX 404,不能直接从 Proxy 输出文件,否则 Next 会过滤 Content-Length。保留 Go ServeFile 的 MIME、原字节、Last-Modified、Content-Length、Accept-Ranges、304/412/206/416、If-Range/多段 Range 和 HEAD;Next compress=false 避免框架自动压缩改变文件响应,外层代理可沿用原传输配置。
- 播放器通过 npm 使用 `xgplayer` 与 `xgplayer-hls`;不要恢复 CDN 脚本版 DPlayer/Hls/Swiper 或旧业务脚本。
- `/h5/m3u8/**`、`/enkey`、`/newenkey` 保留服务端媒体转发:签名 query 不重组,UA/IP/Range 保留,上游重定向按原 Go 客户端跟随。签名媒体请求按原合同不附登录 Cookie/Authorization;上游业务 JSON 错误返回 502,不能当播放清单成功响应。
-- `config/development.env`、`config/test.env`、`config/production.env` 分别管理三套环境,本地覆盖使用忽略提交的 `*.local.env`;进程环境优先。2026-10-16 起开发 API 按用户指定使用 `https://webhuakuiapi.mfcg.me`(替代原 `http://172.104.181.99:30331`),不要擅自切回原站 25319 或旧地址。
+- `config/development.env`、`config/test.env`、`config/production.env` 分别管理三套环境,本地覆盖使用忽略提交的 `*.local.env`;进程环境优先。2026-10-16 起开发 API 按用户指定使用 `http://127.0.0.1:20032`(替代原 `http://172.104.181.99:30331`),不要擅自切回原站 25319 或旧地址。
- SSR 请求准备在 `src/proxy.ts` 完成,通过 `src/server/react/handoff.ts` 向 React 交接;保留同请求 Cookie/页面数据一致性。大快照使用私有临时文件,部署多实例时须处理交接存储共享或实例亲和。
- 所有“黄果短剧”统一为“花魁短剧”。占位图品牌 logo 透明度固定为 `0.2`。Figma 文件为 `1vUq4wf5xOs8ZOlmt26Q3O`,读取设计使用本地 `FIGMA_TOKEN` 调用 REST API,不能打印令牌。
- 本地 `npm run dev` 默认使用 Webpack;该项目已确认 Next 16.4 Turbopack 开发 HMR 存在循环刷新,未经验证不要改回默认。Charles 调试使用 `npm run dev:charles`,不改业务接口地址。
diff --git a/README.md b/README.md
index 36f4ee6..f91fd3c 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ Node 原生代理说明:[Node.js HTTP 文档](https://nodejs.org/download/rele
配置优先级:进程环境变量 > `config/<环境>.local.env` > `config/<环境>.env`。本地覆盖文件不会提交。`APP_ENV` 选择业务环境;测试环境的优化构建仍使用 Next.js 要求的 `NODE_ENV=production`。
-开发 `UPSTREAM_API_URL` 使用 `https://webhuakuiapi.mfcg.me`;测试服务与 API 同机,使用 `http://127.0.0.1:30331`,测试应用端口为 `30334`。本地运行测试环境且 API 不在本机时,可在 `config/test.local.env` 覆盖上游地址。正式配置使用同机 API `http://127.0.0.1:26931`、服务端口 `26935`,可由部署环境或 `config/production.local.env` 覆盖。构建不访问上游,启动时检查地址。
+开发 `UPSTREAM_API_URL` 使用 `http://127.0.0.1:20032`;测试服务与 API 同机,使用 `http://127.0.0.1:30331`,测试应用端口为 `30334`。本地运行测试环境且 API 不在本机时,可在 `config/test.local.env` 覆盖上游地址。正式配置使用同机 API `http://127.0.0.1:26931`、服务端口 `26935`,可由部署环境或 `config/production.local.env` 覆盖。构建不访问上游,启动时检查地址。
```dotenv
UPSTREAM_API_URL=https://your-api.example
diff --git a/config/development.env b/config/development.env
index 986b4d2..a7a391e 100644
--- a/config/development.env
+++ b/config/development.env
@@ -1,5 +1,5 @@
APP_ENV=development
-UPSTREAM_API_URL=https://webhuakuiapi.mfcg.me
+UPSTREAM_API_URL=http://127.0.0.1:20032
# UPSTREAM_API_URL=http://172.104.181.99:30331
# The API supplies imgCdn/imgAppUsCdn; this CloudFront source is only the fallback.
# Primary public domain; overrides the backend foreverUrlAddr.
diff --git a/deploy_prod.sh b/deploy_prod.sh
index e3f33e4..bfa0fb5 100755
--- a/deploy_prod.sh
+++ b/deploy_prod.sh
@@ -1,131 +1,7 @@
-#!/bin/bash
-# 花魁短剧正式服:检查 → 构建 → Linux 运行包 + MD5 → 跳板机 running.sh。
-set -euo pipefail
-
-SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
-cd "$SCRIPT_DIR"
-JUMP_HOST="${DEPLOY_JUMP_HOST:-server@116.212.120.2}"
-JUMP_DIR="${DEPLOY_JUMP_DIR:-/home/server/web_hkdj/h5/nuxt}"
-# 按正式服约定分别设置:SCP 为 22889,触发 SSH 为默认 22。
-SCP_PORT="${DEPLOY_SCP_PORT:-22889}"
-SSH_PORT="${DEPLOY_SSH_PORT:-22}"
-TARGET_ARCH="${DEPLOY_TARGET_ARCH:-x64}"
-TARGET_LIBC="${DEPLOY_TARGET_LIBC:-glibc}"
-PACKAGE_NAME=web_hkdj_h5.tar.gz
-MD5_NAME=web_hkdj_h5.md5
-PACKAGE="$SCRIPT_DIR/$PACKAGE_NAME"
-MD5_FILE="$SCRIPT_DIR/$MD5_NAME"
-RELEASE="$SCRIPT_DIR/dist/production-linux-$TARGET_ARCH-$TARGET_LIBC"
-PACKAGE_ONLY=0
-
-fail() { printf '错误:%s\n' "$*" >&2; exit 1; }
-step() { printf '\n▸ %s\n' "$*"; }
-for argument in "$@"; do
- case "$argument" in
- --dry-run) DEPLOY_DRY_RUN=1 ;;
- --package-only) PACKAGE_ONLY=1 ;;
- -h|--help)
- printf '用法:%s [--dry-run | --package-only]\n' "$0"
- printf '默认上传 server@116.212.120.2:/home/server/web_hkdj/h5/nuxt/,SCP 22889,SSH 22。\n'
- printf '可覆盖 DEPLOY_JUMP_HOST、DEPLOY_JUMP_DIR、DEPLOY_SCP_PORT、DEPLOY_SSH_PORT、DEPLOY_TARGET_ARCH、DEPLOY_TARGET_LIBC。\n'
- exit 0 ;;
- *) fail "不支持的参数 $argument;使用 --help 查看用法" ;;
- esac
-done
-[[ "$JUMP_HOST" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.@-]*$ ]] || fail 'DEPLOY_JUMP_HOST 格式无效'
-[[ "$JUMP_DIR" =~ ^/[a-zA-Z0-9_-]+(/[a-zA-Z0-9_-]+)*/?$ ]] || fail 'DEPLOY_JUMP_DIR 必须是普通绝对路径'
-JUMP_DIR="${JUMP_DIR%/}"
-for port in "$SCP_PORT" "$SSH_PORT"; do
- [[ "$port" =~ ^[0-9]+$ ]] && [ "$port" -ge 1 ] && [ "$port" -le 65535 ] || fail 'SCP/SSH 端口必须在 1–65535 内'
-done
-case "$TARGET_ARCH" in x64|arm64) ;; *) fail 'DEPLOY_TARGET_ARCH 仅支持 x64 或 arm64' ;; esac
-case "$TARGET_LIBC" in glibc|musl) ;; *) fail 'DEPLOY_TARGET_LIBC 仅支持 glibc 或 musl' ;; esac
-for tool in node npm tar; do
- command -v "$tool" >/dev/null || fail "缺少命令 $tool"
-done
-node -e 'const [a,b]=process.versions.node.split(".").map(Number); if(a<20 || a===20 && b<9) process.exit(1)' || fail '需要 Node.js >=20.9,推荐 22'
-node -e 'const [a,b,c]=process.argv[1].split(".").map(Number); if(a<10 || a===10 && (b<9 || b===9 && c<2)) process.exit(1)' "$(npm --version)" || fail '跨平台运行依赖打包需要 npm >=10.9.2'
-command -v md5sum >/dev/null || command -v md5 >/dev/null || fail '缺少 md5sum 或 macOS md5'
-for file in config/production.env config/secrets/m3u8.key package-lock.json scripts/prepare-production-runtime.ts; do
- [ -s "$file" ] || fail "缺少 $file"
-done
-[ -x node_modules/.bin/tsx ] || fail '请先执行 npm ci 安装本地依赖'
-
-if [ "${DEPLOY_DRY_RUN:-0}" = 1 ]; then
- printf 'DRY RUN:正式环境;Linux %s/%s;只核对,不构建、不连接服务器。\n' "$TARGET_ARCH" "$TARGET_LIBC"
- node --input-type=module -e 'import {readFileSync} from "node:fs"; import {parse} from "dotenv"; const c=parse(readFileSync("config/production.env")); console.log(` 服务端口 PORT=${c.PORT};仅打包 config/production.env,不上传本地覆盖。`)'
- printf ' npm run check → build → bundle → bundle:linux -- %s %s\n' "$TARGET_ARCH" "$TARGET_LIBC"
- printf ' 保留 standalone 裁剪依赖,仅补目标 Linux Sharp/libvips;不安装完整生产依赖。\n'
- printf ' tar 根目录:start.mjs、server.js、node_modules、.next、public、config 等\n'
- printf ' 生成 %s + %s(纯 MD5 hash)\n' "$PACKAGE_NAME" "$MD5_NAME"
- if [ "$PACKAGE_ONLY" = 1 ]; then
- printf ' --package-only:生成后结束,不上传。\n'
- else
- printf ' scp -P %s %s %s %s:%s/\n' "$SCP_PORT" "$PACKAGE_NAME" "$MD5_NAME" "$JUMP_HOST" "$JUMP_DIR"
- printf ' ssh -p %s %s %s/running.sh(不带脚本参数)\n' "$SSH_PORT" "$JUMP_HOST" "$JUMP_DIR"
- fi
- exit 0
-fi
-if [ "$PACKAGE_ONLY" = 0 ]; then
- for tool in ssh scp tee; do command -v "$tool" >/dev/null || fail "缺少命令 $tool"; done
-fi
-
-# 同仓库只能有一次构建/打包/上传,避免并发覆盖同名包或提前触发 running.sh。
-mkdir -p "$SCRIPT_DIR/dist"
-DEPLOY_LOCK="$SCRIPT_DIR/dist/.production-deploy.lock"
-mkdir "$DEPLOY_LOCK" 2>/dev/null || fail "已有正式发布进程或残留锁:${DEPLOY_LOCK};请先确认该进程已结束"
-trap 'rmdir "$DEPLOY_LOCK" 2>/dev/null || true' EXIT
-trap 'exit 130' INT
-trap 'exit 143' TERM
-
-step '检查类型和单元测试'
-npm run check
-step '构建并整理正式环境 standalone'
-npm run build
-npm run bundle
-step "准备 standalone 精简运行包,仅补 Linux $TARGET_ARCH/$TARGET_LIBC 图片库"
-npm run bundle:linux -- "$TARGET_ARCH" "$TARGET_LIBC"
-for file in start.mjs server.js .next/BUILD_ID config/production.env config/secrets/m3u8.key runtime-target.json; do
- [ -s "$RELEASE/$file" ] || fail "正式运行包缺少 $file"
-done
-for directory in node_modules .next/static public; do
- [ -d "$RELEASE/$directory" ] || fail "正式运行包缺少目录 $directory"
-done
-
-step "打包 $PACKAGE_NAME"
-# -C 保持产物直接位于 tar 根部;禁止 AppleDouble、环境覆盖和日志混入。
-COPYFILE_DISABLE=1 COPY_EXTENDED_ATTRIBUTES_DISABLE=1 tar \
- --no-xattrs \
- --exclude='._*' --exclude='.DS_Store' --exclude='.env*' \
- --exclude='*.local.env' --exclude='*.log' \
- -czf "$PACKAGE" -C "$RELEASE" .
-chmod 600 "$PACKAGE"
-if command -v md5sum >/dev/null; then
- md5sum "$PACKAGE" | awk '{print $1}' > "$MD5_FILE"
-else
- md5 -q "$PACKAGE" > "$MD5_FILE"
-fi
-tar -tzf "$PACKAGE" >/dev/null
-printf '运行包已生成:%s;校验文件:%s\n' "$PACKAGE_NAME" "$MD5_NAME"
-node -e 'console.log(`压缩包体积:${(require("node:fs").statSync(process.argv[1]).size / 1024 / 1024).toFixed(2)} MiB`)' "$PACKAGE"
-if [ "$PACKAGE_ONLY" = 1 ]; then exit 0; fi
-
-step "上传到跳板机 $JUMP_HOST:$JUMP_DIR/"
-scp -P "$SCP_PORT" "$PACKAGE" "$MD5_FILE" "$JUMP_HOST:$JUMP_DIR/"
-step '执行既有正式服 running.sh'
-# gatekeeper 按完整 .sh 路径放行,不能附参数、cd、bash 前缀或其它命令。
-RUN_LOG=$(mktemp "$SCRIPT_DIR/dist/production-running.XXXXXX")
-printf '远端执行日志:%s\n' "$RUN_LOG"
-if ! ssh -p "$SSH_PORT" "$JUMP_HOST" "$JUMP_DIR/running.sh" 2>&1 | tee "$RUN_LOG"; then
- fail "正式服 running.sh 执行失败;日志:${RUN_LOG}"
-fi
-# 部分既有服务器脚本没有透传 Supervisor 的失败退出码,不能只依据 SSH 返回 0。
-if ! node - "$RUN_LOG" <<'NODE'
-const { readFileSync } = require('node:fs');
-const output = readFileSync(process.argv[2], 'utf8').replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, '');
-if (/\b(?:BACKOFF|FATAL|ERROR)\b|\bspawn\s+error\b/i.test(output)) process.exit(1);
-NODE
-then
- fail "正式服输出包含失败状态,不能确认发布成功;日志:${RUN_LOG}"
-fi
-printf '\n正式服 running.sh 执行完成,未发现失败状态;日志:%s;本地包已保留供排查。\n' "$RUN_LOG"
+set -e
+rm -rf dist dist.zip
+npm run build:prod
+zip -q -r dist.zip dist
+# https://dis79itlh8uwv.cloudfront.net
+scp dist.zip root@172.104.166.87:/tmp/dist.zip
+ssh root@172.104.166.87 "set -e && rm -rf /tmp/extract && unzip -q /tmp/dist.zip -d /tmp/extract && cd /server/web_huakui/h5/dist/ && rm -rf ./* && mv /tmp/extract/dist/* . && rm -rf /tmp/extract /tmp/dist.zip && echo DEPLOY_OK"
diff --git a/deploy_test.sh b/deploy_test.sh
deleted file mode 100755
index 1f02180..0000000
--- a/deploy_test.sh
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/bin/bash
-# 花魁短剧测试服:检查 → 构建 → dist.zip → 上传 → Supervisor 重启/健康检查。
-# DEPLOY_DRY_RUN=1 ./deploy_test.sh 仅核对,不构建、不连接服务器。
-set -euo pipefail
-
-SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
-cd "$SCRIPT_DIR"
-
-HOST="${DEPLOY_HOST:-root@172.104.181.99}"
-SSH_PORT="${DEPLOY_SSH_PORT:-22889}"
-REMOTE_DIR="${DEPLOY_DIR:-/server/hkdj_net/h5}"
-CHECK_URL="${DEPLOY_CHECK_URL:-https://hkdjneth5.remoces.com}"
-PACKAGE="$SCRIPT_DIR/dist.zip"
-CHECKSUM="$SCRIPT_DIR/dist.zip.sha256"
-
-fail() { printf '错误:%s\n' "$*" >&2; exit 1; }
-step() { printf '\n▸ %s\n' "$*"; }
-
-for argument in "$@"; do
- case "$argument" in
- --dry-run) DEPLOY_DRY_RUN=1 ;;
- -h|--help)
- printf '用法:%s [--dry-run]\n默认目标 root@172.104.181.99:22889 /server/hkdj_net/h5/\n可覆盖 DEPLOY_HOST、DEPLOY_SSH_PORT、DEPLOY_DIR、DEPLOY_CHECK_URL;DEPLOY_DRY_RUN=1 等同 --dry-run。\n' "$0"
- exit 0 ;;
- *) fail "不支持的参数 $argument;使用 --help 查看用法" ;;
- esac
-done
-
-# 这些值会作为远端路径/命令使用,仅允许普通 SSH 目标和绝对路径。
-[[ "$HOST" =~ ^[a-zA-Z0-9_][a-zA-Z0-9_.@-]*$ ]] || fail "DEPLOY_HOST 格式无效"
-[[ "$SSH_PORT" =~ ^[0-9]+$ ]] && [ "$SSH_PORT" -ge 1 ] && [ "$SSH_PORT" -le 65535 ] || fail "DEPLOY_SSH_PORT 无效"
-[[ "$REMOTE_DIR" =~ ^/[a-zA-Z0-9_-]+(/[a-zA-Z0-9_-]+)*/?$ ]] || fail "DEPLOY_DIR 必须是普通绝对路径"
-
-for tool in node npm zip unzip ssh scp; do
- command -v "$tool" >/dev/null || fail "缺少命令 $tool"
-done
-node -e 'const [a,b]=process.versions.node.split(".").map(Number); if(a<20 || (a===20 && b<9)) process.exit(1)' || fail "需要 Node.js >=20.9,推荐 Node.js 22"
-node -e 'try { const u=new URL(process.argv[1]); if (!["http:","https:"].includes(u.protocol) || u.username || u.password || u.search || u.hash || u.pathname!=="/") process.exit(1); } catch { process.exit(1); }' "$CHECK_URL" || fail "DEPLOY_CHECK_URL 必须是 HTTP(S) 站点根地址"
-for file in config/test.env config/secrets/m3u8.key deploy/up_next_h5.sh package-lock.json; do
- [ -s "$file" ] || fail "缺少 $file"
-done
-bash -n deploy/up_next_h5.sh
-
-if [ "${DEPLOY_DRY_RUN:-0}" = 1 ]; then
- printf 'DRY RUN:测试配置 config/test.env;上游与端口可由服务器 config/test.local.env 覆盖。\n'
- # 不输出本地覆盖/进程配置中的凭证;只展示仓库公共配置。
- node --input-type=module -e 'import {readFileSync} from "node:fs"; import {parse} from "dotenv"; const c=parse(readFileSync("config/test.env")); console.log(` API=${c.UPSTREAM_API_URL} PORT=${c.PORT}`)'
- printf ' npm run check → npm run build:test → npm run bundle:test\n'
- printf ' dist.zip(不含 node_modules / 本地覆盖)+ SHA-256 → %s:%s/(SSH %s)\n' "$HOST" "$REMOTE_DIR" "$SSH_PORT"
- printf ' ssh 执行 %s/up_next_h5.sh:安装 Linux 运行依赖 → next/ → Supervisor hkdj_next_h5 → 健康检查\n' "$REMOTE_DIR"
- printf ' 公网检查 %s:/healthz(test)+ 首页(Next HTML);此模式不访问域名。\n' "$CHECK_URL"
- exit 0
-fi
-
-step '检查类型和单元测试'
-npm run check
-step '构建并整理测试环境 standalone'
-npm run build:test
-npm run bundle:test
-
-for file in start.mjs server.js .next-test/BUILD_ID config/test.env config/secrets/m3u8.key; do
- [ -s "dist/test/$file" ] || fail "测试包缺少 $file"
-done
-[ -d dist/test/.next-test/static ] && [ -d dist/test/public ] || fail '测试包缺少静态资源'
-
-# Next 本机的原生模块不能直接用于 Linux:远端用 lockfile 安装运行依赖。
-# dotenv 属于 dependencies,start.mjs 在 npm ci --omit=dev 后仍可加载配置。
-cp package.json package-lock.json dist/test/
-step '生成 dist.zip 和 SHA-256(保留本地包便于排查)'
-rm -f "$PACKAGE" "$CHECKSUM"
-(
- cd dist/test
- COPYFILE_DISABLE=1 zip -q -r "$PACKAGE" . \
- -x 'node_modules/*' '*/node_modules/*' '*.local.env' '.env*' '*/.env*' '._*' '*/._*' '*.log'
-)
-chmod 600 "$PACKAGE"
-if command -v sha256sum >/dev/null; then
- sha256sum dist.zip > "$CHECKSUM"
-else
- shasum -a 256 dist.zip > "$CHECKSUM"
-fi
-unzip -tq "$PACKAGE"
-
-step "上传到 $HOST:$REMOTE_DIR/"
-ssh -p "$SSH_PORT" "$HOST" "mkdir -p '$REMOTE_DIR'"
-scp -P "$SSH_PORT" "$PACKAGE" "$CHECKSUM" deploy/up_next_h5.sh "$HOST:$REMOTE_DIR/"
-step '执行服务器更新脚本'
-ssh -p "$SSH_PORT" "$HOST" "/bin/bash '$REMOTE_DIR/up_next_h5.sh'"
-step "检查公网测试站 $CHECK_URL"
-if ! node --input-type=module - "$CHECK_URL" <<'NODE'
-const origin = process.argv[2];
-async function read(path) {
- const response = await fetch(new URL(path, origin), { signal: AbortSignal.timeout(4000), redirect: 'error', cache: 'no-store' });
- if (response.status !== 200) throw new Error(`${path} HTTP ${response.status}`);
- let text = '', size = 0;
- const decoder = new TextDecoder();
- for await (const part of response.body) {
- size += part.length;
- if (size > 262144) throw new Error(`${path} 响应超过检查上限`);
- text += decoder.decode(part, { stream: true });
- if (path === '/' && text.includes('/_next/')) break;
- }
- return { text, type: response.headers.get('content-type') || '' };
-}
-for (let attempt = 1; attempt <= 3; attempt++) {
- try {
- const [health, home] = await Promise.all([read('/healthz'), read('/')]);
- let status;
- try { status = JSON.parse(health.text); } catch { throw new Error('/healthz 返回无效 JSON'); }
- if (status?.status !== 'ok' || status?.environment !== 'test') throw new Error('/healthz 未命中 Next 测试服务');
- if (!/^text\/html(?:;|$)/i.test(home.type) || !home.text.includes('/_next/')) throw new Error('首页不是 Next HTML');
- console.log('公网 /healthz 与 Next 首页检查通过');
- process.exit(0);
- } catch (error) {
- console.error(`公网检查 ${attempt}/3 失败:${error.message}`);
- if (attempt < 3) await new Promise(resolve => setTimeout(resolve, 1000));
- }
-}
-process.exit(1);
-NODE
-then
- fail '服务器服务已更新,但域名检查失败,请检查 Nginx 和 Cloudflare 回源配置。'
-fi
-printf '\n测试服更新完成:%s:%s/next(Supervisor:hkdj_next_h5)\n' "$HOST" "$REMOTE_DIR"
diff --git a/next-env.d.ts b/next-env.d.ts
index 6936789..ce4e94a 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,7 +1,7 @@
///
///
-import "./.next-dev/dev/types/routes.d.ts";
-import "./.next-dev/dev/types/root-params.d.ts";
+import "./.next/types/routes.d.ts";
+import "./.next/types/root-params.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/src/server/config.ts b/src/server/config.ts
index bcb7c59..85c87dc 100644
--- a/src/server/config.ts
+++ b/src/server/config.ts
@@ -15,7 +15,7 @@ export function installationURL(value: string | undefined, deepLink = false): st
export function serverConfig() {
const environment = (process.env.APP_ENV || 'development') as AppEnvironment;
if (!['development', 'test', 'production'].includes(environment)) throw new Error('Invalid APP_ENV');
- const upstreamURL = (process.env.UPSTREAM_API_URL || (environment === 'development' ? 'https://webhuakuiapi.mfcg.me' : '')).trim().replace(/\/+$/, '');
+ const upstreamURL = (process.env.UPSTREAM_API_URL || (environment === 'development' ? 'http://127.0.0.1:20032' : '')).trim().replace(/\/+$/, '');
if (upstreamURL && !/^https?:\/\//.test(upstreamURL)) throw new Error('UPSTREAM_API_URL must be an HTTP(S) URL');
return {
environment, upstreamURL,