#!/usr/bin/env bash # Pack @bytelyst/* tarballs from the sibling common-plat repo for # self-contained Docker builds that don't need the Gitea npm registry. # # Usage: # ./scripts/docker-prep.sh # pack tarballs + rewrite package.json # ./scripts/docker-prep.sh --restore # undo rewrite set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" COMMON_PLAT="${REPO_DIR}/../learning_ai_common_plat" TARBALL_DIR="${REPO_DIR}/.docker-deps" # ── Restore mode ─────────────────────────────────────────────────── if [[ "${1:-}" == "--restore" ]]; then echo "Restoring original package.json files..." for bak in $(find "$REPO_DIR" -name "package.json.bak" -not -path "*/node_modules/*"); do mv "$bak" "${bak%.bak}" echo " Restored ${bak%.bak}" done rm -rf "$TARBALL_DIR" echo "Done." exit 0 fi # ── Pack mode ────────────────────────────────────────────────────── echo "=== docker-prep: packing @bytelyst/* tarballs ===" rm -rf "$TARBALL_DIR" mkdir -p "$TARBALL_DIR" # Build all packages first echo "Building @bytelyst/* packages..." (cd "$COMMON_PLAT" && pnpm -r --filter './packages/**' build) # Pack each package and build a mapping of name → tarball filename # (uses a temp file instead of associative array for bash 3.2 compat) TARBALL_MAP_FILE=$(mktemp) trap 'rm -f "$TARBALL_MAP_FILE"' EXIT for pkg_dir in "$COMMON_PLAT"/packages/*/; do pkg_name=$(node -p "require('${pkg_dir}package.json').name" 2>/dev/null || true) if [[ -z "$pkg_name" ]]; then continue; fi echo " Packing $pkg_name..." tarball=$(cd "$pkg_dir" && pnpm pack --pack-destination "$TARBALL_DIR" 2>/dev/null | tail -1) filename=$(basename "$tarball") echo "${pkg_name}=${filename}" >> "$TARBALL_MAP_FILE" echo " -> $filename" done # ── Rewrite package.json files ───────────────────────────────────── echo "" echo "Rewriting package.json @bytelyst/* refs to .docker-deps/ tarballs..." rewrite_package_json() { local pkg_file="$1" local rel_prefix="$2" # relative path from package.json dir to repo root if [[ ! -f "$pkg_file" ]]; then return; fi # Backup cp "$pkg_file" "${pkg_file}.bak" local tmp="${pkg_file}.tmp" cp "$pkg_file" "$tmp" while IFS='=' read -r pkg_name tarball; do [[ -z "$pkg_name" ]] && continue # Replace "^0.1.0" (or any semver/file: ref) with "file:../.docker-deps/" sed -i '' "s|\"${pkg_name}\": \"[^\"]*\"|\"${pkg_name}\": \"file:${rel_prefix}.docker-deps/${tarball}\"|g" "$tmp" done < "$TARBALL_MAP_FILE" mv "$tmp" "$pkg_file" echo " Rewrote $pkg_file" } # Backend package.json rewrite_package_json "${REPO_DIR}/backend/package.json" "../" # Web package.json rewrite_package_json "${REPO_DIR}/web/package.json" "../" # ── Inject pnpm.overrides for transitive @bytelyst/* deps ───────── # Tarball packages may depend on other @bytelyst/* packages (e.g. # @bytelyst/fastify-core → @bytelyst/errors). Without overrides, pnpm # tries to fetch them from the npm registry which fails. inject_overrides() { local pkg_file="$1" local rel_prefix="$2" if [[ ! -f "$pkg_file" ]]; then return; fi local overrides="" while IFS='=' read -r pkg_name tarball; do [[ -z "$pkg_name" ]] && continue if [[ -n "$overrides" ]]; then overrides="$overrides, "; fi overrides="$overrides\"${pkg_name}\": \"file:${rel_prefix}.docker-deps/${tarball}\"" done < "$TARBALL_MAP_FILE" if [[ -n "$overrides" ]]; then node -e " const fs = require('fs'); const p = JSON.parse(fs.readFileSync('${pkg_file}', 'utf8')); p.pnpm = p.pnpm || {}; p.pnpm.overrides = { ...(p.pnpm.overrides || {}), ...JSON.parse('{${overrides}}') }; fs.writeFileSync('${pkg_file}', JSON.stringify(p, null, 2) + '\n'); " echo " Injected pnpm.overrides into $pkg_file" fi } inject_overrides "${REPO_DIR}/backend/package.json" "../" inject_overrides "${REPO_DIR}/web/package.json" "../" echo "" echo "Done. Tarballs in $TARBALL_DIR" echo "" echo "To build Docker images:" echo " docker compose build" echo "" echo "To restore after build:" echo " ./scripts/docker-prep.sh --restore"