Skip to content
github-actions[bot] edited this page Oct 4, 2026 · 2 revisions

Google Cloud Storage (GCS)

Typed Google Cloud Storage JSON API client for Deno, Bun, Node.js and Cloudflare Workers, with bearer-token or service-account authentication. Upload, download, list, inspect and delete objects, including resumable streamed uploads for large files. A lightweight, Web-API-only alternative to @google-cloud/storage for the operations it covers.

JSR JSR Score

Overview

GCS implements this repository's canonical object-storage interface — putObject, getObject, deleteObject, listObjects, headObject — on top of the Google Cloud Storage JSON API. It uses RESTler for transport and Guardian for runtime response validation.

GCS's own field names differ from the canonical interface (name instead of key, pageToken/nextPageToken instead of a continuation token); the client translates between them internally so the public method/parameter names stay consistent with this repository's other object-storage connects.

Testing your code

Your tests don't need to fake HTTP. Have your code take a GCS instance and pass in a stand-in that returns the shapes from @tundraconnect/gcs/schemas or throws a real GCSError:

import { GCSError } from '@tundraconnect/gcs/errors';

const outage = new GCSError('BACKEND_ERROR', { status: 503 });
console.log(outage.code);

To exercise the client itself against a fake transport, subclass it and reassign the protected _fetch.

Documentation

Topic Description
API Client configuration and endpoint methods
Errors Error codes and diagnostic metadata
Schemas Public Guardian schemas and inferred types

Upstream

Installation

Deno:

deno add jsr:@tundraconnect/gcs

Bun:

bunx jsr add @tundraconnect/gcs

Node.js:

npx jsr add @tundraconnect/gcs

Authentication

GCS supports two auth modes, both modelled as the standard auth option. auth may also be omitted entirely for anonymous reads against a public bucket.

Mode 1 — Bearer token (simple)

Supply an already-obtained OAuth2 access token — from gcloud auth print-access-token, Workload Identity, or your own refresh logic:

import { GCS } from '@tundraconnect/gcs';

const client = new GCS({
  auth: { type: 'BEARER', token: 'ya29.a0AfH6SMC...' },
});

Mode 2 — Service account (full flow)

Supply a service account's client_email/private_key (from its downloaded JSON key). GCS signs an RS256 JWT, exchanges it for a short-lived access token, and caches that token until it nears expiry — entirely with Web Crypto (crypto.subtle), no Node-specific APIs:

import { GCS } from '@tundraconnect/gcs';

const client = new GCS({
  auth: {
    type: 'CUSTOM',
    clientEmail: 'svc@my-project.iam.gserviceaccount.com',
    privateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
    // Optional — defaults to the full-control scope.
    scope: 'https://www.googleapis.com/auth/devstorage.read_write',
  },
});

Quick Start

import { GCS } from '@tundraconnect/gcs';

const client = new GCS({
  auth: { type: 'BEARER', token: 'ya29....' },
});

await client.putObject({
  bucket: 'my-bucket',
  key: 'reports/2024-01.csv',
  body: new TextEncoder().encode('a,b,c\n1,2,3\n'),
  contentType: 'text/csv',
});

const { body, metadata } = await client.getObject({
  bucket: 'my-bucket',
  key: 'reports/2024-01.csv',
});
console.log(metadata.size, await body.text());

const { objects } = await client.listObjects({
  bucket: 'my-bucket',
  prefix: 'reports/',
});
for (const object of objects) console.log(object.name);

await client.deleteObject({ bucket: 'my-bucket', key: 'reports/2024-01.csv' });

Large files

import { GCS } from '@tundraconnect/gcs';

const client = new GCS({ auth: { type: 'BEARER', token: 'ya29....' } });

// Upload from a stream as a resumable upload — one 8 MiB chunk in memory
// at a time; contentType/metadata travel with the session.
const file = await Deno.open('backup.tar');
await client.putObjectStream({
  bucket: 'backups',
  key: 'backup.tar',
  body: file.readable,
});

// Download as a stream — nothing buffered.
const { body } = await client.getObjectStream({
  bucket: 'backups',
  key: 'backup.tar',
});
await body.pipeTo((await Deno.create('restored.tar')).writable);

See API → Streaming.

License

MIT. Part of Tundra Connect, typed vendor API clients for Deno, Bun, Node.js and Cloudflare Workers.

Clone this wiki locally