CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-google-cloud--storage

Cloud Storage Client Library for Node.js that provides comprehensive API for managing buckets, files, and metadata with authentication, streaming, and access control.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

bucket-operations.mddocs/

Bucket Operations

The Bucket class represents a Cloud Storage bucket and provides comprehensive methods for file management, metadata operations, lifecycle rules, and access control.

Class Definition

class Bucket extends ServiceObject {
  constructor(storage: Storage, name: string, options?: BucketOptions);
  
  // Properties
  name: string;
  storage: Storage;
  acl: Acl;
  iam: Iam;
  userProject?: string;
  metadata: BucketMetadata;
  cloudStorageURI: URL;
  
  // File management methods
  file(name: string, options?: FileOptions): File;
  getFiles(options?: GetFilesOptions): Promise<GetFilesResponse>;
  getFilesStream(query?: GetFilesOptions): Readable;
  upload(pathString: string, options?: UploadOptions): Promise<UploadResponse>;
  deleteFiles(query?: DeleteFilesOptions): Promise<void>;
  combine(sources: (File | string)[], destination: File | string, options?: CombineOptions): Promise<CombineResponse>;
  
  // Bucket metadata and management
  exists(options?: BucketExistsOptions): Promise<BucketExistsResponse>;
  get(options?: GetBucketOptions): Promise<GetBucketResponse>;
  getMetadata(options?: GetBucketMetadataOptions): Promise<GetBucketMetadataResponse>;
  setMetadata(metadata: BucketMetadata, options?: SetBucketMetadataOptions): Promise<SetBucketMetadataResponse>;
  delete(options?: DeleteBucketOptions): Promise<DeleteBucketResponse>;
  restore(options?: RestoreBucketOptions): Promise<RestoreBucketResponse>;
  
  // Retention policy management
  setRetentionPeriod(period: number, options?: SetRetentionPeriodOptions): Promise<SetBucketMetadataResponse>;
  removeRetentionPeriod(options?: RemoveRetentionPeriodOptions): Promise<SetBucketMetadataResponse>;
  
  // Configuration helpers
  setCorsConfiguration(cors: Cors[], options?: SetCorsOptions): Promise<SetBucketMetadataResponse>;
  setUserProject(projectId: string): void;
  enableLogging(config: LoggingConfig, options?: EnableLoggingOptions): Promise<SetBucketMetadataResponse>;
  
  // Notifications
  notification(id: string): Notification;
  
  // Low-level access
  request(options: RequestOptions): Promise<RequestResponse>;
}

interface BucketOptions {
  crc32cGenerator?: CRC32CValidatorGenerator;
  kmsKeyName?: string;
  preconditionOpts?: PreconditionOptions;
  userProject?: string;
  generation?: number;
  softDeleted?: boolean;
}

File Management

Get File Reference

file(name: string, options?: FileOptions): File

// Get file reference
const file = bucket.file('path/to/file.txt');

// With options
const file = bucket.file('path/to/file.txt', {
  generation: 1234567890,
  encryptionKey: 'base64-encoded-key'
});

// With KMS encryption
const file = bucket.file('encrypted-file.txt', {
  kmsKeyName: 'projects/PROJECT_ID/locations/LOCATION/keyRings/RING_ID/cryptoKeys/KEY_ID'
});

Upload Files

upload(pathString: string, options?: UploadOptions): Promise<UploadResponse>

interface UploadOptions {
  destination?: string;
  encryptionKey?: string | Buffer;
  gzip?: boolean;
  metadata?: FileMetadata;
  offset?: number;
  predefinedAcl?: PredefinedAcl;
  private?: boolean;
  public?: boolean;
  resumable?: boolean;
  timeout?: number;
  uri?: string;
  userProject?: string;
  validation?: string | boolean;
  preconditionOpts?: PreconditionOptions;
  chunkSize?: number;
}

