#!/usr/bin/env sh set -eu if (set -o pipefail) >/dev/null 2>&1; then set -o pipefail fi export MSYS_NO_PATHCONV=1 SCRIPT_PATH="$0" case "$SCRIPT_PATH" in /*) ;; *) SCRIPT_PATH="$(pwd)/$SCRIPT_PATH" ;; esac SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$SCRIPT_PATH")" && pwd)" cd "$SCRIPT_DIR" ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" ROOT_ENV_FILE="$ROOT_DIR/.env" MODE="${1:-start}" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' info() { printf '%b\n' "${GREEN}[INFO]${NC} $*"; } warn() { printf '%b\n' "${YELLOW}[WARN]${NC} $*"; } error() { printf '%b\n' "${RED}[ERROR]${NC} $*"; exit 1; } if [ -f "$ROOT_ENV_FILE" ]; then ENV_OVERRIDE_WEB_HOST_SET=false ENV_OVERRIDE_SERVER_HOST_SET=false ENV_OVERRIDE_POSTGRES_HOST_SET=false if [ "${WEB_HOST+x}" = x ]; then ENV_OVERRIDE_WEB_HOST_SET=true ENV_OVERRIDE_WEB_HOST="$WEB_HOST" fi if [ "${SERVER_HOST+x}" = x ]; then ENV_OVERRIDE_SERVER_HOST_SET=true ENV_OVERRIDE_SERVER_HOST="$SERVER_HOST" fi if [ "${POSTGRES_HOST+x}" = x ]; then ENV_OVERRIDE_POSTGRES_HOST_SET=true ENV_OVERRIDE_POSTGRES_HOST="$POSTGRES_HOST" fi set -a . "$ROOT_ENV_FILE" set +a if [ "$ENV_OVERRIDE_WEB_HOST_SET" = true ]; then WEB_HOST="$ENV_OVERRIDE_WEB_HOST" fi if [ "$ENV_OVERRIDE_SERVER_HOST_SET" = true ]; then SERVER_HOST="$ENV_OVERRIDE_SERVER_HOST" fi if [ "$ENV_OVERRIDE_POSTGRES_HOST_SET" = true ]; then POSTGRES_HOST="$ENV_OVERRIDE_POSTGRES_HOST" fi fi if [ "${X_FINANCIAL_FORCE_SETUP:-false}" = "true" ]; then SETUP_COMPLETED=false VITE_SETUP_COMPLETED=false fi WEB_HOST="${WEB_HOST:-0.0.0.0}" WEB_PORT="${WEB_PORT:-5273}" export VITE_SETUP_COMPLETED="${SETUP_COMPLETED:-false}" export VITE_COMPANY_NAME="${COMPANY_NAME:-}" export VITE_COMPANY_CODE="${COMPANY_CODE:-}" export VITE_ADMIN_EMAIL="${ADMIN_EMAIL:-}" export VITE_WEB_HOST="${WEB_HOST}" export VITE_WEB_PORT="${WEB_PORT}" export VITE_SERVER_HOST="${SERVER_HOST:-127.0.0.1}" export VITE_SERVER_PORT="${SERVER_PORT:-8000}" export VITE_POSTGRES_HOST="${POSTGRES_HOST:-127.0.0.1}" export VITE_POSTGRES_PORT="${POSTGRES_PORT:-5432}" export VITE_POSTGRES_DB="${POSTGRES_DB:-x_financial}" export VITE_POSTGRES_USER="${POSTGRES_USER:-postgres}" export VITE_REDIS_URL="${REDIS_URL:-}" is_wsl() { grep -qi microsoft /proc/version 2>/dev/null } is_windows_path() { case "$SCRIPT_DIR" in /mnt/*) return 0 ;; /d/*|/c/*|/e/*|/f/*) return 0 ;; *) return 1 ;; esac } use_windows_npm() { is_wsl && is_windows_path && command -v powershell.exe >/dev/null 2>&1 && command -v wslpath >/dev/null 2>&1 } windows_project_path() { wslpath -w "$SCRIPT_DIR" } shell_quote_single() { printf "%s" "$1" | sed "s/'/''/g" } run_windows_powershell() { powershell_command="$1" powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "$powershell_command" } run_windows_npm_install() { win_path="$(windows_project_path)" win_path_ps="$(shell_quote_single "$win_path")" run_windows_powershell "Set-Location -LiteralPath '$win_path_ps'; npm install" } run_windows_npm_start() { win_path="$(windows_project_path)" win_path_ps="$(shell_quote_single "$win_path")" exec powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Set-Location -LiteralPath '$win_path_ps'; npm start -- --host $WEB_HOST --port $WEB_PORT" } dependencies_ready() { [ -d "node_modules" ] || return 1 [ -f "node_modules/vite/bin/vite.js" ] || return 1 [ -f "node_modules/pg/package.json" ] || return 1 [ -f "node_modules/vue-router/package.json" ] || return 1 if use_windows_npm; then win_path="$(windows_project_path)" win_path_ps="$(shell_quote_single "$win_path")" powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "Set-Location -LiteralPath '$win_path_ps'; node -e \"require('rollup'); require('pg'); require('vue-router')\"" >/dev/null 2>&1 return $? fi [ -e "node_modules/.bin/vite" ] || [ -e "node_modules/.bin/vite.cmd" ] || return 1 node -e "require('rollup'); require('pg'); require('vue-router')" >/dev/null 2>&1 } ensure_runtime_tools() { if use_windows_npm; then info "Detected WSL on a Windows-mounted project" info "Using Windows npm to manage web dependencies" if ! run_windows_powershell "node -v > \$null; npm -v > \$null" >/dev/null 2>&1; then error "Windows Node.js/npm is not available in PATH. Install Node.js on Windows first." fi return 0 fi if ! command -v node >/dev/null 2>&1; then error "Node.js is not installed. Install it first: https://nodejs.org" fi if ! command -v npm >/dev/null 2>&1; then error "npm is not installed. It should come with Node.js." fi info "Node.js $(node -v) | npm $(npm -v)" } ensure_dependencies() { ensure_runtime_tools if dependencies_ready; then info "Web dependencies are ready." return 0 fi warn "Web dependencies are missing or incomplete" info "Installing web dependencies..." if use_windows_npm; then run_windows_npm_install else npm install fi if ! dependencies_ready; then error "Web dependencies are still incomplete after installation. Try deleting web/node_modules and running npm install manually." fi info "Web dependencies are ready." } start_dev_server() { info "Starting X-Financial Reimbursement Admin..." info "Access: http://$WEB_HOST:$WEB_PORT" echo "" if use_windows_npm; then run_windows_npm_start fi exec npm start -- --host "$WEB_HOST" --port "$WEB_PORT" } case "$MODE" in deps) ensure_dependencies ;; start) ensure_dependencies start_dev_server ;; *) error "Unknown mode: $MODE. Use one of: deps, start" ;; esac