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
- Create or select a repo in the app (or
POST /api/reposwith a session). - Create an API key from the API keys page.
- Shape the tree:
create_directory,put_file_text,fs_move,fs_delete, symlinks, presigned upload/commit. - Parallel work:
create_branch, edit on the feature branch,merge_branches(andmerge_branches_resolveon conflicts). - Batch publishes:
create_staging→ upload blobs →put_staging(many paths) →commit_staging. - Run
FBB_API_TOKEN=… npm run test:apiagainst a dev server for a full client smoke test.