type UploadResponse = [File, unknown]; // [file, apiResponse]

// Simple upload
const [file] = await bucket.upload('/local/path/file.txt');

// Upload with custom destination
const [file] = await bucket.upload('/local/path/file.txt', {
  destination: 'remote/path/renamed-file.txt'
});

// Upload with metadata
const [file] = await bucket.upload('/local/path/image.jpg', {
  metadata: {
    contentType: 'image/jpeg',
    cacheControl: 'public, max-age=86400',
    metadata: {
      originalName: 'vacation-photo.jpg',
      uploadedBy: 'user-123'
    }
  }
});

// Upload with compression
const [file] = await bucket.upload('/local/path/large-file.txt', {
  gzip: true,
  metadata: {
    contentEncoding: 'gzip'
  }
});

// Upload with encryption
const [file] = await bucket.upload('/local/path/secret.txt', {
  encryptionKey: crypto.randomBytes(32).toString('base64')
});

// Upload with access control
const [file] = await bucket.upload('/local/path/public-file.txt', {
  public: true
});

// Resumable upload for large files
const [file] = await bucket.upload('/local/path/large-video.mp4', {
  resumable: true,
  chunkSize: 256 * 1024, // 256KB chunks
  metadata: {
    contentType: 'video/mp4'
  }
});

List Files

getFiles(options?: GetFilesOptions): Promise<GetFilesResponse>
getFilesStream(query?: GetFilesOptions): Readable

interface GetFilesOptions {
  delimiter?: string;
  directory?: string;
  endOffset?: string;
  includeFoldersAsPrefixes?: boolean;
  includeTrailingDelimiter?: boolean;
  maxResults?: number;
  pageToken?: string;
  prefix?: string;
  startOffset?: string;
  userProject?: string;
  versions?: boolean;
  autoPaginate?: boolean;
  softDeleted?: boolean;
}

type GetFilesResponse = [File[], {}, unknown]; // [files, nextQuery, apiResponse]

// List all files
const [files] = await bucket.getFiles();
files.forEach(file => {
  console.log(`File: ${file.name}`);
});

// List with prefix filter
const [files] = await bucket.getFiles({
  prefix: 'uploads/'
});

// List files in a "directory"
const [files] = await bucket.getFiles({
  prefix: 'images/',
  delimiter: '/'
});

// List with pagination
const [files, nextQuery] = await bucket.getFiles({
  maxResults: 100
});

if (nextQuery) {
  const [moreFiles] = await bucket.getFiles(nextQuery);
}

// List all versions
const [files] = await bucket.getFiles({
  versions: true
});

// Stream files for large lists
bucket.getFilesStream({ prefix: 'logs/' })
  .on('data', file => {
    console.log(`File: ${file.name}, Size: ${file.metadata.size}`);
  })
  .on('end', () => {
    console.log('Finished listing files');
  });

// List with date range
const [files] = await bucket.getFiles({
  startOffset: '2023-01-01',
  endOffset: '2023-12-31'
});

Delete Files

deleteFiles(query?: DeleteFilesOptions): Promise<void>

interface DeleteFilesOptions {
  prefix?: string;
  delimiter?: string;
  directory?: string;
  versions?: boolean;
  force?: boolean;
  userProject?: string;
}

// Delete all files with prefix
await bucket.deleteFiles({
  prefix: 'temp/'
});

// Delete all files in "directory"
await bucket.deleteFiles({
  prefix: 'old-data/',
  delimiter: '/'
});

// Delete all versions
await bucket.deleteFiles({
  prefix: 'archived/',
  versions: true
});

// Force delete (ignore errors)
await bucket.deleteFiles({
  prefix: 'cleanup/',
  force: true
});

Combine Files

combine(sources: (File | string)[], destination: File | string, options?: CombineOptions): Promise<CombineResponse>

interface CombineOptions {
  kmsKeyName?: string;
  userProject?: string;
}

