#!/bin/bash # Script to install importmap packages using npm and copy them to assets/vendor # This runs during Docker build to bake packages into the image set -e cd "$(dirname "$0")/.." echo "Installing npm packages for Asset Mapper..." # Install packages via npm if [ -f "package.json" ]; then npm ci --prefer-offline --no-audit --no-fund else echo "Error: package.json not found" exit 1 fi # Create assets/vendor directory mkdir -p assets/vendor # Function to copy package entry point from node_modules to assets/vendor copy_package() { local pkg_name=$1 local target_dir=$2 # Handle scoped packages (e.g., @noble/curves/secp256k1) local source_dir="" if [[ $pkg_name == @* ]]; then # Scoped package - need to handle subpaths local base_pkg=$(echo "$pkg_name" | cut -d'/' -f1-2) source_dir="node_modules/$base_pkg" else # Regular package local base_pkg=$(echo "$pkg_name" | cut -d'/' -f1) source_dir="node_modules/$base_pkg" fi if [ ! -d "$source_dir" ]; then echo " ⚠ Package not found: $pkg_name (searched in $source_dir)" return 1 fi # Create target directory mkdir -p "$target_dir" # Try to find the entry point file local entry_point="" # Check package.json for exports/main/module fields if [ -f "$source_dir/package.json" ]; then # Try to parse package.json for the right entry point local main_file=$(node -e "const pkg = require('./$source_dir/package.json'); console.log(pkg.exports?.['.']?.import || pkg.module || pkg.main || 'index.js');" 2>/dev/null || echo "index.js") main_file=$(echo "$main_file" | xargs) # trim whitespace # Try various locations for candidate in "$source_dir/$main_file" "$source_dir/dist/$main_file" "$source_dir/esm/$main_file" "$source_dir/es/$main_file"; do if [ -f "$candidate" ]; then entry_point="$candidate" break fi done fi # Fallback: try common locations if [ -z "$entry_point" ]; then for candidate in "$source_dir/dist/index.js" "$source_dir/index.js" "$source_dir/esm/index.js" "$source_dir/es/index.js" "$source_dir/main.js"; do if [ -f "$candidate" ]; then entry_point="$candidate" break fi done fi # Final fallback: find any .js file if [ -z "$entry_point" ]; then entry_point=$(find "$source_dir" -name "*.js" -type f | grep -E "(index|main|dist.*index)" | head -1) if [ -z "$entry_point" ]; then entry_point=$(find "$source_dir" -maxdepth 2 -name "*.js" -type f | head -1) fi fi if [ -n "$entry_point" ] && [ -f "$entry_point" ]; then cp "$entry_point" "$target_dir/index.js" echo " ✓ Copied $pkg_name" return 0 else echo " ✗ Failed to find entry point for $pkg_name" return 1 fi } # Parse importmap.php to get packages that need installation # We'll extract packages with 'version' but no 'path' php -r " require 'importmap.php'; \$map = include 'importmap.php'; \$packages = []; foreach(\$map as \$name => \$config) { if (isset(\$config['version']) && !isset(\$config['path'])) { // Extract base package name (handle subpaths like 'quill/dist/quill.core.css') \$baseName = explode('/', \$name)[0]; if (!isset(\$packages[\$baseName])) { \$packages[\$baseName] = \$config['version']; } } } foreach(\$packages as \$name => \$version) { echo \$name . PHP_EOL; } " > /tmp/importmap_packages.txt # Copy each package while IFS= read -r pkg_name; do if [ -n "$pkg_name" ]; then # Handle scoped packages and create proper directory structure target_dir="assets/vendor/$pkg_name" copy_package "$pkg_name" "$target_dir" || true fi done < /tmp/importmap_packages.txt # Also handle CSS files that might be in subpaths # For CSS files, we need to copy the entire package structure echo "Copying CSS assets..." rm -f /tmp/importmap_packages.txt echo "Done installing importmap packages"