#!/usr/bin/env bash # Update the hotel catalog from a clone source (Habbo, retros, …). # # Two ways to use it: # ./scripts/catalog-sync.sh interactive menu # ./scripts/catalog-sync.sh --all --sql same flags as the CLI, no menu # # The menu asks which sites to compare (Habbo is the preset) and what may be # written. An audit is read-only; only a repair option touches the catalog, and # applying the generated catalog SQL always needs its own choice. cd "$(dirname "$0")/.." || exit 1 CLI="scripts/catalog-sync.ts" # The react-server export condition resolves `server-only` to its no-op build, # exactly like `pnpm jobs:worker` — the audit engine imports server modules. RUN=(node --conditions=react-server --import tsx "$CLI") # Any flag passed straight through means "no menu", so the same entry point # works for cron/CI where only the flag path is safe. if [ $# -gt 0 ]; then exec "${RUN[@]}" "$@" fi if [ ! -t 0 ]; then echo "Not a terminal. Use the non-interactive form, e.g.:" >&2 echo " $0 --all --sources=default-habbo-com" >&2 exit 1 fi echo "=== Catalog sync ===" echo # ── Step 1: which sites to compare ─────────────────────────────────────────── # Ask the CLI for the configured sources so the menu always matches the live # `clone_sources` setting (and its defaults) instead of a hardcoded list. mapfile -t SOURCE_ROWS < <("${RUN[@]}" --list-sources --tsv) if [ "${#SOURCE_ROWS[@]}" -eq 0 ]; then echo "No clone sources are configured." >&2 exit 1 fi IDS=() NAMES=() echo "Compare this catalog against:" for i in "${!SOURCE_ROWS[@]}"; do IFS=$'\t' read -r SOURCE_ID SOURCE_NAME _SOURCE_URL <<<"${SOURCE_ROWS[$i]}" IDS+=("$SOURCE_ID") NAMES+=("$SOURCE_NAME") printf " %2d) %-24s %s\n" "$((i + 1))" "$SOURCE_NAME" "$SOURCE_ID" done echo echo " a) all sources above" echo " Enter) preset: ${NAMES[0]}" read -r -p "Sources [a, 1-${#IDS[@]}, Enter]: " SOURCE_CHOICE SELECTED_FLAG="" case "$SOURCE_CHOICE" in "" | "Habbo" | "habbo" | "habbo.com") # Habbo is the first default preset (Habbo (COM)). SELECTED_FLAG="--sources=${IDS[0]}" SOURCE_LABEL="${NAMES[0]}" ;; a | A | all) SOURCE_LABEL="all sources" ;; *) SELECTED_IDS=() IFS=', ' read -r -a CHOICES <<<"$SOURCE_CHOICE" for CHOICE in "${CHOICES[@]}"; do [ -z "$CHOICE" ] && continue case "$CHOICE" in *[!0-9]* | "") echo "Invalid choice: '$CHOICE'" >&2 exit 1 ;; *) if [ "$CHOICE" -lt 1 ] || [ "$CHOICE" -gt "${#IDS[@]}" ]; then echo "Out of range: $CHOICE" >&2 exit 1 fi SELECTED_IDS+=("${IDS[$((CHOICE - 1))]}") ;; esac done if [ "${#SELECTED_IDS[@]}" -eq 0 ]; then echo "No sources selected." >&2 exit 1 fi SELECTED_FLAG="--sources=$(IFS=,; echo "${SELECTED_IDS[*]}")" SOURCE_LABEL="${#SELECTED_IDS[@]} source(s)" ;; esac # ── Step 2: what may be changed ────────────────────────────────────────────── cat <&2 exit 1 ;; esac echo printf 'Running: %s against %s\n' "${ACTIONS[1]}" "$SOURCE_LABEL" if [ -n "$CONFIRM" ]; then read -r -p "$CONFIRM" REPLY if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then echo "Cancelled." exit 0 fi fi echo # shellcheck disable=SC2086 "${RUN[@]}" $SELECTED_FLAG "${ACTION_FLAGS[@]}"