type CombineResponse = [File, unknown]; // [combinedFile, apiResponse]

// Combine files by name
const [combinedFile] = await bucket.combine([
  'part1.txt',
  'part2.txt', 
  'part3.txt'
], 'combined.txt');

// Combine File objects
const part1 = bucket.file('logs/part1.log');
const part2 = bucket.file('logs/part2.log');
const destination = bucket.file('logs/combined.log');

const [combinedFile] = await bucket.combine([part1, part2], destination);

// Combine with encryption
const [combinedFile] = await bucket.combine(
  ['encrypted-part1.txt', 'encrypted-part2.txt'],
  'encrypted-combined.txt',
  {
    kmsKeyName: 'projects/PROJECT_ID/locations/us/keyRings/my-ring/cryptoKeys/my-key'
  }
);

Bucket Metadata and Management

Check Existence

exists(options?: BucketExistsOptions): Promise<BucketExistsResponse>

interface BucketExistsOptions {
  userProject?: string;
}

type BucketExistsResponse = [boolean]; // [exists]

// Check if bucket exists
const [exists] = await bucket.exists();
if (exists) {
  console.log('Bucket exists');
} else {
  console.log('Bucket does not exist');
}

Get Bucket (Create if Needed)

get(options?: GetBucketOptions): Promise<GetBucketResponse>

interface GetBucketOptions extends GetBucketMetadataOptions {
  autoCreate?: boolean;
  location?: string;
  storageClass?: string;
}

type GetBucketResponse = [Bucket, unknown]; // [bucket, apiResponse]

// Get bucket (create if doesn't exist)
const [bucket] = await bucket.get({
  autoCreate: true,
  location: 'us-central1'
});

Get and Set Metadata

getMetadata(options?: GetBucketMetadataOptions): Promise<GetBucketMetadataResponse>
setMetadata(metadata: BucketMetadata, options?: SetBucketMetadataOptions): Promise<SetBucketMetadataResponse>

interface GetBucketMetadataOptions {
  userProject?: string;
  ifMetagenerationMatch?: number;
  ifMetagenerationNotMatch?: number;
}

interface BucketMetadata {
  acl?: AclMetadata[];
  cors?: Cors[];
  defaultEventBasedHold?: boolean;
  defaultObjectAcl?: AclMetadata[];
  encryption?: {
    defaultKmsKeyName?: string;
  };
  iamConfiguration?: {
    bucketPolicyOnly?: {
      enabled?: boolean;
    };
    publicAccessPrevention?: 'inherited' | 'enforced';
    uniformBucketLevelAccess?: {
      enabled?: boolean;
    };
  };
  labels?: { [key: string]: string };
  lifecycle?: {
    rule?: LifecycleRule[];
  };
  location?: string;
  locationType?: string;
  logging?: {
    logBucket?: string;
    logObjectPrefix?: string;
  };
  name?: string;
  owner?: {
    entity?: string;
    entityId?: string;
  };
  projectNumber?: string;
  retentionPolicy?: {
    effectiveTime?: string;
    isLocked?: boolean;
    retentionPeriod?: number;
  };
  storageClass?: string;
  timeCreated?: string;
  updated?: string;
  versioning?: {
    enabled?: boolean;
  };
  website?: {
    mainPageSuffix?: string;
    notFoundPage?: string;
  };
  requesterPays?: boolean;
}

type GetBucketMetadataResponse = [BucketMetadata, unknown]; // [metadata, apiResponse]
type SetBucketMetadataResponse = [BucketMetadata, unknown]; // [metadata, apiResponse]

// Get bucket metadata
const [metadata] = await bucket.getMetadata();
console.log('Location:', metadata.location);
console.log('Storage Class:', metadata.storageClass);
console.log('Created:', metadata.timeCreated);

// Update bucket metadata
const [metadata] = await bucket.setMetadata({
  website: {
    mainPageSuffix: 'index.html',
    notFoundPage: '404.html'
  },
  labels: {
    environment: 'production',
    team: 'frontend'
  }
});

