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
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.
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
tenantId?
string
options?
disposition?
"inline" | "attachment"
Returns
Promise<string>
upload()
> upload(content, input): Promise<FileRecord>
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
input
Returns
Promise<FileRecord>