#!/bin/bash # 初始化并持久化后端对外公开 API 地址。不会 source .env,避免执行其中内容。 public_url_read_env_value() { local file="$1" local key="$2" local value value="$(awk -v key="$key" 'index($0, key "=") == 1 { print substr($0, length(key) + 2); exit }' "$file")" value="$(printf '%s' "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" case "$value" in \"*\") value="${value#\"}"; value="${value%\"}" ;; \'*\') value="${value#\'}"; value="${value%\'}" ;; esac printf '%s' "$value" } public_url_write_env_value() { local file="$1" local key="$2" local value="$3" local tmp tmp="$(mktemp "${file}.tmp.XXXXXX")" awk -v key="$key" -v value="$value" ' BEGIN { replaced = 0 } index($0, key "=") == 1 { if (!replaced) { print key "=" value replaced = 1 } next } { print } END { if (!replaced) print key "=" value } ' "$file" > "$tmp" chmod 600 "$tmp" mv "$tmp" "$file" } public_url_normalize() { local value value="$(printf '%s' "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" while [ "${value%/}" != "$value" ]; do value="${value%/}"; done printf '%s' "$value" } public_url_validate() { local value rest authority host port value="$(public_url_normalize "$1")" case "$value" in http://*|https://*) ;; *) return 1 ;; esac case "$value" in *[[:space:]@?#]*) return 1 ;; esac rest="${value#*://}" authority="${rest%%/*}" [ -n "$authority" ] || return 1 if [[ "$authority" == \[* ]]; then [[ "$authority" =~ ^\[[0-9A-Fa-f:.]+\](:[0-9]+)?$ ]] || return 1 if [[ "$authority" == *]:* ]]; then port="${authority##*:}"; fi else [[ "$authority" =~ ^[A-Za-z0-9._-]+(:[0-9]+)?$ ]] || return 1 if [[ "$authority" == *:* ]]; then host="${authority%:*}" port="${authority##*:}" [ -n "$host" ] || return 1 fi fi if [ -n "${port:-}" ]; then [[ "$port" =~ ^[0-9]+$ ]] || return 1 [ "$port" -ge 1 ] && [ "$port" -le 65535 ] || return 1 fi } public_url_derive_from_env() { local file="$1" local api_url socket_url security_origin origin scheme combined api_url="$(public_url_read_env_value "$file" "NUXT_PUBLIC_BASE_APIURL")" if public_url_validate "$api_url"; then public_url_normalize "$api_url" return 0 fi [[ "$api_url" == /* ]] || return 1 socket_url="$(public_url_read_env_value "$file" "NUXT_PUBLIC_BASE_SOCKETURL")" if [[ "$socket_url" =~ ^(ws|wss)://([^/?#[:space:]]+) ]]; then scheme="http" [ "${BASH_REMATCH[1]}" = "wss" ] && scheme="https" origin="${scheme}://${BASH_REMATCH[2]}" fi if [ -z "${origin:-}" ]; then security_origin="$(public_url_read_env_value "$file" "CONFIG_SECURITY_ORIGIN")" security_origin="${security_origin%%,*}" security_origin="$(public_url_normalize "$security_origin")" if [[ "$security_origin" =~ ^(https?://[^/]+) ]]; then origin="${BASH_REMATCH[1]}" fi fi [ -n "${origin:-}" ] || return 1 combined="$(public_url_normalize "${origin}${api_url}")" public_url_validate "$combined" || return 1 printf '%s' "$combined" } init_public_api_base_url() { local file="${1:-.env}" local mode="${2:-upgrade}" local override="${3:-${DEPLOY_PUBLIC_API_BASE_URL:-}}" local current selected if [ ! -f "$file" ]; then echo "❌ 环境配置文件不存在: $file" >&2 return 1 fi if [ "$mode" != "configure" ] && [ "$mode" != "upgrade" ]; then echo "❌ 公开 API 地址初始化模式无效: $mode(仅支持 configure/upgrade)" >&2 return 1 fi if [ -z "$override" ]; then override="$(public_url_read_env_value "$file" "DEPLOY_PUBLIC_API_BASE_URL")" fi current="$(public_url_read_env_value "$file" "CONFIG_PUBLIC_API_BASE_URL")" if [ -n "$override" ]; then selected="$(public_url_normalize "$override")" elif [ -n "$current" ]; then if ! public_url_validate "$current"; then echo "❌ CONFIG_PUBLIC_API_BASE_URL 配置无效: $current" >&2 return 1 fi return 0 else selected="$(public_url_derive_from_env "$file")" || { echo "❌ 无法从现有前端配置推导 CONFIG_PUBLIC_API_BASE_URL" >&2 echo " 请设置完整地址,例如 https://example.com/api" >&2 return 1 } fi if ! public_url_validate "$selected"; then echo "❌ 公开 API 地址配置无效: $selected" >&2 return 1 fi selected="$(public_url_normalize "$selected")" public_url_write_env_value "$file" "CONFIG_PUBLIC_API_BASE_URL" "$selected" echo " ✓ 已配置公开 API 地址: $selected" } if [ "${BASH_SOURCE[0]}" = "$0" ]; then init_public_api_base_url "${1:-.env}" "${2:-upgrade}" "${3:-}" fi