// Enable versioning
await bucket.setMetadata({
  versioning: {
    enabled: true
  }
});

// Set CORS configuration
await bucket.setMetadata({
  cors: [
    {
      origin: ['https://example.com', 'https://app.example.com'],
      method: ['GET', 'POST', 'PUT', 'DELETE'],
      responseHeader: ['Content-Type', 'x-custom-header'],
      maxAgeSeconds: 3600
    }
  ]
});

Lifecycle Management

Add Lifecycle Rules

addLifecycleRule(rule: LifecycleRule | LifecycleRule[], options?: AddLifecycleRuleOptions): Promise<SetBucketMetadataResponse>

interface LifecycleRule {
  action: LifecycleAction;
  condition: LifecycleCondition;
}

interface LifecycleAction {
  type: 'Delete' | 'SetStorageClass' | 'AbortIncompleteMultipartUpload';
  storageClass?: string;
}

interface LifecycleCondition {
  age?: number;
  createdBefore?: Date | string;
  customTimeBefore?: Date | string;
  daysSinceCustomTime?: number;
  daysSinceNoncurrentTime?: number;
  isLive?: boolean;
  matchesStorageClass?: string[];
  noncurrentTimeBefore?: Date | string;
  numNewerVersions?: number;
}

interface AddLifecycleRuleOptions {
  append?: boolean;
  userProject?: string;
}

// Delete files older than 365 days
await bucket.addLifecycleRule({
  action: { type: 'Delete' },
  condition: { age: 365 }
});

// Move to Coldline after 30 days
await bucket.addLifecycleRule({
  action: { 
    type: 'SetStorageClass',
    storageClass: 'COLDLINE'
  },
  condition: { age: 30 }
});

// Delete old versions (keep only 5 newest)
await bucket.addLifecycleRule({
  action: { type: 'Delete' },
  condition: { 
    numNewerVersions: 5,
    isLive: false
  }
});

// Multiple rules at once
await bucket.addLifecycleRule([
  {
    action: { type: 'SetStorageClass', storageClass: 'NEARLINE' },
    condition: { age: 7, matchesStorageClass: ['STANDARD'] }
  },
  {
    action: { type: 'SetStorageClass', storageClass: 'ARCHIVE' },
    condition: { age: 90, matchesStorageClass: ['NEARLINE'] }
  },
  {
    action: { type: 'Delete' },
    condition: { age: 2555 } // ~7 years
  }
]);

// Abort incomplete multipart uploads
await bucket.addLifecycleRule({
  action: { type: 'AbortIncompleteMultipartUpload' },
  condition: { age: 7 }
});

Set Storage Class

setStorageClass(storageClass: string, options?: SetBucketStorageClassOptions): Promise<SetBucketMetadataResponse>

interface SetBucketStorageClassOptions {
  userProject?: string;
}

// Available storage classes
const storageClasses = [
  'STANDARD',
  'NEARLINE',
  'COLDLINE', 
  'ARCHIVE',
  'DURABLE_REDUCED_AVAILABILITY'
];

// Set bucket storage class
await bucket.setStorageClass('COLDLINE');

// Regional storage
await bucket.setStorageClass('REGIONAL');

Retention Policy Management

Set Retention Period

setRetentionPeriod(period: number, options?: SetRetentionPeriodOptions): Promise<SetBucketMetadataResponse>

interface SetRetentionPeriodOptions {
  userProject?: string;
}

// Set retention period (in seconds)
await bucket.setRetentionPeriod(86400 * 30); // 30 days

// Set retention period with user project
await bucket.setRetentionPeriod(86400 * 365, {
  userProject: 'billing-project-id'
});

// Equivalent using setMetadata
await bucket.setMetadata({
  retentionPolicy: {
    retentionPeriod: 86400 * 30
  }
});

