# Install from caches filled by download-deps.ps1. Unpacks the official Node zip # into .offline-cache/node/runtime and prepends it to PATH so the offline machine # does not need a system Node. Fails if any lockfile package is missing from # .offline-store (no registry access). # # Usage (repo root): powershell -File scripts/offline/install-deps.ps1 [-Build] [CmdletBinding()] param( [switch]$Build ) $ErrorActionPreference = 'Stop' Set-StrictMode -Version Latest $Root = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path Set-Location $Root function Import-OfflineNode { $nodeCache = Join-Path $Root '.offline-cache\node' $metaPath = Join-Path $nodeCache 'runtime.json' if (-not (Test-Path $metaPath)) { throw "Missing $metaPath. Run scripts/offline/download-deps.ps1 on a networked machine first, then copy the checkout." } $meta = Get-Content $metaPath -Raw | ConvertFrom-Json $archivePath = Join-Path $nodeCache ([string]$meta.archive) $runtimeDir = Join-Path $nodeCache 'runtime' $nodeHome = Join-Path $runtimeDir ("node-v{0}-{1}" -f $meta.version, $meta.platform) if (-not (Test-Path (Join-Path $nodeHome 'node.exe'))) { if (-not (Test-Path $archivePath)) { throw "Missing Node archive $archivePath. Re-run download-deps.ps1." } if (Test-Path $runtimeDir) { Remove-Item -Recurse -Force $runtimeDir } New-Item -ItemType Directory -Force -Path $runtimeDir | Out-Null Expand-Archive -LiteralPath $archivePath -DestinationPath $runtimeDir } if (-not (Test-Path (Join-Path $nodeHome 'node.exe'))) { throw "Unpacked Node is missing: $nodeHome\node.exe" } $env:PATH = "$nodeHome;$env:PATH" return $nodeHome } $nodeHome = Import-OfflineNode $storeDir = Join-Path $Root '.offline-store' $corepackHome = Join-Path $Root '.offline-cache\corepack' if (-not (Test-Path $storeDir)) { throw "Missing $storeDir. Run scripts/offline/download-deps.ps1 on a networked machine first, then copy the checkout." } if (-not (Test-Path $corepackHome)) { throw "Missing $corepackHome. Re-run download-deps.ps1 so Corepack pnpm is cached in-repo." } $env:COREPACK_HOME = $corepackHome $env:COREPACK_ENABLE_NETWORK = '0' $manifest = Get-Content (Join-Path $Root 'package.json') -Raw | ConvertFrom-Json $packageManager = [string]$manifest.packageManager $corepack = Join-Path $nodeHome 'corepack.cmd' Write-Host "Offline install $packageManager from $storeDir (Node $(& (Join-Path $nodeHome 'node.exe') --version))" & $corepack pnpm install --offline --frozen-lockfile --store-dir $storeDir if ($Build) { Write-Host 'Building host/client libs, then the web frontend' npm run build:lib & $corepack pnpm --dir apps/web run build Write-Host "Build complete. Start the UI with: `"$nodeHome\corepack.cmd`" pnpm dsh web" } else { Write-Host 'Install complete. For dsh web also run: powershell -File scripts/offline/install-deps.ps1 -Build' }