Back to docs

Guide

Quick start for the public FileBackbone JavaScript client—directories, renames, parallel branches, merges, and multi-file staging in one commit. Full narrative + env vars + errors: docs/client-guide.md.

Initialize client

Use an API key as public_id.secret (Bearer). For browser sessions, omit token and pass csrfToken plus fetchImpl: window.fetch.bind(window).

import { FileBackboneClient } from 'reposys/client/filebackbone_client.js';

const client = new FileBackboneClient({
  baseUrl: process.env.FBB_API_BASE_URL || 'https://your-domain.example',
  token: process.env.FBB_API_TOKEN,
});

Errors

Failed responses throw FileBackboneApiError with status, body, and url. Merge conflicts and some staging races return 409.

import { FileBackboneClient, FileBackboneApiError } from 'reposys/client/filebackbone_client.js';

try {
  await client.put_file_text(repoId, { /* … */ });
} catch (e) {
  if (e instanceof FileBackboneApiError) {
    console.error(e.status, e.body);
  } else {
    throw e;
  }
}

Write a file (text branch commit)

Pass the current branch head as expected_head (from list_branches or the last mutation). Re-read the head after each write if the branch moves.

import { FileBackboneClient } from 'reposys/client/filebackbone_client.js';

const client = new FileBackboneClient({ baseUrl, token });
const repoId = Number(process.env.FBB_REPO_ID || 1);

const branches = await client.list_branches(repoId);
const main = branches.branches.find((b) => b.branch_name === 'main');
let head = main?.repo_commit_object_id || '';

await client.put_file_text(repoId, {
  branch: 'main',
  file_path: 'notes/hello.txt',
  content: 'hello\n',
  expected_head: head,
});

Directories and mv

create_directory scaffolds folders; fs_move renames or moves paths (same idea as mv). Refresh expected_head after each commit.

let head = mainHead; // from list_branches

await client.create_directory(repoId, {
  branch: 'main',
  path: 'project/docs',
  expected_head: head,
});
head = /* re-read branch head */;

await client.put_file_text(repoId, {
  branch: 'main',
  file_path: 'project/docs/README.md',
  content: '# Doc\n',
  expected_head: head,
});
head = /* re-read */;

await client.fs_move(repoId, {
  branch: 'main',
  from_path: 'project/docs/README.md',
  to_path: 'project/README.md',
  expected_head: head,
});

const tree = await client.get_tree(repoId, { branch: 'main', path: 'project' });

Switch branches, ship with merge

The API takes an explicit branch on every call—there is no hidden “current branch” for keys. Create a branch, do all reads/writes on that name, then merge into main when ready.

await client.create_branch(repoId, {
  branch_name: 'feature/ingest',
  from_branch: 'main',
});

await client.put_file_text(repoId, {
  branch: 'feature/ingest',
  file_path: 'config.json',
  content: '{}\n',
  expected_head: featureHead,
});

await client.merge_branches(repoId, {
  into_branch: 'main',
  from_branch: 'feature/ingest',
  expected_into_head: mainHead,
});

Staging: several files, one commit

Upload blobs with presign_blob_upload + put_presigned_object, register multiple paths in a single put_staging, then commit_staging—one atomic commit for the whole batch.

import { git_blob_object_id } from 'reposys/client/git_blob_object_id.js';

const st = await client.create_staging(repoId, {
  branch_name: 'main',
  label: 'import',
});
let etag = st.meta_etag;

// presign + PUT each body, build `paths` map: path → { op:'put', blob_object_id, tree_entry_mode:'100644' }
await client.put_staging(repoId, st.staging_id, { expected_meta_etag: etag, paths });
await client.commit_staging(repoId, st.staging_id, {
  expected_head: mainHead,
  message: 'Batch import\n',
});

Typical flow

  1. Create or select a repo in the app (or POST /api/repos with a session).
  2. Create an API key from the API keys page.
  3. Shape the tree: create_directory, put_file_text, fs_move, fs_delete, symlinks, presigned upload/commit.
  4. Parallel work: create_branch, edit on the feature branch, merge_branches (and merge_branches_resolve on conflicts).
  5. Batch publishes: create_staging → upload blobs → put_staging (many paths) → commit_staging.
  6. Run FBB_API_TOKEN=… npm run test:api against a dev server for a full client smoke test.
JavaScript SDK reference · HTTP API