Remove Retention Period

removeRetentionPeriod(options?: RemoveRetentionPeriodOptions): Promise<SetBucketMetadataResponse>

interface RemoveRetentionPeriodOptions {
  userProject?: string;
}

// Remove retention period (only possible if policy is not locked)
await bucket.removeRetentionPeriod();

// With user project
await bucket.removeRetentionPeriod({
  userProject: 'billing-project-id'
});

Lock Retention Policy

lock(metageneration: number | string): Promise<BucketLockResponse>

type BucketLockResponse = [BucketMetadata, unknown]; // [metadata, apiResponse]

// Lock retention policy (irreversible!)
const [metadata] = await bucket.lock(bucket.metadata.metageneration);
console.log('Retention policy locked until:', metadata.retentionPolicy.effectiveTime);

Access Control and Security

Make Public/Private

makePublic(options?: MakeBucketPublicOptions): Promise<MakeBucketPublicResponse>
makePrivate(options?: MakeBucketPrivateOptions): Promise<MakeBucketPrivateResponse>

interface MakeBucketPublicOptions {
  includeFiles?: boolean;
  force?: boolean;
  userProject?: string;
}

interface MakeBucketPrivateOptions {
  includeFiles?: boolean;
  force?: boolean;
  userProject?: string;
}

type MakeBucketPublicResponse = [File[], unknown]; // [files, apiResponse]
type MakeBucketPrivateResponse = [File[], unknown]; // [files, apiResponse]

// Make bucket public (bucket and all files)
const [files] = await bucket.makePublic({
  includeFiles: true
});

// Make bucket private
await bucket.makePrivate({
  includeFiles: true
});

// Force operation (ignore errors)
await bucket.makePublic({
  includeFiles: true,
  force: true
});

Requester Pays

enableRequesterPays(options?: EnableRequesterPaysOptions): Promise<EnableRequesterPaysResponse>
disableRequesterPays(options?: DisableRequesterPaysOptions): Promise<DisableRequesterPaysResponse>

interface EnableRequesterPaysOptions {
  userProject?: string;
}

interface DisableRequesterPaysOptions {
  userProject?: string;
}

type EnableRequesterPaysResponse = [unknown]; // [apiResponse]
type DisableRequesterPaysResponse = [unknown]; // [apiResponse]

// Enable requester pays
await bucket.enableRequesterPays();

// Disable requester pays
await bucket.disableRequesterPays();

Configuration Helper Methods

Set CORS Configuration

setCorsConfiguration(cors: Cors[], options?: SetCorsOptions): Promise<SetBucketMetadataResponse>

interface SetCorsOptions {
  userProject?: string;
}

interface Cors {
  origin?: string[];
  method?: string[];
  responseHeader?: string[];
  maxAgeSeconds?: number;
}

// Set CORS configuration
await bucket.setCorsConfiguration([
  {
    origin: ['https://example.com', 'https://app.example.com'],
    method: ['GET', 'POST', 'PUT', 'DELETE'],
    responseHeader: ['Content-Type', 'x-custom-header'],
    maxAgeSeconds: 3600
  }
]);

// Allow all origins (use carefully)
await bucket.setCorsConfiguration([
  {
    origin: ['*'],
    method: ['GET', 'HEAD'],
    responseHeader: ['*'],
    maxAgeSeconds: 86400
  }
]);

Set User Project

setUserProject(projectId: string): void

// Set user project for billing
bucket.setUserProject('billing-project-id');

// All subsequent operations will use this project for billing
const [files] = await bucket.getFiles(); // Uses billing-project-id for billing

Enable Access Logging

enableLogging(config: LoggingConfig, options?: EnableLoggingOptions): Promise<SetBucketMetadataResponse>

interface LoggingConfig {
  logBucket: string;
  logObjectPrefix?: string;
}

interface EnableLoggingOptions {
  userProject?: string;
}

