#!/usr/bin/env bash set -euo pipefail cd -- "$(dirname -- "${BASH_SOURCE[0]}")" export PATH="$PWD/.runtime/node/bin:$PATH" if ! command -v node >/dev/null 2>&1 || ! node -e 'const [major, minor] = process.versions.node.split(".").map(Number); if (major < 22 || major === 22 && minor < 13) process.exit(1); require("node:sqlite")' >/dev/null 2>&1 || ! command -v npm >/dev/null 2>&1; then missing=() for tool in curl tar sha256sum; do command -v "$tool" >/dev/null 2>&1 || missing+=("$tool") done if ((${#missing[@]})); then if command -v apt-get >/dev/null 2>&1; then runner=() if [[ $(id -u) != 0 ]]; then command -v sudo >/dev/null 2>&1 || { echo 'Install curl, tar and coreutils, then rerun install.sh.' >&2; exit 1; } runner=(sudo) fi "${runner[@]}" apt-get update "${runner[@]}" apt-get install -y curl ca-certificates tar coreutils else echo 'Install curl, tar and coreutils, then rerun install.sh.' >&2 exit 1 fi fi case "$(uname -s)" in Linux) platform=linux ;; Darwin) platform=darwin ;; *) echo 'Install Node.js >=22.13 with npm manually.' >&2; exit 1 ;; esac case "$(uname -m)" in x86_64|amd64) arch=x64 ;; aarch64|arm64) arch=arm64 ;; *) echo 'Install Node.js >=22.13 with npm manually.' >&2; exit 1 ;; esac version=v24.18.0 archive="node-$version-$platform-$arch.tar.gz" base="https://nodejs.org/dist/$version" temp_dir=$(mktemp -d) trap 'rm -rf -- "$temp_dir"' EXIT curl --fail --silent --show-error --location "$base/$archive" -o "$temp_dir/$archive" curl --fail --silent --show-error --location "$base/SHASUMS256.txt" -o "$temp_dir/SHASUMS256.txt" (cd "$temp_dir"; awk -v file="$archive" '$2 == file { print; found=1 } END { if (!found) exit 1 }' SHASUMS256.txt > checksum; sha256sum -c checksum) mkdir -p .runtime tar -xzf "$temp_dir/$archive" -C .runtime rm -rf .runtime/node mv ".runtime/node-$version-$platform-$arch" .runtime/node fi npm ci --omit=dev --no-audit --no-fund node - <<'JS' const fs = require('node:fs'); fs.mkdirSync('data', { recursive: true }); if (!fs.existsSync('.passwd')) { fs.writeFileSync('.passwd', require('node:crypto').randomBytes(15).toString('base64url') + '\n', { flag: 'wx', mode: 0o600 }); console.log('Created .passwd. Read or edit it to set the login password.'); } JS printf 'Installed. Start with ./run.sh\n'