Vectrum
Sign In
60 lines · 2.3 KB · JavaScript
// Downloads the PocketBase server into bin/ (run by `bun install`, or `bun run pocketbase:install`).
// lib/db.ts starts it when the app needs the database, unless PB_URL points at a server of your own.

import { execFileSync } from "node:child_process";
import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";

const VERSION = "0.40.4";

const root = path.resolve(import.meta.dirname, "..");
const exe = process.platform === "win32" ? "pocketbase.exe" : "pocketbase";
const target = path.join(root, "bin", exe);

const installed = () => {
  try {
    return execFileSync(target, ["--version"], { encoding: "utf8" }).trim().endsWith(VERSION);
  } catch {
    return false;
  }
};

if (process.env.PB_URL || process.env.PB_BINARY) {
  console.log("[pocketbase] PB_URL or PB_BINARY is set; not downloading PocketBase.");
  process.exit(0);
}
if (existsSync(target) && installed()) process.exit(0);

const os = { linux: "linux", darwin: "darwin", win32: "windows" }[process.platform];
const arch = { x64: "amd64", arm64: "arm64", arm: "armv7" }[process.arch];
if (!os || !arch) {
  console.error(`[pocketbase] No PocketBase build for ${process.platform}/${process.arch}. Install it yourself and set PB_BINARY.`);
  process.exit(1);
}

const url = `https://github.com/pocketbase/pocketbase/releases/download/v${VERSION}/pocketbase_${VERSION}_${os}_${arch}.zip`;
console.log(`[pocketbase] Downloading PocketBase ${VERSION} for ${os}/${arch}…`);
const res = await fetch(url);
if (!res.ok) {
  console.error(`[pocketbase] Download failed (${res.status}): ${url}`);
  process.exit(1);
}

const work = mkdtempSync(path.join(tmpdir(), "pocketbase-"));
try {
  const zip = path.join(work, "pocketbase.zip");
  writeFileSync(zip, Buffer.from(await res.arrayBuffer()));
  // unzip on Linux, bsdtar (which reads zip files) on macOS and Windows.
  try {
    execFileSync("unzip", ["-o", "-q", zip, exe, "-d", work], { stdio: "ignore" });
  } catch {
    execFileSync("tar", ["-xf", zip, "-C", work, exe], { stdio: "ignore" });
  }
  mkdirSync(path.dirname(target), { recursive: true });
  copyFileSync(path.join(work, exe), target);
  chmodSync(target, 0o755);
} finally {
  rmSync(work, { recursive: true, force: true });
}
console.log(`[pocketbase] Installed ${path.relative(root, target)}`);