// Enable access logging
await bucket.enableLogging({
  logBucket: 'access-logs-bucket',
  logObjectPrefix: 'my-bucket-logs/'
});

// Basic logging (no prefix)
await bucket.enableLogging({
  logBucket: 'access-logs-bucket'
});

Labels Management

Get, Set, and Delete Labels

getLabels(options?: GetLabelsOptions): Promise<GetLabelsResponse>
setLabels(labels: Labels, options?: SetLabelsOptions): Promise<SetLabelsResponse>
deleteLabels(labels?: string[], options?: DeleteLabelsOptions): Promise<DeleteLabelsResponse>

interface Labels {
  [key: string]: string;
}

interface GetLabelsOptions {
  userProject?: string;
}

interface SetLabelsOptions {
  userProject?: string;
}

interface DeleteLabelsOptions {
  userProject?: string;
}

type GetLabelsResponse = [Labels, unknown]; // [labels, apiResponse]
type SetLabelsResponse = [Labels, unknown]; // [labels, apiResponse]
type DeleteLabelsResponse = [Labels, unknown]; // [labels, apiResponse]

// Get current labels
const [labels] = await bucket.getLabels();
console.log('Current labels:', labels);

// Set labels
await bucket.setLabels({
  environment: 'production',
  team: 'backend',
  cost_center: '12345'
});

// Delete specific labels
await bucket.deleteLabels(['cost_center']);

// Delete all labels
await bucket.deleteLabels();

Notifications and Channels

Create Notifications

createNotification(topic: string, options?: CreateNotificationOptions): Promise<CreateNotificationResponse>
getNotifications(options?: GetNotificationsOptions): Promise<GetNotificationsResponse>

interface CreateNotificationOptions {
  eventTypes?: string[];
  objectNamePrefix?: string;
  payloadFormat?: string;
  userProject?: string;
}

interface GetNotificationsOptions {
  userProject?: string;
}

type CreateNotificationResponse = [Notification, unknown]; // [notification, apiResponse]
type GetNotificationsResponse = [Notification[], unknown]; // [notifications, apiResponse]

// Create notification for all events
const [notification] = await bucket.createNotification('projects/my-project/topics/bucket-notifications');

// Create notification for specific events
const [notification] = await bucket.createNotification('projects/my-project/topics/bucket-uploads', {
  eventTypes: ['OBJECT_FINALIZE'],
  objectNamePrefix: 'uploads/',
  payloadFormat: 'JSON_API_V1'
});

// List notifications
const [notifications] = await bucket.getNotifications();
notifications.forEach(notification => {
  console.log(`Notification: ${notification.id}`);
});

Get Notification Reference

notification(id: string): Notification

// Get notification reference by ID
const notification = bucket.notification('notification-id-123');

// Use the reference to get metadata or delete
const [metadata] = await notification.getMetadata();
console.log('Topic:', metadata.topic);

// Delete the notification
await notification.delete();

Create Watch Channel

createChannel(id: string, config: CreateChannelConfig, options?: CreateChannelOptions): Promise<CreateChannelResponse>

interface CreateChannelConfig {
  address: string;
  type?: string;
  token?: string;
  params?: { [key: string]: string };
}

interface CreateChannelOptions {
  userProject?: string;
}

type CreateChannelResponse = [Channel, unknown]; // [channel, apiResponse]

// Create watch channel
const [channel] = await bucket.createChannel('my-channel-id', {
  address: 'https://example.com/webhook',
  type: 'web_hook'
});

// With authentication token
const [channel] = await bucket.createChannel('secure-channel', {
  address: 'https://api.example.com/storage-webhook',
  token: 'secret-token-123'
});

Signed URLs

Generate Signed URLs

getSignedUrl(config: GetBucketSignedUrlConfig): Promise<GetSignedUrlResponse>

