B2 Files
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.
Global Arguments
| Argument | Type | Description |
|---|---|---|
| applicationKeyId | string | B2 application key ID (master or scoped). See the README for the |
| applicationKey | string | B2 application key — supply via vault.get(), never inline. |
| authHost? | string | Override the B2 authorize host (testing only). Defaults to |
| bucketName? | string | Bucket this model manages. Required by sync/delete/hide/copy/update. |
| bucketId? | string | Bucket ID matching bucketName. Supplying it saves one class-C |
| allowFileDestruction? | boolean | Acknowledge that delete and hide remove or mask a file version. Doing |
| allowComplianceRetention? | boolean | Acknowledge that compliance-mode retention is irreversible — it cannot |
| Argument | Type | Description |
|---|---|---|
| mode? | enum | Defaults to "aggregate": one summary resource per bucket, no per-file |
| bucketNames? | array | Scan exactly these buckets. Overrides globalArgs.bucketName. Omit both |
| prefix? | string | Server-side file-name prefix filter. Optional in aggregate mode; |
| groupBy? | enum | Defaults to "none" — one aggregate per bucket. "topLevel" additionally |
| includeVersions? | boolean | Defaults to true: list every file VERSION (b2_list_file_versions), |
| maxFileCount? | number | Files requested per list page. Defaults to 10000, the B2 maximum. B2 |
| maxPages? | number | Hard cap on list pages per bucket. Defaults to 50 (up to 500,000 files |
| maxFiles? | number | Maximum per-file resources to emit. REQUIRED in detailed mode; ignored |
| Argument | Type | Description |
|---|---|---|
| fileId? | string | The file version to act on. Exact and free of a lookup; prefer it when |
| fileName? | string | File name to resolve to its newest version via b2_list_file_versions |
| Argument | Type | Description |
|---|---|---|
| fileName | string | File name to hide. B2 writes a hide marker as a new version; the |
| allowFileDestruction? | boolean | Acknowledge the destruction for this run only. Equivalent to the global |
| Argument | Type | Description |
|---|---|---|
| sourceFileId | string | File version to copy from. Must be readable by the calling key. |
| fileName | string | File name to create in the destination. |
| destinationBucketId? | string | Destination bucket ID. Defaults to this model's bucket. Both buckets |
| destinationBucketName? | string | Name of the destination bucket, recorded in the snapshot. Resolved from |
| contentType? | string | Content type for the copy. Only meaningful with metadataDirective |
| fileInfo? | record | Replacement file metadata. Only meaningful with metadataDirective |
| metadataDirective? | enum | Whether to carry the source metadata over ("COPY", the B2 default) or |
| range? | string | Byte range of the source to copy, e.g. "bytes=0-1023". Omit to copy the |
Resources
Declare SPDX license (MIT) in manifest.
Modified 1 behaviors
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.
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.
- 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