Uplo
Services

Google Cloud Storage

Installation

Install package

npm i @uplo/service-gcs

Add service to Uplo

import { createGCSService } from '@uplo/service-gcs'

const uplo = createUplo({
  services: {
    google: createGCSService({
      isPublic: false,
      credentialsPath: path.resolve(__dirname, './config/gcp-credentials.json'),
      bucket: process.env.GCS_BUCKET,
    }),
  },
})

Options

  • bucket (required): Your bucket name where to store objects.
  • isPublic = false: Make uploaded files public
  • credentialsPath, credentials, projectId: Auth options. See Authentication
  • enforceContentLength = false: Refuse direct uploads with a different file size than declared. See Enforce file size
  • storagePath: Default file path in the bucket for attachments without their own storagePath. See Storage path

Authentication

The service forwards auth options to @google-cloud/storage. Pick one:

Key file path

createGCSService({
  bucket: process.env.GCS_BUCKET,
  credentialsPath: '/path/to/gcp-credentials.json',
})

Inline credentials

Useful when the service account JSON lives in a secret manager or env var.

createGCSService({
  bucket: process.env.GCS_BUCKET,
  credentials: {
    client_email: process.env.GCP_CLIENT_EMAIL,
    private_key: process.env.GCP_PRIVATE_KEY,
  },
  projectId: process.env.GCP_PROJECT_ID,
})

Application Default Credentials (ADC)

Pass no credentials. The SDK auto-discovers from the GOOGLE_APPLICATION_CREDENTIALS env var, gcloud user creds, or the workload's attached service account (Cloud Run, GKE, GCE, Cloud Functions).

createGCSService({
  bucket: process.env.GCS_BUCKET,
})

Direct Upload

CORS

This is an example CORS configuration for direct uploads. To setup CORS, read a guide in Google Cloud Docs.

[
  {
    "origin": ["https://www.example.com"],
    "method": ["PUT"],
    "responseHeader": [
      "Origin",
      "Content-Type",
      "Content-MD5",
      "Content-Disposition",
      "x-goog-content-length-range"
    ],
    "maxAgeSeconds": 3600
  }
]

x-goog-content-length-range is only needed with enforceContentLength.

Permissions

Before attaching a direct upload, Uplo reads the file metadata, which needs storage.objects.get.

Enforce file size

By default GCS accepts a direct upload of any size, even if validate.size checked the declared size. Set enforceContentLength: true to sign the declared size into the upload URL. GCS then refuses files with a different size (400 Bad Request).

createGCSService({
  bucket: process.env.GCS_BUCKET,
  enforceContentLength: true,
})

Browsers send it as x-goog-content-length-range header, so add it to bucket CORS responseHeader first (see the example above), otherwise browser uploads fail. To update CORS of an existing bucket, get the current config, add the header, and set it again:

gcloud storage buckets describe gs://YOUR_BUCKET --format="default(cors_config)"
gcloud storage buckets update gs://YOUR_BUCKET --cors-file=cors.json

On this page