interface GetBucketSignedUrlConfig {
  version: 'v2' | 'v4';
  action: 'list';
  expires: string | number | Date;
  extensionHeaders?: { [key: string]: string };
  queryParams?: { [key: string]: string };
  cname?: string;
  contentMd5?: string;
  contentType?: string;
  virtualHostedStyle?: boolean;
}

type GetSignedUrlResponse = [string]; // [signedUrl]

// Generate signed URL for listing bucket contents
const [url] = await bucket.getSignedUrl({
  version: 'v4',
  action: 'list',
  expires: Date.now() + 15 * 60 * 1000 // 15 minutes
});

console.log('Signed URL:', url);

// With query parameters
const [url] = await bucket.getSignedUrl({
  version: 'v4', 
  action: 'list',
  expires: Date.now() + 3600000, // 1 hour
  queryParams: {
    prefix: 'uploads/',
    delimiter: '/'
  }
});

Delete Bucket

delete(options?: DeleteBucketOptions): Promise<DeleteBucketResponse>

interface DeleteBucketOptions {
  ignoreNotFound?: boolean;
  userProject?: string;
  ifMetagenerationMatch?: number;
  ifMetagenerationNotMatch?: number;
}

type DeleteBucketResponse = [unknown]; // [apiResponse]

// Delete empty bucket
await bucket.delete();

// Delete bucket ignoring not found errors
await bucket.delete({
  ignoreNotFound: true
});

Bucket Restoration

Restore Soft-Deleted Bucket

restore(options?: RestoreBucketOptions): Promise<RestoreBucketResponse>

interface RestoreBucketOptions {
  userProject?: string;
  ifMetagenerationMatch?: number;
  ifMetagenerationNotMatch?: number;
}

type RestoreBucketResponse = [Bucket, unknown]; // [bucket, apiResponse]

// Restore soft-deleted bucket
const [restoredBucket] = await bucket.restore();
console.log('Bucket restored:', restoredBucket.name);

// Restore with preconditions
const [restoredBucket] = await bucket.restore({
  ifMetagenerationMatch: bucket.metadata.metageneration
});

// Check if bucket is soft-deleted before restoring
const [exists] = await bucket.exists();
if (!exists && bucket.metadata.softDeleted) {
  const [restoredBucket] = await bucket.restore();
  console.log('Soft-deleted bucket restored successfully');
}

Low-Level Request Access

Make Custom HTTP Request

request(options: RequestOptions): Promise<RequestResponse>

interface RequestOptions {
  uri: string;
  method?: string;
  headers?: { [key: string]: string };
  body?: any;
  json?: boolean;
  qs?: { [key: string]: string };
}

type RequestResponse = [any, unknown]; // [responseBody, rawResponse]

// Make custom authenticated request to Storage API
const [response] = await bucket.request({
  uri: `/b/${bucket.name}/o`,
  method: 'GET',
  qs: {
    prefix: 'logs/',
    delimiter: '/'
  }
});

// Custom POST request with body
const [response] = await bucket.request({
  uri: `/b/${bucket.name}/acl`,
  method: 'POST',
  json: true,
  body: {
    entity: 'user-example@gmail.com',
    role: 'READER'
  }
});

// Use for advanced operations not covered by high-level methods
const [response] = await bucket.request({
  uri: `/b/${bucket.name}`,
  method: 'PATCH',
  json: true,
  body: {
    labels: {
      'custom-label': 'custom-value'
    }
  }
});

Callback Support

All async methods support both Promise and callback patterns:

// Promise pattern (recommended)
const [files] = await bucket.getFiles();

// Callback pattern  
bucket.getFiles((err, files, nextQuery, apiResponse) => {
  if (err) {
    console.error('Error:', err);
    return;
  }
  console.log(`Found ${files.length} files`);
});

docs

access-control.md

authentication.md

bucket-operations.md

file-operations.md

index.md

notifications.md

storage-client.md

transfer-manager.md

utilities.md

tile.json