158 lines
5.0 KiB
Bash
Executable File
158 lines
5.0 KiB
Bash
Executable File
#!/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
|