Skip to main content

B2 Files

@sntxrr/b2-filesv2026.10.22.1· MIT· 13d agoBEHAVIORS
01README

Inventory and manage Backblaze B2 file versions via the Native API v4 — an aggregate scan that separates current bytes from the non-current versions a bucket with no hidden-version lifecycle rule pays for forever, plus sync, copy, and gated hide, delete and Object Lock updates.

02Behaviors1
@sntxrr/b2/filesv2026.08.06.1b2_files.ts

Global Arguments

ArgumentTypeDescription
applicationKeyIdstringB2 application key ID (master or scoped). See the README for the
applicationKeystringB2 application key — supply via vault.get(), never inline.
authHost?stringOverride the B2 authorize host (testing only). Defaults to
bucketName?stringBucket this model manages. Required by sync/delete/hide/copy/update.
bucketId?stringBucket ID matching bucketName. Supplying it saves one class-C
allowFileDestruction?booleanAcknowledge that delete and hide remove or mask a file version. Doing
allowComplianceRetention?booleanAcknowledge that compliance-mode retention is irreversible — it cannot
fn scan(mode?: enum, bucketNames?: array, prefix?: string, groupBy?: enum, includeVersions?: boolean, maxFileCount?: number, maxPages?: number, maxFiles?: number)
Factory discovery — inventory file versions and write one aggregate
ArgumentTypeDescription
mode?enumDefaults to "aggregate": one summary resource per bucket, no per-file
bucketNames?arrayScan exactly these buckets. Overrides globalArgs.bucketName. Omit both
prefix?stringServer-side file-name prefix filter. Optional in aggregate mode;
groupBy?enumDefaults to "none" — one aggregate per bucket. "topLevel" additionally
includeVersions?booleanDefaults to true: list every file VERSION (b2_list_file_versions),
maxFileCount?numberFiles requested per list page. Defaults to 10000, the B2 maximum. B2
maxPages?numberHard cap on list pages per bucket. Defaults to 50 (up to 500,000 files
maxFiles?numberMaximum per-file resources to emit. REQUIRED in detailed mode; ignored
fn sync(fileId?: string, fileName?: string)
Read one file's current state and snapshot it. By fileId this is a cheap class-B b2_get_file_info; by fileName it is one class-C b2_list_file_versions that reports the NEWEST version, so a deleted file comes back as its hide marker rather than as not-found. Requires readFiles (fileId path) or listFiles (fileName path).
ArgumentTypeDescription
fileId?stringThe file version to act on. Exact and free of a lookup; prefer it when
fileName?stringFile name to resolve to its newest version via b2_list_file_versions
fn delete()
Permanently delete one file version (b2_delete_file_version) and write an exists=false tombstone. DESTRUCTIVE and not recoverable: requires allowFileDestruction as a global argument or a method input. Idempotent — a 404, or a 400 with b2Code file_not_present or no_such_file, is treated as success. Requires deleteFiles, plus listFiles when identifying the file by name, plus bypassGovernance to delete through governance retention.
fn hide(fileName: string, allowFileDestruction?: boolean)
Hide a file (b2_hide_file), writing a hide marker as its newest version so downloads by name stop resolving. The underlying data is retained and billed until a lifecycle rule reaps it. DESTRUCTIVE in effect — hiding a restic pack file makes the repository unreadable — so it requires allowFileDestruction as a global argument or a method input. Requires writeFiles. NOTE: pre-flight checks do not fire for a method named `hide`, so the guard is inside execute.
ArgumentTypeDescription
fileNamestringFile name to hide. B2 writes a hide marker as a new version; the
allowFileDestruction?booleanAcknowledge the destruction for this run only. Equivalent to the global
fn copy(sourceFileId: string, fileName: string, destinationBucketId?: string, destinationBucketName?: string, contentType?: string, fileInfo?: record, metadataDirective?: enum, range?: string)
Copy a file version server-side (b2_copy_file) into this model's bucket or another one, without moving bytes through swamp. Non-destructive: B2 writes a new version and never removes the source. Capped by B2 at 5 GB; larger files need the large-file copy path in @sntxrr/b2/transfer. Requires readFiles on the source and writeFiles on the destination.
ArgumentTypeDescription
sourceFileIdstringFile version to copy from. Must be readable by the calling key.
fileNamestringFile name to create in the destination.
destinationBucketId?stringDestination bucket ID. Defaults to this model's bucket. Both buckets
destinationBucketName?stringName of the destination bucket, recorded in the snapshot. Resolved from
contentType?stringContent type for the copy. Only meaningful with metadataDirective
fileInfo?recordReplacement file metadata. Only meaningful with metadataDirective
metadataDirective?enumWhether to carry the source metadata over ("COPY", the B2 default) or
range?stringByte range of the source to copy, e.g. "bytes=0-1023". Omit to copy the
fn update()
Set or clear a file version's legal hold (b2_update_file_legal_hold) and Object Lock retention (b2_update_file_retention), then re-read the file so the snapshot carries its full state rather than the slim update response. Setting compliance retention is IRREVERSIBLE and requires allowComplianceRetention. Requires writeFileLegalHolds / writeFileRetentions to change them, readFiles for the re-read, and bypassGovernance to shorten an existing governance lock.

Resources

aggregate(infinite)— Per-bucket (and optionally per-prefix) file inventory: current versus non-current object counts and bytes, with a truncation flag
file(infinite)— Snapshot of one B2 file version, instance-named file-<fileId>
03Previous Versions3
2026.10.14.1MIT(was none)

Declare SPDX license (MIT) in manifest.

Modified 1 behaviors

2026.08.06.1

Removes the file-destruction-acknowledged pre-flight check, which made delete unusable as documented.

Because swamp does not pass method inputs to checks, the check could only read globalArgs — so it rejected --input allowFileDestruction=true BEFORE execute ever received the flag, while its own error message instructed you to pass exactly that.

The consequence was worse than a self-contradicting message. With the per-run path blocked, the only way to delete anything was to set allowFileDestruction: true permanently on the model — so a check written to prevent accidental destruction was forcing you to arm destruction for good, on a model whose delete can leave a restic repository unreadable with no error until the next restore. It failed on the safe configuration and passed on the dangerous one.

The protection is unchanged. assertDestructionAllowed inside delete and hide still refuses without the acknowledgement; it now simply sees both the method input and the global argument, as it always should have. It also covers hide, which no pre-flight check could ever guard — checks fire only for methods named create/update/delete/action.

Both halves verified against live B2: the per-run acknowledgement now reaches execute, and delete without it still refuses.

Strictly compatible. This can only turn a failing run into a working one — nobody could have depended on delete being blocked, and if you set allowFileDestruction on the model as a workaround it still works, though you can now drop it and acknowledge per run instead. No schema, instance name, method or argument changed.

The test accompanying the removed check asserted its behaviour was correct, so the suite encoded the bug rather than catching it. Its replacement asserts the property that matters — every check applying to delete must pass on a model that has not pre-authorised destruction — and was verified to fail when the check is reintroduced.

2026.08.05.1

First publish of @sntxrr/b2/files — inventory and manage B2 file versions via the Native API v4.

Aggregate scan separates current bytes from the non-current versions a bucket with no hidden-version lifecycle rule pays for forever, plus sync, copy, and gated hide, delete and Object Lock updates.

Live-verified against a real account: a full fleet scan of 2,693,460 versions sized 39.49 GiB of non-current data. That run found and fixed three contract-level defects no mock test caught:

  • B2 omits legalHold and fileRetention entirely on buckets without Object Lock, so a zero lock count meant "not reported" rather than "not locked" — lockFieldsAbsentCount now models absent, unreadable and readable as three distinct states.
  • sync, delete and update forced a bucket-ID lookup their B2 calls never need when addressed by fileId, locking out bucket-restricted keys without listBuckets.
  • copy resolved the destination bucket name after the copy had landed, stranding a completed side effect behind a failed method.

Every version-derived metric is nullable: null means "not measured", never zero. Read the truncated flag before reading any byte total — the default maxPages of 50 caps buckets past roughly 500k versions.

04Stats
A
100 / 100
Downloads
38
Archive size
44.0 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License2/2earned
  • Verified public repository2/2earned
05Platforms
06Labels