Skip to content

basalt / files/src / Files

Class: Files ​

Defined in: files/src/files.ts:295

Upload pipeline over a storage Disk: validates size/type, enforces a per-tenant quota, writes the bytes, records metadata, and emits hooks. Every operation is tenant-scoped; storage access runs in the resolved tenant's context so files are isolated whether called from a request or a job.

Constructors ​

Constructor ​

> new Files(options, tenancyActive?): Files

Defined in: files/src/files.ts:307

Parameters ​

options ​

FilesOptions

tenancyActive? ​

() => boolean

Whether the host app registered @basaltkit/tenancy. filesPlugin wires this to the container's 'tenancy:active' metadata marker — a signal, not an import, so this generic package never depends on the opt-in SaaS layer. Defaults to false (single-tenant).

Returns ​

Files

Methods ​

canStreamDownloads() ​

> canStreamDownloads(): boolean

Defined in: files/src/files.ts:642

Whether downloadStream works on this disk — i.e. its driver implements getStream (local, S3, Azure, GCS do; a custom one may not). Lets a caller take the streaming path where it exists and buffer where it does not, instead of catching STORAGE_GET_STREAM_UNSUPPORTED.

Returns ​

boolean


delete() ​

> delete(id, tenantId?): Promise<void>

Defined in: files/src/files.ts:693

Parameters ​

id ​

string

tenantId? ​

string

Returns ​

Promise<void>


download() ​

> download(id, tenantId?, options?): Promise<{ content: Buffer; record: FileRecord; }>

Defined in: files/src/files.ts:623

The file's bytes and record. With requireScan, throws while the file is quarantined — except for { bypassQuarantine: true }, which is for the scanner itself (it must read the bytes it is about to judge). Never pass it on a path that serves users.

Parameters ​

id ​

string

tenantId? ​

string

options? ​
bypassQuarantine? ​

boolean

Returns ​

Promise<{ content: Buffer; record: FileRecord; }>


downloadStream() ​

> downloadStream(id, tenantId?, options?): Promise<{ record: FileRecord; stream: Readable; }>

Defined in: files/src/files.ts:661

The file's record and a stream of its bytes — the same contract as download (quarantine included), without holding the file in memory. Requires a disk whose driver implements getStream; otherwise the disk throws STORAGE_GET_STREAM_UNSUPPORTED.

ts
const { record, stream } = await files.downloadStream(id)
reply.header('content-type', record.contentType)
await pipeline(stream, reply.raw)

The caller MUST consume the stream or destroy() it — an abandoned stream holds a connection (S3, Azure, GCS) or a file descriptor (local) open.

Parameters ​

id ​

string

tenantId? ​

string

options? ​
bypassQuarantine? ​

boolean

Returns ​

Promise<{ record: FileRecord; stream: Readable; }>


get() ​

> get(id, tenantId?): Promise<FileRecord | null>

Defined in: files/src/files.ts:609

Parameters ​

id ​

string

tenantId? ​

string

Returns ​

Promise<FileRecord | null>


list() ​

> list(tenantId?): Promise<FileRecord[]>

Defined in: files/src/files.ts:613

Parameters ​

tenantId? ​

string

Returns ​

Promise<FileRecord[]>


markScanned() ​

> markScanned(id, result, tenantId?): Promise<FileRecord>

Defined in: files/src/files.ts:704

Records the result of an out-of-band scan (antivirus, moderation, …).

Parameters ​

id ​

string

result ​
clean ​

boolean

detail? ​

string

tenantId? ​

string

Returns ​

Promise<FileRecord>


temporaryUrl() ​

> temporaryUrl(id, expiresIn, tenantId?, options?): Promise<string>

Defined in: files/src/files.ts:680

Signed download URL — served Content-Disposition: attachment by default so an uploaded HTML/SVG file can never render top-level on the storage origin; pass { disposition: 'inline' } when in-browser rendering is deliberate (embedded <img>/<video> uses render regardless).

Parameters ​

id ​

string

expiresIn ​

DurationInput

tenantId? ​

string

options? ​
disposition? ​

"inline" | "attachment"

Returns ​

Promise&lt;string&gt;


upload() ​

> upload(content, input): Promise&lt;FileRecord&gt;

Defined in: files/src/files.ts:346

Validates, enforces the quota, stores and records one file.

content is a buffer or a stream (UploadContent). A stream is read once: its size is enforced while it arrives (the source is cancelled past validate.maxSize), its SHA-256 computed on the fly and — with validate.sniff — its type checked on the first 64 KiB.

On a disk whose driver implements putStream (BK-019) the bytes go straight to the backend: this class holds only the sniff window (64 KiB), and the driver only what its upload protocol needs (one S3 multipart part per slot, the Azure SDK's block buffers) — never up to maxSize. Otherwise — a driver with no streaming capability, an unbounded validate.maxSize with no declared contentLength, or a custom checkQuota, which needs the size before the write — the accepted bytes are buffered (at most maxSize of them) and written with disk.put.

Parameters ​

content ​

UploadContent

input ​

UploadInput

Returns ​

Promise&lt;FileRecord&gt;

Released under the MIT License.