Skip to content

Package reference

Mirrors the package README (single source). Install @basaltkit/storage-gcs v1.3.2 — npm · source.

<p align="center"> <a href="https://basaltkit-docs.pages.dev"> <img src="https://basaltkit-docs.pages.dev/social-card.png" alt="Basalt" width="440"> </a> </p>

@basaltkit/storage-gcs ​

Google Cloud Storage driver for @basaltkit/storage: stores files on GCS without changing your app's code. You need this module when you run on Google Cloud and want GCS instead of S3 or local disk.

Installation ​

bash
pnpm add @basaltkit/storage-gcs @google-cloud/storage

@google-cloud/storage is a peer dependency. Credentials follow GCP's standard chain (ADC, keyFilename, service account).

Usage ​

ts
import { storagePlugin } from '@basaltkit/storage'
import { GcsStorageDriver } from '@basaltkit/storage-gcs'

storagePlugin({
  disks: { uploads: { driver: new GcsStorageDriver({ bucket: 'my-bucket', projectId: 'my-project' }) } },
})

Implements the StorageDriver contract — put, get, exists, delete, list, and signed URLs (temporaryUrl). Per-tenant isolation, key validation and the opt-in upload limits all happen in Disk above this driver, so they apply here unchanged.

Options reference ​

new GcsStorageDriver(options: GcsDriverOptions):

OptionTypeDefaultPurpose
bucketstring— (required)Bucket the disk maps to.
projectIdstringfrom the ambient GCP credentialsPin the project explicitly instead of inheriting it from ADC.
keyFilenamestringADC chainPath to a service-account JSON key. Omit it on GCE/GKE/Cloud Run and let Application Default Credentials work.
clientGcsBucketLike—Pre-built bucket handle. Bypasses projectId/keyFilename and the dynamic @google-cloud/storage import — used by tests, or to reuse a client you already authenticate yourself.

The @google-cloud/storage module is imported lazily, on the first operation, so installing this package without using it costs nothing at boot.

Signed URLs and content disposition ​

temporaryUrl signs a read URL and pins the response disposition into the signature (responseDisposition). It defaults to attachment — matching the Disk default — so an uploaded HTML or SVG object downloads instead of rendering top-level on the storage origin. Pass { disposition: 'inline' } through disk.temporaryUrl(path, expiresIn, options) when in-browser rendering is deliberate.

Direct browser uploads ​

temporaryUploadUrl (via disk.temporaryUploadUrl(...)) signs a V4 write URL. The Content-Type is signed, and a declared contentLength is signed as x-goog-content-length-range: n,n, so GCS rejects any other type or size. Send the returned headers verbatim. checksumSha256 is refused with STORAGE_UPLOAD_URL_UNSUPPORTED (GCS verifies MD5/CRC32C only). A custom client fake receives the config typed as GcsSignedUrlConfig.

delete() checks exists() first so it can return false for a missing object rather than throwing — that costs one extra round-trip per delete.

Streaming, copy and stat ​

All four optional capabilities are implemented:

CapabilityGCS callNotes
putStreamcreateWriteStreamA resumable upload GCS chunks itself, in bounded memory, so a body of unknown length streams fine — no contentLength needed. A declared one is verified by the Disk; the object is finalized only when the body ends cleanly.
getStreamcreateReadStreamReturns a Node Readable; consume it or destroy() it. GCS only discovers a missing object once the download starts, so STORAGE_FILE_NOT_FOUND arrives as an error on the stream, not as a rejected promise.
copyfile.copy()GCS rewrites the object server-side; the bytes never reach the process.
statgetMetadata(){ size, contentType, etag, lastModified } (GCS reports size as a string; it is coerced).

An injected fake client that omits one of these methods makes that capability report STORAGE_*_UNSUPPORTED instead of crashing.

Endpoint overrides are refused. V4 signatures are bound to the bucket host and file.getSignedUrl takes no endpoint, so { endpoint } on temporaryUrl / temporaryUploadUrl throws STORAGE_TEMPORARY_URL_UNSUPPORTED / STORAGE_UPLOAD_URL_UNSUPPORTED rather than minting a URL for the wrong host. Use a bucket-bound hostname (cname) on the @google-cloud/storage client.

Errors ​

ErrorCodeHTTPWhen
StorageFileNotFoundErrorSTORAGE_FILE_NOT_FOUND500get() on an object that doesn't exist (GCS error code: 404). Re-exported from @basaltkit/storage.

Any other GCS client error propagates unchanged. This driver defines no error classes of its own; the facade-level errors (STORAGE_INVALID_KEY, STORAGE_TOO_LARGE, STORAGE_CONTENT_TYPE, STORAGE_TEMPORARY_URL_UNSUPPORTED) are raised by Disk before the driver is reached. Storage errors carry no HTTP status, so the adapters surface them as a generic 500 INTERNAL_ERROR — catch and map them in your handler.

Hooks & events ​

None. Upload lifecycle events live in @basaltkit/files.

Testable without the cloud ​

The client (bucket) is injectable, so the driver's logic can be tested with a fake — no GCS required:

ts
new GcsStorageDriver({ bucket: 'b', client: fakeBucket })

How it connects to other modules ​

  • @basaltkit/storage — this is a driver for that package; the API (Disk, storagePlugin) comes from there.
  • Sibling drivers: S3StorageDriver (in core) and @basaltkit/storage-azure.

Guide: Storage.

Released under the MIT License.