SPB Git

spb/spbgit Public MIT

SPB Git — the platform hosting itself

JavaScript 73.9% CSS 11.7% Nunjucks 11.6% Shell 2.7%
2.4 KB · 64 lines javascript
Raw Blame History
1/**2 * ─────────────────────────────────────────────3 *  SPB Git — Personal Git Platform4 * ─────────────────────────────────────────────5 *  Author  : Simon-Pierre Boucher6 *  Contact : contact@spboucher.ai7 *  File    : cli/lib/api.mjs8 *  Purpose : SPB Git API client (native fetch, friendly errors)9 *  License : MIT © Simon-Pierre Boucher10 * ─────────────────────────────────────────────11 */1213import pc from 'picocolors';1415/** Exit codes per CLAUDE.md §6.3. */16export const EXIT = Object.freeze({ OK: 0, USER: 1, NETWORK: 2, PARTIAL: 3 });1718/**19 * Perform an API request against the configured server.20 * @param {object} config CLI config21 * @param {string} method22 * @param {string} path e.g. `/api/v1/repos`23 * @param {object} [body]24 * @param {{auth?: boolean}} [opts]25 * @returns {Promise<any>} parsed JSON26 */27export async function api(config, method, path, body, opts = {}) {28  const headers = { Accept: 'application/json' };29  if (opts.auth !== false && config.token) headers.Authorization = `Bearer ${config.token}`;30  if (body !== undefined) headers['Content-Type'] = 'application/json';31  let response;32  try {33    response = await fetch(`${config.server.replace(/\/+$/, '')}${path}`, {34      method,35      headers,36      body: body === undefined ? undefined : JSON.stringify(body),37    });38  } catch (err) {39    console.error(pc.red(`✗ Cannot reach ${config.server} — ${err.cause?.code ?? err.message}`));40    console.error('  Check the server URL in ~/.spbgit/config.json or run: spbgit doctor');41    process.exit(EXIT.NETWORK);42  }43  const text = await response.text();44  let json = null;45  try {46    json = text ? JSON.parse(text) : null;47  } catch {48    /* non-JSON error body */49  }50  if (!response.ok) {51    if (response.status === 401) {52      console.error(pc.red('✗ Token invalid or revoked.'));53      console.error('  Run `spbgit token new` on a machine with a valid token, then `spbgit init`.');54      process.exit(EXIT.NETWORK);55    }56    const message = json?.error?.message ?? `HTTP ${response.status}`;57    const error = new Error(message);58    error.status = response.status;59    error.code = json?.error?.code;60    throw error;61  }62  return json;63}64