diff --git a/storage/README.md b/storage/README.md
new file mode 100644
index 0000000000..04f33426fa
--- /dev/null
+++ b/storage/README.md
@@ -0,0 +1,2472 @@
+[//]: # "This README.md file is auto-generated, all changes to this file will be lost."
+[//]: # "To regenerate it, use `python -m synthtool`."
+
+
+# [Google Cloud Storage: Node.js Samples](https://github.com/googleapis/nodejs-storage)
+
+[![Open in Cloud Shell][shell_img]][shell_link]
+
+> Node.js idiomatic client for [Cloud Storage][product-docs].
+
+[Cloud Storage](https://cloud.google.com/storage/docs) allows world-wide
+storage and retrieval of any amount of data at any time. You can use Google
+Cloud Storage for a range of scenarios including serving website content,
+storing data for archival and disaster recovery, or distributing large data
+objects to users via direct download.
+
+## Table of Contents
+
+* [Before you begin](#before-you-begin)
+* [Samples](#samples)
+ * [Add Bucket Conditional Binding](#add-bucket-conditional-binding)
+ * [Add Bucket Default Owner Acl](#add-bucket-default-owner-acl)
+ * [Add Bucket Iam Member](#add-bucket-iam-member)
+ * [Storage Add Bucket Label.](#storage-add-bucket-label.)
+ * [Add Bucket Owner Acl](#add-bucket-owner-acl)
+ * [Bucket Website Configuration.](#bucket-website-configuration.)
+ * [Add File Owner Acl](#add-file-owner-acl)
+ * [Storage Get Bucket Metadata.](#storage-get-bucket-metadata.)
+ * [Change Bucket's Default Storage Class.](#change-bucket's-default-storage-class.)
+ * [Storage File Convert CSEK to CMEK.](#storage-file-convert-csek-to-cmek.)
+ * [Storage Combine files.](#storage-combine-files.)
+ * [Storage Configure Bucket Cors.](#storage-configure-bucket-cors.)
+ * [Configure Retries](#configure-retries)
+ * [Copy File](#copy-file)
+ * [Copy Old Version Of File.](#copy-old-version-of-file.)
+ * [Create a Dual-Region Bucket](#create-a-dual-region-bucket)
+ * [Create a hierarchical namespace enabled bucket](#create-a-hierarchical-namespace-enabled-bucket)
+ * [Create a Bucket with object retention enabled.](#create-a-bucket-with-object-retention-enabled.)
+ * [Create Bucket With Storage Class and Location.](#create-bucket-with-storage-class-and-location.)
+ * [Create Bucket With Turbo Replication](#create-bucket-with-turbo-replication)
+ * [Create New Bucket](#create-new-bucket)
+ * [Create Notification](#create-notification)
+ * [Delete Bucket](#delete-bucket)
+ * [Delete File](#delete-file)
+ * [Delete Notification](#delete-notification)
+ * [Delete Old Version Of File.](#delete-old-version-of-file.)
+ * [Disable Bucket Lifecycle Management](#disable-bucket-lifecycle-management)
+ * [Storage Disable Bucket Versioning.](#storage-disable-bucket-versioning.)
+ * [Disable Default Event Based Hold](#disable-default-event-based-hold)
+ * [Disable Requester Pays](#disable-requester-pays)
+ * [Disable Soft Delete](#disable-soft-delete)
+ * [Disable Uniform Bucket Level Access](#disable-uniform-bucket-level-access)
+ * [Download Byte Range](#download-byte-range)
+ * [Download Encrypted File](#download-encrypted-file)
+ * [Download File](#download-file)
+ * [Download a File in Chunks With Transfer Manager](#download-a-file-in-chunks-with-transfer-manager)
+ * [Download File Using Requester Pays](#download-file-using-requester-pays)
+ * [Download Folder With Transfer Manager](#download-folder-with-transfer-manager)
+ * [Download Into Memory](#download-into-memory)
+ * [Download Many Files With Transfer Manager](#download-many-files-with-transfer-manager)
+ * [Storage Download Public File.](#storage-download-public-file.)
+ * [Enable Bucket Lifecycle Management](#enable-bucket-lifecycle-management)
+ * [Storage Enable Bucket Versioning.](#storage-enable-bucket-versioning.)
+ * [Enable Default Event Based Hold](#enable-default-event-based-hold)
+ * [Enable Default KMS Key](#enable-default-kms-key)
+ * [Enable Requester Pays](#enable-requester-pays)
+ * [Enable Uniform Bucket Level Access](#enable-uniform-bucket-level-access)
+ * [Change File's Storage Class.](#change-file's-storage-class.)
+ * [Storage Set File Metadata.](#storage-set-file-metadata.)
+ * [Generate Encryption Key](#generate-encryption-key)
+ * [Generate Signed Url](#generate-signed-url)
+ * [Generate V4 Read Signed Url](#generate-v4-read-signed-url)
+ * [Generate V4 Signed Policy](#generate-v4-signed-policy)
+ * [Generate V4 Upload Signed Url](#generate-v4-upload-signed-url)
+ * [Get Autoclass](#get-autoclass)
+ * [Get Default Event Based Hold](#get-default-event-based-hold)
+ * [Get Metadata](#get-metadata)
+ * [Get Metadata Notifications](#get-metadata-notifications)
+ * [Get Public Access Prevention](#get-public-access-prevention)
+ * [Get RPO](#get-rpo)
+ * [Get Requester Pays Status](#get-requester-pays-status)
+ * [Get Retention Policy](#get-retention-policy)
+ * [Storage Get Service Account.](#storage-get-service-account.)
+ * [Get Soft Delete Policy](#get-soft-delete-policy)
+ * [Get Soft Deleted Bucket](#get-soft-deleted-bucket)
+ * [Get Uniform Bucket Level Access](#get-uniform-bucket-level-access)
+ * [Activate HMAC SA Key.](#activate-hmac-sa-key.)
+ * [Create HMAC SA Key.](#create-hmac-sa-key.)
+ * [Deactivate HMAC SA Key.](#deactivate-hmac-sa-key.)
+ * [Delete HMAC SA Key.](#delete-hmac-sa-key.)
+ * [Get HMAC SA Key Metadata.](#get-hmac-sa-key-metadata.)
+ * [List HMAC SA Keys Metadata.](#list-hmac-sa-keys-metadata.)
+ * [List Buckets](#list-buckets)
+ * [List Buckets Partial Success](#list-buckets-partial-success)
+ * [List Files](#list-files)
+ * [List Files By Prefix](#list-files-by-prefix)
+ * [List Files Paginate](#list-files-paginate)
+ * [List Files with Old Versions.](#list-files-with-old-versions.)
+ * [List Notifications](#list-notifications)
+ * [List Soft Deleted Bucket](#list-soft-deleted-bucket)
+ * [List Soft Deleted Object Versions](#list-soft-deleted-object-versions)
+ * [List Soft Deleted Objects](#list-soft-deleted-objects)
+ * [Lock Retention Policy](#lock-retention-policy)
+ * [Storage Make Bucket Public.](#storage-make-bucket-public.)
+ * [Make Public](#make-public)
+ * [Move File](#move-file)
+ * [Move File Atomic](#move-file-atomic)
+ * [Print Bucket Acl](#print-bucket-acl)
+ * [Print Bucket Acl For User](#print-bucket-acl-for-user)
+ * [Print File Acl](#print-file-acl)
+ * [Print File Acl For User](#print-file-acl-for-user)
+ * [Quickstart](#quickstart)
+ * [Release Event Based Hold](#release-event-based-hold)
+ * [Release Temporary Hold](#release-temporary-hold)
+ * [Remove Bucket Conditional Binding](#remove-bucket-conditional-binding)
+ * [Storage Remove Bucket Cors Configuration.](#storage-remove-bucket-cors-configuration.)
+ * [Remove Bucket Default Owner](#remove-bucket-default-owner)
+ * [Remove Bucket Iam Member](#remove-bucket-iam-member)
+ * [Storage Remove Bucket Label.](#storage-remove-bucket-label.)
+ * [Remove Bucket Owner Acl](#remove-bucket-owner-acl)
+ * [Remove Default KMS Key.](#remove-default-kms-key.)
+ * [Remove File Owner Acl](#remove-file-owner-acl)
+ * [Remove Retention Policy](#remove-retention-policy)
+ * [Rename File](#rename-file)
+ * [Restore Soft Deleted Bucket](#restore-soft-deleted-bucket)
+ * [Restore Soft Deleted Object](#restore-soft-deleted-object)
+ * [Rotate Encryption Key](#rotate-encryption-key)
+ * [Set Autoclass](#set-autoclass)
+ * [Set Client Endpoint](#set-client-endpoint)
+ * [Set Event Based Hold](#set-event-based-hold)
+ * [Set the object retention policy of a File.](#set-the-object-retention-policy-of-a-file.)
+ * [Set Public Access Prevention Enforced](#set-public-access-prevention-enforced)
+ * [Set Public Access Prevention Inherited](#set-public-access-prevention-inherited)
+ * [Set RPO Async Turbo](#set-rpo-async-turbo)
+ * [Set RPO Default](#set-rpo-default)
+ * [Set Retention Policy](#set-retention-policy)
+ * [Set Soft Delete Policy](#set-soft-delete-policy)
+ * [Set Temporary Hold](#set-temporary-hold)
+ * [Stream File Download](#stream-file-download)
+ * [Stream File Upload](#stream-file-upload)
+ * [Upload a directory to a bucket.](#upload-a-directory-to-a-bucket.)
+ * [Upload Directory With Transfer Manager](#upload-directory-with-transfer-manager)
+ * [Upload Encrypted File](#upload-encrypted-file)
+ * [Upload File](#upload-file)
+ * [Upload a File in Chunks With Transfer Manager](#upload-a-file-in-chunks-with-transfer-manager)
+ * [Upload File With Kms Key](#upload-file-with-kms-key)
+ * [Upload From Memory](#upload-from-memory)
+ * [Upload Many Files With Transfer Manager](#upload-many-files-with-transfer-manager)
+ * [Upload Without Authentication](#upload-without-authentication)
+ * [Upload Without Authentication Signed Url](#upload-without-authentication-signed-url)
+ * [View Bucket Iam Members](#view-bucket-iam-members)
+
+## Before you begin
+
+Before running the samples, make sure you've followed the steps outlined in
+[Using the client library](https://github.com/googleapis/nodejs-storage#using-the-client-library).
+
+`cd samples`
+
+`npm install`
+
+`cd ..`
+
+## Samples
+
+
+
+### Add Bucket Conditional Binding
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketConditionalBinding.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketConditionalBinding.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/addBucketConditionalBinding.js`
+
+
+-----
+
+
+
+
+### Add Bucket Default Owner Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketDefaultOwnerAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketDefaultOwnerAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/addBucketDefaultOwnerAcl.js`
+
+
+-----
+
+
+
+
+### Add Bucket Iam Member
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketIamMember.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketIamMember.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/addBucketIamMember.js`
+
+
+-----
+
+
+
+
+### Storage Add Bucket Label.
+
+Adds bucket label.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketLabel.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketLabel.js,samples/README.md)
+
+__Usage:__
+
+
+`node addBucketLabel.js `
+
+
+-----
+
+
+
+
+### Add Bucket Owner Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketOwnerAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketOwnerAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/addBucketOwnerAcl.js`
+
+
+-----
+
+
+
+
+### Bucket Website Configuration.
+
+Bucket Website Configuration.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addBucketWebsiteConfiguration.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addBucketWebsiteConfiguration.js,samples/README.md)
+
+__Usage:__
+
+
+`node addBucketWebsiteConfiguration.js `
+
+
+-----
+
+
+
+
+### Add File Owner Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/addFileOwnerAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/addFileOwnerAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/addFileOwnerAcl.js`
+
+
+-----
+
+
+
+
+### Storage Get Bucket Metadata.
+
+Get bucket metadata.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/bucketMetadata.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/bucketMetadata.js,samples/README.md)
+
+__Usage:__
+
+
+`node bucketMetadata.js `
+
+
+-----
+
+
+
+
+### Change Bucket's Default Storage Class.
+
+Change Bucket's Default Storage Class.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/changeDefaultStorageClass.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/changeDefaultStorageClass.js,samples/README.md)
+
+__Usage:__
+
+
+`node changeDefaultStorageClass.js `
+
+
+-----
+
+
+
+
+### Storage File Convert CSEK to CMEK.
+
+Storage File Convert CSEK to CMEK.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/changeFileCSEKToCMEK.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/changeFileCSEKToCMEK.js,samples/README.md)
+
+__Usage:__
+
+
+`node changeFileCSEKToCMEK.js `
+
+
+-----
+
+
+
+
+### Storage Combine files.
+
+Combine multiple files into one new file.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/composeFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/composeFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node composeFile.js `
+
+
+-----
+
+
+
+
+### Storage Configure Bucket Cors.
+
+Configures bucket cors.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/configureBucketCors.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/configureBucketCors.js,samples/README.md)
+
+__Usage:__
+
+
+`node configureBucketCors.js `
+
+
+-----
+
+
+
+
+### Configure Retries
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/configureRetries.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/configureRetries.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/configureRetries.js`
+
+
+-----
+
+
+
+
+### Copy File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/copyFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/copyFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/copyFile.js`
+
+
+-----
+
+
+
+
+### Copy Old Version Of File.
+
+Copy Old Version Of File.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/copyOldVersionOfFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/copyOldVersionOfFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node copyOldVersionOfFile.js `
+
+
+-----
+
+
+
+
+### Create a Dual-Region Bucket
+
+Create a Dual-Region Bucket with provided location and regions.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithDualRegion.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createBucketWithDualRegion.js,samples/README.md)
+
+__Usage:__
+
+
+`node createBucketWithDualRegion.js `
+
+
+-----
+
+
+
+
+### Create a hierarchical namespace enabled bucket
+
+Create a hierarchical namespace enabled bucket.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithHierarchicalNamespace.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createBucketWithHierarchicalNamespace.js,samples/README.md)
+
+__Usage:__
+
+
+`node createBucketWithHierarchicalNamespace.js `
+
+
+-----
+
+
+
+
+### Create a Bucket with object retention enabled.
+
+Create a Bucket with object retention enabled.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithObjectRetention.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createBucketWithObjectRetention.js,samples/README.md)
+
+__Usage:__
+
+
+`node createBucketWithObjectRetention.js `
+
+
+-----
+
+
+
+
+### Create Bucket With Storage Class and Location.
+
+Create Bucket With Storage Class and Location.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithStorageClassAndLocation.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createBucketWithStorageClassAndLocation.js,samples/README.md)
+
+__Usage:__
+
+
+`node createBucketWithStorageClassAndLocation.js `
+
+
+-----
+
+
+
+
+### Create Bucket With Turbo Replication
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createBucketWithTurboReplication.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createBucketWithTurboReplication.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/createBucketWithTurboReplication.js`
+
+
+-----
+
+
+
+
+### Create New Bucket
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createNewBucket.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createNewBucket.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/createNewBucket.js`
+
+
+-----
+
+
+
+
+### Create Notification
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/createNotification.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/createNotification.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/createNotification.js`
+
+
+-----
+
+
+
+
+### Delete Bucket
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/deleteBucket.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/deleteBucket.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/deleteBucket.js`
+
+
+-----
+
+
+
+
+### Delete File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/deleteFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/deleteFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/deleteFile.js`
+
+
+-----
+
+
+
+
+### Delete Notification
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/deleteNotification.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/deleteNotification.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/deleteNotification.js`
+
+
+-----
+
+
+
+
+### Delete Old Version Of File.
+
+Delete Old Version Of File.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/deleteOldVersionOfFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/deleteOldVersionOfFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node deleteOldVersionOfFile.js `
+
+
+-----
+
+
+
+
+### Disable Bucket Lifecycle Management
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableBucketLifecycleManagement.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableBucketLifecycleManagement.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/disableBucketLifecycleManagement.js`
+
+
+-----
+
+
+
+
+### Storage Disable Bucket Versioning.
+
+Disables bucket versioning.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableBucketVersioning.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableBucketVersioning.js,samples/README.md)
+
+__Usage:__
+
+
+`node disableBucketVersioning.js `
+
+
+-----
+
+
+
+
+### Disable Default Event Based Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableDefaultEventBasedHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableDefaultEventBasedHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/disableDefaultEventBasedHold.js`
+
+
+-----
+
+
+
+
+### Disable Requester Pays
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableRequesterPays.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableRequesterPays.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/disableRequesterPays.js`
+
+
+-----
+
+
+
+
+### Disable Soft Delete
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableSoftDelete.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableSoftDelete.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/disableSoftDelete.js`
+
+
+-----
+
+
+
+
+### Disable Uniform Bucket Level Access
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/disableUniformBucketLevelAccess.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/disableUniformBucketLevelAccess.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/disableUniformBucketLevelAccess.js`
+
+
+-----
+
+
+
+
+### Download Byte Range
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadByteRange.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadByteRange.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/downloadByteRange.js`
+
+
+-----
+
+
+
+
+### Download Encrypted File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadEncryptedFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadEncryptedFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/downloadEncryptedFile.js`
+
+
+-----
+
+
+
+
+### Download File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/downloadFile.js`
+
+
+-----
+
+
+
+
+### Download a File in Chunks With Transfer Manager
+
+Downloads a single file in in chunks in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadFileInChunksWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadFileInChunksWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node downloadFileInChunksWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Download File Using Requester Pays
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadFileUsingRequesterPays.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadFileUsingRequesterPays.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/downloadFileUsingRequesterPays.js`
+
+
+-----
+
+
+
+
+### Download Folder With Transfer Manager
+
+Downloads a folder in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadFolderWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadFolderWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node downloadFolderWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Download Into Memory
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadIntoMemory.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadIntoMemory.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/downloadIntoMemory.js`
+
+
+-----
+
+
+
+
+### Download Many Files With Transfer Manager
+
+Downloads many files in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadManyFilesWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadManyFilesWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node downloadManyFilesWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Storage Download Public File.
+
+Download Public File.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadPublicFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/downloadPublicFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node downloadPublicFile.js `
+
+
+-----
+
+
+
+
+### Enable Bucket Lifecycle Management
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableBucketLifecycleManagement.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableBucketLifecycleManagement.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/enableBucketLifecycleManagement.js`
+
+
+-----
+
+
+
+
+### Storage Enable Bucket Versioning.
+
+Enables bucket versioning.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableBucketVersioning.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableBucketVersioning.js,samples/README.md)
+
+__Usage:__
+
+
+`node enableBucketVersioning.js `
+
+
+-----
+
+
+
+
+### Enable Default Event Based Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableDefaultEventBasedHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableDefaultEventBasedHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/enableDefaultEventBasedHold.js`
+
+
+-----
+
+
+
+
+### Enable Default KMS Key
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableDefaultKMSKey.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableDefaultKMSKey.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/enableDefaultKMSKey.js`
+
+
+-----
+
+
+
+
+### Enable Requester Pays
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableRequesterPays.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableRequesterPays.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/enableRequesterPays.js`
+
+
+-----
+
+
+
+
+### Enable Uniform Bucket Level Access
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/enableUniformBucketLevelAccess.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/enableUniformBucketLevelAccess.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/enableUniformBucketLevelAccess.js`
+
+
+-----
+
+
+
+
+### Change File's Storage Class.
+
+Change File's Storage Class.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/fileChangeStorageClass.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/fileChangeStorageClass.js,samples/README.md)
+
+__Usage:__
+
+
+`node fileChangeStorageClass.js `
+
+
+-----
+
+
+
+
+### Storage Set File Metadata.
+
+Set file metadata.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/fileSetMetadata.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/fileSetMetadata.js,samples/README.md)
+
+__Usage:__
+
+
+`node fileSetMetadata.js `
+
+
+-----
+
+
+
+
+### Generate Encryption Key
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/generateEncryptionKey.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/generateEncryptionKey.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/generateEncryptionKey.js`
+
+
+-----
+
+
+
+
+### Generate Signed Url
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/generateSignedUrl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/generateSignedUrl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/generateSignedUrl.js`
+
+
+-----
+
+
+
+
+### Generate V4 Read Signed Url
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/generateV4ReadSignedUrl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/generateV4ReadSignedUrl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/generateV4ReadSignedUrl.js`
+
+
+-----
+
+
+
+
+### Generate V4 Signed Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/generateV4SignedPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/generateV4SignedPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/generateV4SignedPolicy.js`
+
+
+-----
+
+
+
+
+### Generate V4 Upload Signed Url
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/generateV4UploadSignedUrl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/generateV4UploadSignedUrl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/generateV4UploadSignedUrl.js`
+
+
+-----
+
+
+
+
+### Get Autoclass
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getAutoclass.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getAutoclass.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getAutoclass.js`
+
+
+-----
+
+
+
+
+### Get Default Event Based Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getDefaultEventBasedHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getDefaultEventBasedHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getDefaultEventBasedHold.js`
+
+
+-----
+
+
+
+
+### Get Metadata
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getMetadata.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getMetadata.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getMetadata.js`
+
+
+-----
+
+
+
+
+### Get Metadata Notifications
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getMetadataNotifications.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getMetadataNotifications.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getMetadataNotifications.js`
+
+
+-----
+
+
+
+
+### Get Public Access Prevention
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getPublicAccessPrevention.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getPublicAccessPrevention.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getPublicAccessPrevention.js`
+
+
+-----
+
+
+
+
+### Get RPO
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getRPO.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getRPO.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getRPO.js`
+
+
+-----
+
+
+
+
+### Get Requester Pays Status
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getRequesterPaysStatus.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getRequesterPaysStatus.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getRequesterPaysStatus.js`
+
+
+-----
+
+
+
+
+### Get Retention Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getRetentionPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getRetentionPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getRetentionPolicy.js`
+
+
+-----
+
+
+
+
+### Storage Get Service Account.
+
+Get Service Account.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getServiceAccount.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getServiceAccount.js,samples/README.md)
+
+__Usage:__
+
+
+`node getServiceAccount.js `
+
+
+-----
+
+
+
+
+### Get Soft Delete Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getSoftDeletePolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getSoftDeletePolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getSoftDeletePolicy.js`
+
+
+-----
+
+
+
+
+### Get Soft Deleted Bucket
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getSoftDeletedBucket.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getSoftDeletedBucket.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getSoftDeletedBucket.js`
+
+
+-----
+
+
+
+
+### Get Uniform Bucket Level Access
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/getUniformBucketLevelAccess.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/getUniformBucketLevelAccess.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/getUniformBucketLevelAccess.js`
+
+
+-----
+
+
+
+
+### Activate HMAC SA Key.
+
+Activate HMAC SA Key.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeyActivate.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeyActivate.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyActivate.js [projectId]`
+
+
+-----
+
+
+
+
+### Create HMAC SA Key.
+
+Create HMAC SA Key.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeyCreate.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeyCreate.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyCreate.js [projectId]`
+
+
+-----
+
+
+
+
+### Deactivate HMAC SA Key.
+
+Deactivate HMAC SA Key.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeyDeactivate.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeyDeactivate.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyDeactivate.js [projectId]`
+
+
+-----
+
+
+
+
+### Delete HMAC SA Key.
+
+Delete HMAC SA Key.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeyDelete.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeyDelete.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyDelete.js [projectId]`
+
+
+-----
+
+
+
+
+### Get HMAC SA Key Metadata.
+
+Get HMAC SA Key Metadata.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeyGet.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeyGet.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyGet.js [projectId]`
+
+
+-----
+
+
+
+
+### List HMAC SA Keys Metadata.
+
+List HMAC SA Keys Metadata.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/hmacKeysList.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/hmacKeysList.js,samples/README.md)
+
+__Usage:__
+
+
+`node hmacKeyList.js [projectId]`
+
+
+-----
+
+
+
+
+### List Buckets
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listBuckets.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listBuckets.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listBuckets.js`
+
+
+-----
+
+
+
+
+### List Buckets Partial Success
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listBucketsPartialSuccess.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listBucketsPartialSuccess.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listBucketsPartialSuccess.js`
+
+
+-----
+
+
+
+
+### List Files
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFiles.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFiles.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listFiles.js`
+
+
+-----
+
+
+
+
+### List Files By Prefix
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesByPrefix.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesByPrefix.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listFilesByPrefix.js`
+
+
+-----
+
+
+
+
+### List Files Paginate
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesPaginate.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesPaginate.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listFilesPaginate.js`
+
+
+-----
+
+
+
+
+### List Files with Old Versions.
+
+List Files with Old Versions.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listFilesWithOldVersions.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listFilesWithOldVersions.js,samples/README.md)
+
+__Usage:__
+
+
+`node listFilesWithOldVersions.js `
+
+
+-----
+
+
+
+
+### List Notifications
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listNotifications.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listNotifications.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listNotifications.js`
+
+
+-----
+
+
+
+
+### List Soft Deleted Bucket
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listSoftDeletedBucket.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listSoftDeletedBucket.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listSoftDeletedBucket.js`
+
+
+-----
+
+
+
+
+### List Soft Deleted Object Versions
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listSoftDeletedObjectVersions.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listSoftDeletedObjectVersions.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listSoftDeletedObjectVersions.js`
+
+
+-----
+
+
+
+
+### List Soft Deleted Objects
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/listSoftDeletedObjects.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/listSoftDeletedObjects.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/listSoftDeletedObjects.js`
+
+
+-----
+
+
+
+
+### Lock Retention Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/lockRetentionPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/lockRetentionPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/lockRetentionPolicy.js`
+
+
+-----
+
+
+
+
+### Storage Make Bucket Public.
+
+Storage Make Bucket Public.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/makeBucketPublic.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/makeBucketPublic.js,samples/README.md)
+
+__Usage:__
+
+
+`node makeBucketPublic.js `
+
+
+-----
+
+
+
+
+### Make Public
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/makePublic.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/makePublic.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/makePublic.js`
+
+
+-----
+
+
+
+
+### Move File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/moveFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/moveFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/moveFile.js`
+
+
+-----
+
+
+
+
+### Move File Atomic
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/moveFileAtomic.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/moveFileAtomic.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/moveFileAtomic.js`
+
+
+-----
+
+
+
+
+### Print Bucket Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/printBucketAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/printBucketAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/printBucketAcl.js`
+
+
+-----
+
+
+
+
+### Print Bucket Acl For User
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/printBucketAclForUser.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/printBucketAclForUser.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/printBucketAclForUser.js`
+
+
+-----
+
+
+
+
+### Print File Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/printFileAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/printFileAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/printFileAcl.js`
+
+
+-----
+
+
+
+
+### Print File Acl For User
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/printFileAclForUser.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/printFileAclForUser.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/printFileAclForUser.js`
+
+
+-----
+
+
+
+
+### Quickstart
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/quickstart.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/quickstart.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/quickstart.js`
+
+
+-----
+
+
+
+
+### Release Event Based Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/releaseEventBasedHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/releaseEventBasedHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/releaseEventBasedHold.js`
+
+
+-----
+
+
+
+
+### Release Temporary Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/releaseTemporaryHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/releaseTemporaryHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/releaseTemporaryHold.js`
+
+
+-----
+
+
+
+
+### Remove Bucket Conditional Binding
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketConditionalBinding.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketConditionalBinding.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeBucketConditionalBinding.js`
+
+
+-----
+
+
+
+
+### Storage Remove Bucket Cors Configuration.
+
+Removes bucket cors configuration.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketCors.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketCors.js,samples/README.md)
+
+__Usage:__
+
+
+`node removeBucketCors.js `
+
+
+-----
+
+
+
+
+### Remove Bucket Default Owner
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketDefaultOwner.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketDefaultOwner.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeBucketDefaultOwner.js`
+
+
+-----
+
+
+
+
+### Remove Bucket Iam Member
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketIamMember.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketIamMember.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeBucketIamMember.js`
+
+
+-----
+
+
+
+
+### Storage Remove Bucket Label.
+
+Removes bucket label.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketLabel.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketLabel.js,samples/README.md)
+
+__Usage:__
+
+
+`node removeBucketLabel.js labelone)`
+
+
+-----
+
+
+
+
+### Remove Bucket Owner Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeBucketOwnerAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeBucketOwnerAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeBucketOwnerAcl.js`
+
+
+-----
+
+
+
+
+### Remove Default KMS Key.
+
+Remove Default KMS Key.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeDefaultKMSKey.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeDefaultKMSKey.js,samples/README.md)
+
+__Usage:__
+
+
+`node removeDefaultKMSKey.js `
+
+
+-----
+
+
+
+
+### Remove File Owner Acl
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeFileOwnerAcl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeFileOwnerAcl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeFileOwnerAcl.js`
+
+
+-----
+
+
+
+
+### Remove Retention Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/removeRetentionPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/removeRetentionPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/removeRetentionPolicy.js`
+
+
+-----
+
+
+
+
+### Rename File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/renameFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/renameFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/renameFile.js`
+
+
+-----
+
+
+
+
+### Restore Soft Deleted Bucket
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/restoreSoftDeletedBucket.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/restoreSoftDeletedBucket.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/restoreSoftDeletedBucket.js`
+
+
+-----
+
+
+
+
+### Restore Soft Deleted Object
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/restoreSoftDeletedObject.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/restoreSoftDeletedObject.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/restoreSoftDeletedObject.js`
+
+
+-----
+
+
+
+
+### Rotate Encryption Key
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/rotateEncryptionKey.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/rotateEncryptionKey.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/rotateEncryptionKey.js`
+
+
+-----
+
+
+
+
+### Set Autoclass
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setAutoclass.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setAutoclass.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setAutoclass.js`
+
+
+-----
+
+
+
+
+### Set Client Endpoint
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setClientEndpoint.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setClientEndpoint.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setClientEndpoint.js`
+
+
+-----
+
+
+
+
+### Set Event Based Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setEventBasedHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setEventBasedHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setEventBasedHold.js`
+
+
+-----
+
+
+
+
+### Set the object retention policy of a File.
+
+Set the object retention policy of a File.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setObjectRetentionPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setObjectRetentionPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node setObjectRetentionPolicy.js `
+
+
+-----
+
+
+
+
+### Set Public Access Prevention Enforced
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setPublicAccessPreventionEnforced.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setPublicAccessPreventionEnforced.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setPublicAccessPreventionEnforced.js`
+
+
+-----
+
+
+
+
+### Set Public Access Prevention Inherited
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setPublicAccessPreventionInherited.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setPublicAccessPreventionInherited.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setPublicAccessPreventionInherited.js`
+
+
+-----
+
+
+
+
+### Set RPO Async Turbo
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setRPOAsyncTurbo.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setRPOAsyncTurbo.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setRPOAsyncTurbo.js`
+
+
+-----
+
+
+
+
+### Set RPO Default
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setRPODefault.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setRPODefault.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setRPODefault.js`
+
+
+-----
+
+
+
+
+### Set Retention Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setRetentionPolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setRetentionPolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setRetentionPolicy.js`
+
+
+-----
+
+
+
+
+### Set Soft Delete Policy
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setSoftDeletePolicy.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setSoftDeletePolicy.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setSoftDeletePolicy.js`
+
+
+-----
+
+
+
+
+### Set Temporary Hold
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/setTemporaryHold.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/setTemporaryHold.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/setTemporaryHold.js`
+
+
+-----
+
+
+
+
+### Stream File Download
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/streamFileDownload.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/streamFileDownload.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/streamFileDownload.js`
+
+
+-----
+
+
+
+
+### Stream File Upload
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/streamFileUpload.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/streamFileUpload.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/streamFileUpload.js`
+
+
+-----
+
+
+
+
+### Upload a directory to a bucket.
+
+Uploads full hierarchy of a local directory to a bucket.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadDirectory.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadDirectory.js,samples/README.md)
+
+__Usage:__
+
+
+`node files.js upload-directory `
+
+
+-----
+
+
+
+
+### Upload Directory With Transfer Manager
+
+Uploads a directory in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadDirectoryWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadDirectoryWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node uploadFolderWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Upload Encrypted File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadEncryptedFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadEncryptedFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadEncryptedFile.js`
+
+
+-----
+
+
+
+
+### Upload File
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadFile.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadFile.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadFile.js`
+
+
+-----
+
+
+
+
+### Upload a File in Chunks With Transfer Manager
+
+Uploads a single file in in chunks in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadFileInChunksWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadFileInChunksWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node uploadFileInChunksWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Upload File With Kms Key
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadFileWithKmsKey.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadFileWithKmsKey.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadFileWithKmsKey.js`
+
+
+-----
+
+
+
+
+### Upload From Memory
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadFromMemory.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadFromMemory.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadFromMemory.js`
+
+
+-----
+
+
+
+
+### Upload Many Files With Transfer Manager
+
+Uploads many files in parallel utilizing transfer manager.
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadManyFilesWithTransferManager.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadManyFilesWithTransferManager.js,samples/README.md)
+
+__Usage:__
+
+
+`node uploadManyFilesWithTransferManager.js `
+
+
+-----
+
+
+
+
+### Upload Without Authentication
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadWithoutAuthentication.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadWithoutAuthentication.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadWithoutAuthentication.js`
+
+
+-----
+
+
+
+
+### Upload Without Authentication Signed Url
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/uploadWithoutAuthenticationSignedUrl.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/uploadWithoutAuthenticationSignedUrl.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/uploadWithoutAuthenticationSignedUrl.js`
+
+
+-----
+
+
+
+
+### View Bucket Iam Members
+
+View the [source code](https://github.com/googleapis/nodejs-storage/blob/main/samples/viewBucketIamMembers.js).
+
+[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/viewBucketIamMembers.js,samples/README.md)
+
+__Usage:__
+
+
+`node samples/viewBucketIamMembers.js`
+
+
+
+
+
+
+[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png
+[shell_link]: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-storage&page=editor&open_in_editor=samples/README.md
+[product-docs]: https://cloud.google.com/storage
diff --git a/storage/addBucketConditionalBinding.js b/storage/addBucketConditionalBinding.js
new file mode 100644
index 0000000000..db5aac9b4b
--- /dev/null
+++ b/storage/addBucketConditionalBinding.js
@@ -0,0 +1,109 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ roleName = 'roles/storage.objectViewer',
+ title = 'match-prefix',
+ description = 'Applies to objects matching a prefix',
+ expression = 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")',
+ members = 'user:test@example.com'
+) {
+ members = members.split(',');
+ // [START storage_add_bucket_conditional_iam_binding]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The role to grant
+ // const roleName = 'roles/storage.objectViewer';
+
+ // The members to grant the new role to
+ // const members = [
+ // 'user:jdoe@example.com',
+ // 'group:admins@example.com',
+ // ];
+
+ // Create a condition
+ // const title = 'Title';
+ // const description = 'Description';
+ // const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addBucketConditionalBinding() {
+ try {
+ // Get a reference to a Google Cloud Storage bucket
+ const bucket = storage.bucket(bucketName);
+
+ // Gets and updates the bucket's IAM policy
+ const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
+
+ // Set the policy's version to 3 to use condition in bindings.
+ policy.version = 3;
+
+ // Adds the new roles to the bucket's IAM policy
+ policy.bindings.push({
+ role: roleName,
+ members: members,
+ condition: {
+ title: title,
+ description: description,
+ expression: expression,
+ },
+ });
+
+ // Updates the bucket's IAM policy
+ await bucket.iam.setPolicy(policy);
+
+ console.log(
+ `Added the following member(s) with role ${roleName} to ${bucketName}:`
+ );
+
+ members.forEach(member => {
+ console.log(` ${member}`);
+ });
+
+ console.log('with condition:');
+ console.log(` Title: ${title}`);
+ console.log(` Description: ${description}`);
+ console.log(` Expression: ${expression}`);
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket conditional binding:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketConditionalBinding();
+ // [END storage_add_bucket_conditional_iam_binding]
+}
+main(...process.argv.slice(2));
diff --git a/storage/addBucketDefaultOwnerAcl.js b/storage/addBucketDefaultOwnerAcl.js
new file mode 100644
index 0000000000..38431f62a0
--- /dev/null
+++ b/storage/addBucketDefaultOwnerAcl.js
@@ -0,0 +1,64 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', userEmail = 'jdobry@google.com') {
+ // [START storage_add_bucket_default_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The email address of the user to add
+ // const userEmail = 'user-email-to-add';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addBucketDefaultOwner() {
+ try {
+ // Makes the user an owner in the default ACL of the bucket. You can use
+ // addAllUsers(), addDomain(), addProject(), addGroup(), and
+ // addAllAuthenticatedUsers() to grant access to different types of entities.
+ // You can also use "readers" and "writers" to grant different roles.
+ await storage.bucket(bucketName).acl.default.owners.addUser(userEmail);
+
+ console.log(
+ `Added user ${userEmail} as an owner on bucket ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket default owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketDefaultOwner();
+ // [END storage_add_bucket_default_owner]
+}
+main(...process.argv.slice(2));
diff --git a/storage/addBucketIamMember.js b/storage/addBucketIamMember.js
new file mode 100644
index 0000000000..a3b25c5419
--- /dev/null
+++ b/storage/addBucketIamMember.js
@@ -0,0 +1,82 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ roleName = 'roles/storage.objectViewer',
+ members = 'user:test@example.com'
+) {
+ //including this logic so as to not use yargs
+ members = members.split(',');
+ // [START storage_add_bucket_iam_member]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The role to grant
+ // const roleName = 'roles/storage.objectViewer';
+
+ // The members to grant the new role to
+ // const members = [
+ // 'user:jdoe@example.com',
+ // 'group:admins@example.com',
+ // ];
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addBucketIamMember() {
+ try {
+ // Get a reference to a Google Cloud Storage bucket
+ const bucket = storage.bucket(bucketName);
+
+ // For more information please read:
+ // https://cloud.google.com/storage/docs/access-control/iam
+ const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
+
+ // Adds the new roles to the bucket's IAM policy
+ policy.bindings.push({
+ role: roleName,
+ members: members,
+ });
+
+ // Updates the bucket's IAM policy
+ await bucket.iam.setPolicy(policy);
+
+ console.log(
+ `Added the following member(s) with role ${roleName} to ${bucketName}:`
+ );
+
+ members.forEach(member => {
+ console.log(` ${member}`);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket iam member:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketIamMember();
+ // [END storage_add_bucket_iam_member]
+}
+main(...process.argv.slice(2));
diff --git a/storage/addBucketLabel.js b/storage/addBucketLabel.js
new file mode 100644
index 0000000000..6cc6228951
--- /dev/null
+++ b/storage/addBucketLabel.js
@@ -0,0 +1,69 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Add Bucket Label.
+// description: Adds bucket label.
+// usage: node addBucketLabel.js
+
+function main(
+ bucketName = 'my-bucket',
+ labelKey = 'labelone',
+ labelValue = 'labelonevalue'
+) {
+ // [START storage_add_bucket_label]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The key of the label to add
+ // const labelKey = 'label-key-to-add';
+
+ // The value of the label to add
+ // const labelValue = 'label-value-to-add';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ const labels = {
+ [labelKey]: labelValue,
+ };
+
+ async function addBucketLabel() {
+ try {
+ await storage.bucket(bucketName).setMetadata({labels});
+ console.log(`Added label to bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket label:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketLabel();
+ // [END storage_add_bucket_label]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/addBucketOwnerAcl.js b/storage/addBucketOwnerAcl.js
new file mode 100644
index 0000000000..b3ee2f0844
--- /dev/null
+++ b/storage/addBucketOwnerAcl.js
@@ -0,0 +1,64 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', userEmail = 'jdobry@google.com') {
+ // [START storage_add_bucket_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The email address of the user to add
+ // const userEmail = 'user-email-to-add';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addBucketOwner() {
+ try {
+ // Makes the user an owner of the bucket. You can use addAllUsers(),
+ // addDomain(), addProject(), addGroup(), and addAllAuthenticatedUsers()
+ // to grant access to different types of entities. You can also use "readers"
+ // and "writers" to grant different roles.
+ await storage.bucket(bucketName).acl.owners.addUser(userEmail);
+
+ console.log(
+ `Added user ${userEmail} as an owner on bucket ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketOwner();
+ // [END storage_add_bucket_owner]
+}
+main(...process.argv.slice(2));
diff --git a/storage/addBucketWebsiteConfiguration.js b/storage/addBucketWebsiteConfiguration.js
new file mode 100644
index 0000000000..d8541ec816
--- /dev/null
+++ b/storage/addBucketWebsiteConfiguration.js
@@ -0,0 +1,73 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Bucket Website Configuration.
+// description: Bucket Website Configuration.
+// usage: node addBucketWebsiteConfiguration.js
+
+function main(
+ bucketName = 'my-bucket',
+ mainPageSuffix = 'http://example.com',
+ notFoundPage = 'http://example.com/404.html'
+) {
+ // [START storage_define_bucket_website_configuration]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of the main page
+ // const mainPageSuffix = 'http://example.com';
+
+ // The Name of a 404 page
+ // const notFoundPage = 'http://example.com/404.html';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addBucketWebsiteConfiguration() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ website: {
+ mainPageSuffix,
+ notFoundPage,
+ },
+ });
+
+ console.log(
+ `Static website bucket ${bucketName} is set up to use ${mainPageSuffix} as the index page and ${notFoundPage} as the 404 page`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing add bucket website configuration:',
+ error.message || error
+ );
+ }
+ }
+
+ addBucketWebsiteConfiguration();
+ // [END storage_define_bucket_website_configuration]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/addFileOwnerAcl.js b/storage/addFileOwnerAcl.js
new file mode 100644
index 0000000000..a908a03e9c
--- /dev/null
+++ b/storage/addFileOwnerAcl.js
@@ -0,0 +1,68 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ userEmail = 'jdobry@google.com'
+) {
+ // [START storage_add_file_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of the file to access
+ // const fileName = 'file.txt';
+
+ // The email address of the user to add
+ // const userEmail = 'user-email-to-add';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function addFileOwner() {
+ try {
+ await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .acl.owners.addUser(userEmail);
+
+ console.log(`Added user ${userEmail} as an owner on file ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing add file owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ addFileOwner();
+ // [END storage_add_file_owner]
+}
+main(...process.argv.slice(2));
diff --git a/storage/bucketMetadata.js b/storage/bucketMetadata.js
new file mode 100644
index 0000000000..399354e0b2
--- /dev/null
+++ b/storage/bucketMetadata.js
@@ -0,0 +1,53 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Get Bucket Metadata.
+// description: Get bucket metadata.
+// usage: node bucketMetadata.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_bucket_metadata]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getBucketMetadata() {
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Get Bucket Metadata
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+
+ console.log(JSON.stringify(metadata, null, 2));
+ } catch (error) {
+ console.error(
+ 'Error executing get bucket metadata:',
+ error.message || error
+ );
+ }
+ }
+ // [END storage_get_bucket_metadata]
+ getBucketMetadata();
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/changeDefaultStorageClass.js b/storage/changeDefaultStorageClass.js
new file mode 100644
index 0000000000..990ad805ba
--- /dev/null
+++ b/storage/changeDefaultStorageClass.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Change Bucket's Default Storage Class.
+// description: Change Bucket's Default Storage Class.
+// usage: node changeDefaultStorageClass.js
+
+function main(bucketName = 'my-bucket', storageClass = 'standard') {
+ // [START storage_change_default_storage_class]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of a storage class
+ // See the StorageClass documentation for other valid storage classes:
+ // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/storage/StorageClass.html
+ // const storageClass = 'coldline';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function changeDefaultStorageClass() {
+ try {
+ await storage.bucket(bucketName).setStorageClass(storageClass);
+
+ console.log(`${bucketName} has been set to ${storageClass}`);
+ } catch (error) {
+ console.error(
+ 'Error executing change default storage class:',
+ error.message || error
+ );
+ }
+ }
+
+ changeDefaultStorageClass();
+ // [END storage_change_default_storage_class]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/changeFileCSEKToCMEK.js b/storage/changeFileCSEKToCMEK.js
new file mode 100644
index 0000000000..9b9902455d
--- /dev/null
+++ b/storage/changeFileCSEKToCMEK.js
@@ -0,0 +1,89 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage File Convert CSEK to CMEK.
+// description: Storage File Convert CSEK to CMEK.
+// usage: node changeFileCSEKToCMEK.js
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ encryptionKey = 'my-encription-key',
+ kmsKeyName = 'my-kms-key',
+ generationMatchPrecondition = 0
+) {
+ // [START storage_object_csek_to_cmek]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The Base64 encoded decryption key, which should be the same key originally
+ // used to encrypt the file
+ // const encryptionKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
+
+ // The name of the KMS key to manage this file with
+ // const kmsKeyName = 'projects/your-project-id/locations/global/keyRings/your-key-ring/cryptoKeys/your-key';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function changeFileCSEKToCMEK() {
+ try {
+ const rotateEncryptionKeyOptions = {
+ kmsKeyName,
+ // Optional: set a generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to copy is aborted if the
+ // object's generation number does not match your precondition.
+ preconditionOpts: {
+ ifGenerationMatch: generationMatchPrecondition,
+ },
+ };
+
+ console.log(rotateEncryptionKeyOptions);
+
+ await storage
+ .bucket(bucketName)
+ .file(fileName, {
+ encryptionKey: Buffer.from(encryptionKey, 'base64'),
+ })
+ .rotateEncryptionKey({
+ rotateEncryptionKeyOptions,
+ });
+
+ console.log(
+ `file ${fileName} in bucket ${bucketName} is now managed by KMS key ${kmsKeyName} instead of customer-supplied encryption key`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing change file CSEK to CMEK:',
+ error.message || error
+ );
+ }
+ }
+
+ changeFileCSEKToCMEK();
+ // [END storage_object_csek_to_cmek]
+}
+main(...process.argv.slice(2));
diff --git a/storage/composeFile.js b/storage/composeFile.js
new file mode 100644
index 0000000000..817223dd15
--- /dev/null
+++ b/storage/composeFile.js
@@ -0,0 +1,79 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Combine files.
+// description: Combine multiple files into one new file.
+// usage: node composeFile.js
+
+function main(
+ bucketName = 'my-bucket',
+ firstFileName = 'file-one.txt',
+ secondFileName = 'file-two.txt',
+ destinationFileName = 'file-one-two.txt',
+ destinationGenerationMatchPrecondition = 0
+) {
+ // [START storage_compose_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the first GCS file to compose
+ // const firstFileName = 'your-first-file-name';
+
+ // The ID of the second GCS file to compose
+ // const secondFileName = 'your-second-file-name';
+
+ // The ID to give the new composite file
+ // const destinationFileName = 'new-composite-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function composeFile() {
+ try {
+ const bucket = storage.bucket(bucketName);
+ const sources = [firstFileName, secondFileName];
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to compose is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const combineOptions = {
+ ifGenerationMatch: destinationGenerationMatchPrecondition,
+ };
+ await bucket.combine(sources, destinationFileName, combineOptions);
+
+ console.log(
+ `New composite file ${destinationFileName} was created by combining ${firstFileName} and ${secondFileName}`
+ );
+ } catch (error) {
+ console.error('Error executing compose file:', error.message || error);
+ }
+ }
+
+ composeFile();
+ // [END storage_compose_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/configureBucketCors.js b/storage/configureBucketCors.js
new file mode 100644
index 0000000000..0e24b30f63
--- /dev/null
+++ b/storage/configureBucketCors.js
@@ -0,0 +1,87 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Configure Bucket Cors.
+// description: Configures bucket cors.
+// usage: node configureBucketCors.js
+
+function main(
+ bucketName = 'my-bucket',
+ maxAgeSeconds = 3600,
+ method = 'POST',
+ origin = 'http://example.appspot.com',
+ responseHeader = 'content-type'
+) {
+ // [START storage_cors_configuration]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The origin for this CORS config to allow requests from
+ // const origin = 'http://example.appspot.com';
+
+ // The response header to share across origins
+ // const responseHeader = 'Content-Type';
+
+ // The maximum amount of time the browser can make requests before it must
+ // repeat preflighted requests
+ // const maxAgeSeconds = 3600;
+
+ // The name of the method
+ // See the HttpMethod documentation for other HTTP methods available:
+ // https://cloud.google.com/appengine/docs/standard/java/javadoc/com/google/appengine/api/urlfetch/HTTPMethod
+ // const method = 'GET';
+
+ async function configureBucketCors() {
+ try {
+ await storage.bucket(bucketName).setCorsConfiguration([
+ {
+ maxAgeSeconds,
+ method: [method],
+ origin: [origin],
+ responseHeader: [responseHeader],
+ },
+ ]);
+
+ console.log(`Bucket ${bucketName} was updated with a CORS config
+ to allow ${method} requests from ${origin} sharing
+ ${responseHeader} responses across origins`);
+ } catch (error) {
+ console.error(
+ 'Error executing configure bucket cors:',
+ error.message || error
+ );
+ }
+ }
+
+ configureBucketCors();
+ // [END storage_cors_configuration]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/configureRetries.js b/storage/configureRetries.js
new file mode 100644
index 0000000000..245a14b9ad
--- /dev/null
+++ b/storage/configureRetries.js
@@ -0,0 +1,95 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {IdempotencyStrategy} = require('@google-cloud/storage');
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_configure_retries]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage({
+ retryOptions: {
+ // If this is false, requests will not retry and the parameters
+ // below will not affect retry behavior.
+ autoRetry: true,
+ // The multiplier by which to increase the delay time between the
+ // completion of failed requests, and the initiation of the subsequent
+ // retrying request.
+ retryDelayMultiplier: 3,
+ // The total time between an initial request getting sent and its timeout.
+ // After timeout, an error will be returned regardless of any retry attempts
+ // made during this time period.
+ totalTimeout: 500,
+ // The maximum delay time between requests. When this value is reached,
+ // retryDelayMultiplier will no longer be used to increase delay time.
+ maxRetryDelay: 60,
+ // The maximum number of automatic retries attempted before returning
+ // the error.
+ maxRetries: 5,
+ // Will respect other retry settings and attempt to always retry
+ // conditionally idempotent operations, regardless of precondition
+ idempotencyStrategy: IdempotencyStrategy.RetryAlways,
+ },
+ });
+ console.log(
+ 'Functions are customized to be retried according to the following parameters:'
+ );
+ console.log(`Auto Retry: ${storage.retryOptions.autoRetry}`);
+ console.log(
+ `Retry delay multiplier: ${storage.retryOptions.retryDelayMultiplier}`
+ );
+ console.log(`Total timeout: ${storage.retryOptions.totalTimeout}`);
+ console.log(`Maximum retry delay: ${storage.retryOptions.maxRetryDelay}`);
+ console.log(`Maximum retries: ${storage.retryOptions.maxRetries}`);
+ console.log(
+ `Idempotency strategy: ${storage.retryOptions.idempotencyStrategy}`
+ );
+
+ async function deleteFileWithCustomizedRetrySetting() {
+ try {
+ await storage.bucket(bucketName).file(fileName).delete();
+ console.log(`File ${fileName} deleted with a customized retry strategy.`);
+ } catch (error) {
+ console.error(
+ 'Error executing delete file with customized retry setting:',
+ error.message || error
+ );
+ }
+ }
+
+ deleteFileWithCustomizedRetrySetting();
+ // [END storage_configure_retries]
+}
+main(...process.argv.slice(2));
diff --git a/storage/copyFile.js b/storage/copyFile.js
new file mode 100644
index 0000000000..e81b914c2f
--- /dev/null
+++ b/storage/copyFile.js
@@ -0,0 +1,88 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ srcBucketName = 'my-bucket',
+ srcFilename = 'test2.txt',
+ destBucketName = 'my-bucket',
+ destFileName = 'test3.txt',
+ destinationGenerationMatchPrecondition = 0
+) {
+ // [START storage_copy_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of the bucket the original file is in
+ // const srcBucketName = 'your-source-bucket';
+
+ // The ID of the GCS file to copy
+ // const srcFilename = 'your-file-name';
+
+ // The ID of the bucket to copy the file to
+ // const destBucketName = 'target-file-bucket';
+
+ // The ID of the GCS file to create
+ // const destFileName = 'target-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function copyFile() {
+ try {
+ const copyDestination = storage.bucket(destBucketName).file(destFileName);
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to copy is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const copyOptions = {
+ preconditionOpts: {
+ ifGenerationMatch: destinationGenerationMatchPrecondition,
+ },
+ };
+
+ // Copies the file to the other bucket
+ await storage
+ .bucket(srcBucketName)
+ .file(srcFilename)
+ .copy(copyDestination, copyOptions);
+
+ console.log(
+ `gs://${srcBucketName}/${srcFilename} copied to gs://${destBucketName}/${destFileName}`
+ );
+ } catch (error) {
+ console.error('Error executing copy file:', error.message || error);
+ }
+ }
+
+ copyFile();
+ // [END storage_copy_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/copyOldVersionOfFile.js b/storage/copyOldVersionOfFile.js
new file mode 100644
index 0000000000..9353873d62
--- /dev/null
+++ b/storage/copyOldVersionOfFile.js
@@ -0,0 +1,93 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Copy Old Version Of File.
+// description: Copy Old Version Of File.
+// usage: node copyOldVersionOfFile.js
+
+function main(
+ srcBucketName = 'my-bucket',
+ srcFilename = 'test2.txt',
+ destBucketName = 'my-bucket',
+ destFileName = 'test3.txt',
+ generation = 1,
+ destinationGenerationMatchPrecondition = 0
+) {
+ // [START storage_copy_file_archived_generation]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const srcBucketName = "your-unique-bucket-name";
+
+ // The ID of the GCS file to copy an old version of
+ // const srcFilename = "your-file-name";
+
+ // The generation of fileToCopy to copy
+ // const generation = 1579287380533984;
+
+ // The ID of the bucket to copy the file to
+ // const destBucketName = 'target-file-bucket';
+
+ // What to name the new file with the old data from srcFilename
+ // const destFileName = "your-new-file";
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function copyOldVersionOfFile() {
+ try {
+ // Copies the file to the other bucket
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to copy is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const copyOptions = {
+ preconditionOpts: {
+ ifGenerationMatch: destinationGenerationMatchPrecondition,
+ },
+ };
+
+ await storage
+ .bucket(srcBucketName)
+ .file(srcFilename, {
+ generation,
+ })
+ .copy(storage.bucket(destBucketName).file(destFileName), copyOptions);
+
+ console.log(
+ `Generation ${generation} of file ${srcFilename} in bucket ${srcBucketName} was copied to ${destFileName} in bucket ${destBucketName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing copy old version of file:',
+ error.message || error
+ );
+ }
+ }
+
+ copyOldVersionOfFile();
+ // [END storage_copy_file_archived_generation]
+}
+main(...process.argv.slice(2));
diff --git a/storage/createBucketWithDualRegion.js b/storage/createBucketWithDualRegion.js
new file mode 100644
index 0000000000..d49e20d56c
--- /dev/null
+++ b/storage/createBucketWithDualRegion.js
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// sample-metadata:
+// title: Create a Dual-Region Bucket
+// description: Create a Dual-Region Bucket with provided location and regions.
+// usage: node createBucketWithDualRegion.js
+
+function main(
+ bucketName = 'my-bucket',
+ location = 'US',
+ region1 = 'US-EAST1',
+ region2 = 'US-WEST1'
+) {
+ // [START storage_create_bucket_dual_region]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The bucket's pair of regions. Case-insensitive.
+ // See this documentation for other valid locations:
+ // https://cloud.google.com/storage/docs/locations
+ // const location = 'US';
+ // const region1 = 'US-EAST1';
+ // const region2 = 'US-WEST1';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createDualRegionBucket() {
+ // For regions supporting dual-regions see: https://cloud.google.com/storage/docs/locations
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ location,
+ customPlacementConfig: {
+ dataLocations: [region1, region2],
+ },
+ });
+
+ console.log(`Created '${bucket.name}'`);
+ console.log(`- location: '${bucket.metadata.location}'`);
+ console.log(`- locationType: '${bucket.metadata.locationType}'`);
+ console.log(
+ `- customPlacementConfig: '${JSON.stringify(
+ bucket.metadata.customPlacementConfig
+ )}'`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing create dual region bucket:',
+ error.message || error
+ );
+ }
+ }
+
+ createDualRegionBucket();
+ // [END storage_create_bucket_dual_region]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/createBucketWithHierarchicalNamespace.js b/storage/createBucketWithHierarchicalNamespace.js
new file mode 100644
index 0000000000..efb5c40ea0
--- /dev/null
+++ b/storage/createBucketWithHierarchicalNamespace.js
@@ -0,0 +1,72 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// sample-metadata:
+// title: Create a hierarchical namespace enabled bucket
+// description: Create a hierarchical namespace enabled bucket.
+// usage: node createBucketWithHierarchicalNamespace.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_create_bucket_hierarchical_namespace]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createBucketWithHierarchicalNamespace() {
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ iamConfiguration: {
+ uniformBucketLevelAccess: {
+ enabled: true,
+ },
+ },
+ hierarchicalNamespace: {
+ enabled: true,
+ },
+ });
+
+ console.log(
+ `Created '${bucket.name}' with hierarchical namespace enabled.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing create bucket with hierarchical namespace:',
+ error.message || error
+ );
+ }
+ }
+
+ createBucketWithHierarchicalNamespace();
+ // [END storage_create_bucket_hierarchical_namespace]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/createBucketWithObjectRetention.js b/storage/createBucketWithObjectRetention.js
new file mode 100644
index 0000000000..fb6d29c654
--- /dev/null
+++ b/storage/createBucketWithObjectRetention.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// sample-metadata:
+// title: Create a Bucket with object retention enabled.
+// description: Create a Bucket with object retention enabled.
+// usage: node createBucketWithObjectRetention.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_create_bucket_with_object_retention]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createBucketWithObjectRetention() {
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ enableObjectRetention: true,
+ });
+
+ console.log(
+ `Created '${bucket.name}' with object retention enabled setting: ${bucket.metadata.objectRetention.mode}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing create bucket with object retention:',
+ error.message || error
+ );
+ }
+ }
+
+ createBucketWithObjectRetention();
+ // [END storage_create_bucket_with_object_retention]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/createBucketWithStorageClassAndLocation.js b/storage/createBucketWithStorageClassAndLocation.js
new file mode 100644
index 0000000000..5b4adaa796
--- /dev/null
+++ b/storage/createBucketWithStorageClassAndLocation.js
@@ -0,0 +1,82 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// sample-metadata:
+// title: Create Bucket With Storage Class and Location.
+// description: Create Bucket With Storage Class and Location.
+// usage: node createBucketWithStorageClassAndLocation.js
+
+function main(
+ bucketName = 'my-bucket',
+ storageClass = 'coldline',
+ location = 'ASIA'
+) {
+ // [START storage_create_bucket_class_location]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of a storage class
+ // See the StorageClass documentation for other valid storage classes:
+ // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/storage/StorageClass.html
+ // const storageClass = 'coldline';
+
+ // The name of a location
+ // See this documentation for other valid locations:
+ // http://g.co/cloud/storage/docs/locations#location-mr
+ // const location = 'ASIA';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createBucketWithStorageClassAndLocation() {
+ // For default values see: https://cloud.google.com/storage/docs/locations and
+ // https://cloud.google.com/storage/docs/storage-classes
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ location,
+ [storageClass]: true,
+ });
+
+ console.log(
+ `${bucket.name} created with ${storageClass} class in ${location}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing create bucket with storage class and location:',
+ error.message || error
+ );
+ }
+ }
+
+ createBucketWithStorageClassAndLocation();
+ // [END storage_create_bucket_class_location]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/createBucketWithTurboReplication.js b/storage/createBucketWithTurboReplication.js
new file mode 100644
index 0000000000..fdedac9be5
--- /dev/null
+++ b/storage/createBucketWithTurboReplication.js
@@ -0,0 +1,78 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket', location = 'NAM4') {
+ // [START storage_create_bucket_turbo_replication]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of a dual-region location
+ // See this documentation for other valid locations:
+ // https://cloud.google.com/storage/docs/locations#location-dr
+ // const location = 'NAM4';
+
+ // Flag to enable turbo replication for this bucket
+ const rpo = 'ASYNC_TURBO';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createBucketWithTurboReplication() {
+ // For default values see: https://cloud.google.com/storage/docs/locations and
+ // https://cloud.google.com/storage/docs/storage-classes
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ location,
+ rpo,
+ });
+
+ console.log(
+ `${bucket.name} created with the recovery point objective (RPO) set to ${rpo} in ${location}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing create bucket with turbo replication:',
+ error.message || error
+ );
+ }
+ }
+
+ createBucketWithTurboReplication();
+ // [END storage_create_bucket_turbo_replication]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/createNewBucket.js b/storage/createNewBucket.js
new file mode 100644
index 0000000000..9438769ae9
--- /dev/null
+++ b/storage/createNewBucket.js
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_create_bucket]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project asscociated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function createBucket() {
+ // Creates a new bucket in the Asia region with the coldline default storage
+ // class. Leave the second argument blank for default settings.
+ //
+ // For default values see: https://cloud.google.com/storage/docs/locations and
+ // https://cloud.google.com/storage/docs/storage-classes
+
+ try {
+ const [bucket] = await storage.createBucket(bucketName, {
+ location: 'ASIA',
+ storageClass: 'COLDLINE',
+ });
+
+ console.log(`Bucket ${bucket.name} created.`);
+ } catch (error) {
+ console.error('Error executing create bucket:', error.message || error);
+ }
+ }
+
+ createBucket();
+ // [END storage_create_bucket]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/createNotification.js b/storage/createNotification.js
new file mode 100644
index 0000000000..447e0037c5
--- /dev/null
+++ b/storage/createNotification.js
@@ -0,0 +1,63 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+const uuid = require('uuid');
+
+function main(
+ bucketName = 'my-bucket',
+ topic = `nodejs-storage-samples-${uuid.v4()}`
+) {
+ // [START storage_create_bucket_notifications]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of a topic
+ // const topic = 'my-topic';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function createNotification() {
+ try {
+ // Creates a notification
+ await storage.bucket(bucketName).createNotification(topic);
+
+ console.log('Notification subscription created.');
+ } catch (error) {
+ console.error(
+ 'Error executing create notification:',
+ error.message || error
+ );
+ }
+ }
+
+ createNotification();
+ // [END storage_create_bucket_notifications]
+}
+main(...process.argv.slice(2));
diff --git a/storage/deleteBucket.js b/storage/deleteBucket.js
new file mode 100644
index 0000000000..0b08732e8f
--- /dev/null
+++ b/storage/deleteBucket.js
@@ -0,0 +1,52 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_delete_bucket]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function deleteBucket() {
+ try {
+ await storage.bucket(bucketName).delete();
+ console.log(`Bucket ${bucketName} deleted`);
+ } catch (error) {
+ console.error('Error executing delete bucket:', error.message || error);
+ }
+ }
+
+ deleteBucket();
+ // [END storage_delete_bucket]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/deleteFile.js b/storage/deleteFile.js
new file mode 100644
index 0000000000..9e9c702cb2
--- /dev/null
+++ b/storage/deleteFile.js
@@ -0,0 +1,69 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ generationMatchPrecondition = 0
+) {
+ // [START storage_delete_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to delete is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const deleteOptions = {
+ ifGenerationMatch: generationMatchPrecondition,
+ };
+ async function deleteFile() {
+ try {
+ await storage.bucket(bucketName).file(fileName).delete(deleteOptions);
+
+ console.log(`gs://${bucketName}/${fileName} deleted`);
+ } catch (error) {
+ console.error('Error executing delete file:', error.message || error);
+ }
+ }
+
+ deleteFile();
+ // [END storage_delete_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/deleteNotification.js b/storage/deleteNotification.js
new file mode 100644
index 0000000000..90ac6b18af
--- /dev/null
+++ b/storage/deleteNotification.js
@@ -0,0 +1,59 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', notificationId = '1') {
+ // [START storage_delete_bucket_notification]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the notification
+ // const notificationId = '1';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function deleteNotification() {
+ try {
+ // Deletes the notification from the bucket
+ await storage.bucket(bucketName).notification(notificationId).delete();
+
+ console.log(`Notification ${notificationId} deleted.`);
+ } catch (error) {
+ console.error(
+ 'Error executing delete notification:',
+ error.message || error
+ );
+ }
+ }
+
+ deleteNotification();
+ // [END storage_delete_bucket_notification]
+}
+main(...process.argv.slice(2));
diff --git a/storage/deleteOldVersionOfFile.js b/storage/deleteOldVersionOfFile.js
new file mode 100644
index 0000000000..45a430c6b6
--- /dev/null
+++ b/storage/deleteOldVersionOfFile.js
@@ -0,0 +1,66 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Delete Old Version Of File.
+// description: Delete Old Version Of File.
+// usage: node deleteOldVersionOfFile.js
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt', generation = 1) {
+ // [START storage_delete_file_archived_generation]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The generation of fileName to delete
+ // const generation = 1579287380533984;
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function deleteOldVersionOfFile() {
+ try {
+ // Deletes the file from the bucket with given version
+ await storage
+ .bucket(bucketName)
+ .file(fileName, {
+ generation,
+ })
+ .delete();
+
+ console.log(
+ `Generation ${generation} of file ${fileName} was deleted from ${bucketName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing delete old version of file:',
+ error.message || error
+ );
+ }
+ }
+
+ deleteOldVersionOfFile();
+ // [END storage_delete_file_archived_generation]
+}
+main(...process.argv.slice(2));
diff --git a/storage/disableBucketLifecycleManagement.js b/storage/disableBucketLifecycleManagement.js
new file mode 100644
index 0000000000..04569982f9
--- /dev/null
+++ b/storage/disableBucketLifecycleManagement.js
@@ -0,0 +1,55 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to disable Object Lifecycle Management for
+ * a bucket.
+ *
+ * For more information, see the documentation at https://cloud.google.com/storage/docs/lifecycle.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_bucket_lifecycle_management]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function disableBucketLifecycleManagement() {
+ try {
+ await storage.bucket(bucketName).setMetadata({lifecycle: null});
+
+ console.log(`Lifecycle management is disabled for bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing disable bucket lifecycle management:',
+ error.message || error
+ );
+ }
+ }
+
+ disableBucketLifecycleManagement();
+ // [END storage_disable_bucket_lifecycle_management]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/disableBucketVersioning.js b/storage/disableBucketVersioning.js
new file mode 100644
index 0000000000..3c6a4f060e
--- /dev/null
+++ b/storage/disableBucketVersioning.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Disable Bucket Versioning.
+// description: Disables bucket versioning.
+// usage: node disableBucketVersioning.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_versioning]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function disableBucketVersioning() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ versioning: {
+ enabled: false,
+ },
+ });
+
+ console.log(`Versioning is disabled for bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing disable bucket versioning:',
+ error.message || error
+ );
+ }
+ }
+
+ disableBucketVersioning();
+ // [END storage_disable_versioning]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/disableDefaultEventBasedHold.js b/storage/disableDefaultEventBasedHold.js
new file mode 100644
index 0000000000..53237fe56a
--- /dev/null
+++ b/storage/disableDefaultEventBasedHold.js
@@ -0,0 +1,57 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_default_event_based_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function disableDefaultEventBasedHold() {
+ try {
+ // Disables a default event-based hold for a bucket.
+ await storage.bucket(bucketName).setMetadata({
+ defaultEventBasedHold: false,
+ });
+ console.log(`Default event-based hold was disabled for ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing disable default event-based hold:',
+ error.message || error
+ );
+ }
+ }
+
+ disableDefaultEventBasedHold();
+ // [END storage_disable_default_event_based_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/disableRequesterPays.js b/storage/disableRequesterPays.js
new file mode 100644
index 0000000000..e051aa7fe5
--- /dev/null
+++ b/storage/disableRequesterPays.js
@@ -0,0 +1,59 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_requester_pays]
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function disableRequesterPays() {
+ try {
+ // Disables requester-pays requests
+ await storage.bucket(bucketName).disableRequesterPays();
+
+ console.log(
+ `Requester-pays requests have been disabled for bucket ${bucketName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing disable requester pays:',
+ error.message || error
+ );
+ }
+ }
+
+ disableRequesterPays();
+ // [END storage_disable_requester_pays]
+}
+main(...process.argv.slice(2));
diff --git a/storage/disableSoftDelete.js b/storage/disableSoftDelete.js
new file mode 100644
index 0000000000..a65aba4462
--- /dev/null
+++ b/storage/disableSoftDelete.js
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_soft_delete]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function disableSoftDelete() {
+ try {
+ const options = {
+ softDeletePolicy: {
+ retentionDurationSeconds: 0,
+ },
+ };
+
+ const [metadata] = await storage.bucket(bucketName).setMetadata(options);
+
+ console.log(`Bucket ${metadata.name} soft delete policy was disabled`);
+ } catch (error) {
+ console.error(
+ 'Error executing disable soft delete:',
+ error.message || error
+ );
+ }
+ }
+
+ disableSoftDelete();
+ // [END storage_disable_soft_delete]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/disableUniformBucketLevelAccess.js b/storage/disableUniformBucketLevelAccess.js
new file mode 100644
index 0000000000..1b80c0b594
--- /dev/null
+++ b/storage/disableUniformBucketLevelAccess.js
@@ -0,0 +1,63 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_disable_uniform_bucket_level_access]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+ async function disableUniformBucketLevelAccess() {
+ // Disables uniform bucket-level access for the bucket
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ iamConfiguration: {
+ uniformBucketLevelAccess: {
+ enabled: false,
+ },
+ },
+ });
+
+ console.log(
+ `Uniform bucket-level access was disabled for ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing disable uniform bucket-level access:',
+ error.message || error
+ );
+ }
+ }
+
+ disableUniformBucketLevelAccess();
+ // [END storage_disable_uniform_bucket_level_access]
+}
+main(...process.argv.slice(2));
diff --git a/storage/downloadByteRange.js b/storage/downloadByteRange.js
new file mode 100644
index 0000000000..1bb286f970
--- /dev/null
+++ b/storage/downloadByteRange.js
@@ -0,0 +1,87 @@
+/**
+ * Copyright 2021 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+const path = require('path');
+const cwd = path.join(__dirname, '..');
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ startByte = 0,
+ endByte = 20,
+ destFileName = path.join(cwd, 'downloaded.txt')
+) {
+ // [START storage_download_byte_range]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The starting byte at which to begin the download
+ // const startByte = 0;
+
+ // The ending byte at which to end the download
+ // const endByte = 20;
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadByteRange() {
+ try {
+ const options = {
+ destination: destFileName,
+ start: startByte,
+ end: endByte,
+ };
+
+ // Downloads the file from the starting byte to the ending byte specified in options
+ await storage.bucket(bucketName).file(fileName).download(options);
+
+ console.log(
+ `gs://${bucketName}/${fileName} downloaded to ${destFileName} from byte ${startByte} to byte ${endByte}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing download byte range:',
+ error.message || error
+ );
+ }
+ }
+
+ downloadByteRange();
+ // [END storage_download_byte_range]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/downloadEncryptedFile.js b/storage/downloadEncryptedFile.js
new file mode 100644
index 0000000000..ebf3176dff
--- /dev/null
+++ b/storage/downloadEncryptedFile.js
@@ -0,0 +1,82 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on encrypted
+ * files with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+const path = require('path');
+
+function main(
+ bucketName = 'my-bucket',
+ srcFileName = path.join(__dirname, '../resources', 'test.txt'),
+ destFileName = 'test.txt',
+ encryptionKey = process.env.GOOGLE_CLOUD_KMS_KEY_US
+) {
+ // [START storage_download_encrypted_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const srcFileName = 'your-file-name';
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // The Base64 encoded decryption key, which should be the same key originally
+ // used to encrypt the file
+ // const encryptionKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadEncryptedFile() {
+ try {
+ const options = {
+ destination: destFileName,
+ };
+
+ // Decrypts and downloads the file. This can only be done with the key used
+ // to encrypt and upload the file.
+ await storage
+ .bucket(bucketName)
+ .file(srcFileName)
+ .setEncryptionKey(Buffer.from(encryptionKey, 'base64'))
+ .download(options);
+
+ console.log(`File ${srcFileName} downloaded to ${destFileName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing download encrypted file:',
+ error.message || error
+ );
+ }
+ }
+
+ downloadEncryptedFile();
+ // [END storage_download_encrypted_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/downloadFile.js b/storage/downloadFile.js
new file mode 100644
index 0000000000..1b9ccf3026
--- /dev/null
+++ b/storage/downloadFile.js
@@ -0,0 +1,71 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+const path = require('path');
+const cwd = path.join(__dirname, '..');
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ destFileName = path.join(cwd, 'downloaded.txt')
+) {
+ // [START storage_download_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadFile() {
+ try {
+ const options = {
+ destination: destFileName,
+ };
+
+ // Downloads the file
+ await storage.bucket(bucketName).file(fileName).download(options);
+
+ console.log(
+ `gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
+ );
+ } catch (error) {
+ console.error('Error executing download file:', error.message || error);
+ }
+ }
+
+ downloadFile().catch(console.error);
+ // [END storage_download_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/downloadFileInChunksWithTransferManager.js b/storage/downloadFileInChunksWithTransferManager.js
new file mode 100644
index 0000000000..5fe1e64cd6
--- /dev/null
+++ b/storage/downloadFileInChunksWithTransferManager.js
@@ -0,0 +1,77 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+const path = require('path');
+const cwd = path.join(__dirname, '..');
+
+// sample-metadata:
+// title: Download a File in Chunks With Transfer Manager
+// description: Downloads a single file in in chunks in parallel utilizing transfer manager.
+// usage: node downloadFileInChunksWithTransferManager.js
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'file1.txt',
+ destFileName = path.join(cwd, fileName),
+ chunkSize = 1024
+) {
+ // [START storage_transfer_manager_download_chunks_concurrently]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the GCS file to download
+ // const fileName = 'your-file-name';
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // The size of each chunk to be downloaded
+ // const chunkSize = 1024;
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function downloadFileInChunksWithTransferManager() {
+ // Downloads the files
+ await transferManager.downloadFileInChunks(fileName, {
+ destination: destFileName,
+ chunkSizeBytes: chunkSize,
+ });
+
+ console.log(
+ `gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
+ );
+ }
+
+ downloadFileInChunksWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_download_chunks_concurrently]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/downloadFileUsingRequesterPays.js b/storage/downloadFileUsingRequesterPays.js
new file mode 100644
index 0000000000..7e27c8fb06
--- /dev/null
+++ b/storage/downloadFileUsingRequesterPays.js
@@ -0,0 +1,81 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+const uuid = require('uuid');
+const path = require('path');
+
+function main(
+ projectId = 'cloud-devrel-public-resources',
+ bucketName = `nodejs-storage-samples-${uuid.v4()}`,
+ srcFileName = 'test.txt',
+ destFileName = path.join(__dirname, `test_${uuid.v4()}.txt`)
+) {
+ // [START storage_download_file_requester_pays]
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The project ID to bill
+ // const projectId = 'my-billable-project-id';
+
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const srcFileName = 'your-file-name';
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadFileUsingRequesterPays() {
+ try {
+ const options = {
+ destination: destFileName,
+ userProject: projectId,
+ };
+
+ // Downloads the file
+ await storage.bucket(bucketName).file(srcFileName).download(options);
+
+ console.log(
+ `gs://${bucketName}/${srcFileName} downloaded to ${destFileName} using requester-pays requests`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing download file using requester pays:',
+ error.message || error
+ );
+ }
+ }
+
+ downloadFileUsingRequesterPays();
+ // [END storage_download_file_requester_pays]
+}
+main(...process.argv.slice(2));
diff --git a/storage/downloadFolderWithTransferManager.js b/storage/downloadFolderWithTransferManager.js
new file mode 100644
index 0000000000..9087f1f712
--- /dev/null
+++ b/storage/downloadFolderWithTransferManager.js
@@ -0,0 +1,60 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// sample-metadata:
+// title: Download Folder With Transfer Manager
+// description: Downloads a folder in parallel utilizing transfer manager.
+// usage: node downloadFolderWithTransferManager.js
+
+function main(bucketName = 'my-bucket', folderName = 'my-folder') {
+ // [START storage_transfer_manager_download_folder]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the GCS folder to download. The folder will be downloaded to the local path of the executing code.
+ // const folderName = 'your-folder-name';
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function downloadFolderWithTransferManager() {
+ // Downloads the folder
+ await transferManager.downloadManyFiles(folderName);
+
+ console.log(
+ `gs://${bucketName}/${folderName} downloaded to ${folderName}.`
+ );
+ }
+
+ downloadFolderWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_download_folder]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/downloadIntoMemory.js b/storage/downloadIntoMemory.js
new file mode 100644
index 0000000000..1f69fc161a
--- /dev/null
+++ b/storage/downloadIntoMemory.js
@@ -0,0 +1,65 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_file_download_into_memory]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadIntoMemory() {
+ try {
+ // Downloads the file into a buffer in memory.
+ const contents = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .download();
+
+ console.log(
+ `Contents of gs://${bucketName}/${fileName} are ${contents.toString()}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing file download into memory:',
+ error.message || error
+ );
+ }
+ }
+
+ downloadIntoMemory();
+ // [END storage_file_download_into_memory]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/downloadManyFilesWithTransferManager.js b/storage/downloadManyFilesWithTransferManager.js
new file mode 100644
index 0000000000..7a464ad4c6
--- /dev/null
+++ b/storage/downloadManyFilesWithTransferManager.js
@@ -0,0 +1,67 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// sample-metadata:
+// title: Download Many Files With Transfer Manager
+// description: Downloads many files in parallel utilizing transfer manager.
+// usage: node downloadManyFilesWithTransferManager.js
+
+function main(
+ bucketName = 'my-bucket',
+ firstFileName = 'file1.txt',
+ secondFileName = 'file2.txt'
+) {
+ // [START storage_transfer_manager_download_many]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the first GCS file to download
+ // const firstFileName = 'your-first-file-name';
+
+ // The ID of the second GCS file to download
+ // const secondFileName = 'your-second-file-name;
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function downloadManyFilesWithTransferManager() {
+ // Downloads the files
+ await transferManager.downloadManyFiles([firstFileName, secondFileName]);
+
+ for (const fileName of [firstFileName, secondFileName]) {
+ console.log(`gs://${bucketName}/${fileName} downloaded to ${fileName}.`);
+ }
+ }
+
+ downloadManyFilesWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_download_many]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/downloadPublicFile.js b/storage/downloadPublicFile.js
new file mode 100644
index 0000000000..ba80658ed2
--- /dev/null
+++ b/storage/downloadPublicFile.js
@@ -0,0 +1,72 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Download Public File.
+// description: Download Public File.
+// usage: node downloadPublicFile.js
+
+const path = require('path');
+const cwd = path.join(__dirname, '..');
+
+function main(
+ bucketName = 'my-bucket',
+ srcFileName = 'test.txt',
+ destFileName = path.join(cwd, 'downloaded.txt')
+) {
+ // [START storage_download_public_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const srcFilename = 'your-file-name';
+
+ // The path to which the file should be downloaded
+ // const destFileName = '/local/path/to/file.txt';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function downloadPublicFile() {
+ try {
+ const options = {
+ destination: destFileName,
+ };
+
+ // Download public file.
+ await storage.bucket(bucketName).file(srcFileName).download(options);
+
+ console.log(
+ `Downloaded public file ${srcFileName} from bucket name ${bucketName} to ${destFileName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing download public file:',
+ error.message || error
+ );
+ }
+ }
+
+ downloadPublicFile();
+ // [END storage_download_public_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/enableBucketLifecycleManagement.js b/storage/enableBucketLifecycleManagement.js
new file mode 100644
index 0000000000..a3157c93d3
--- /dev/null
+++ b/storage/enableBucketLifecycleManagement.js
@@ -0,0 +1,64 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to enable Object Lifecycle Management for
+ * a bucket.
+ *
+ * For more information, see the documentation at https://cloud.google.com/storage/docs/lifecycle.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_enable_bucket_lifecycle_management]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function enableBucketLifecycleManagement() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).addLifecycleRule({
+ action: {
+ type: 'Delete',
+ },
+ condition: {age: 100},
+ });
+
+ console.log(
+ `Lifecycle management is enabled for bucket ${bucketName} and the rules are:`
+ );
+
+ console.log(metadata.lifecycle.rule);
+ } catch (error) {
+ console.error(
+ 'Error executing enable bucket lifecycle management:',
+ error.message || error
+ );
+ }
+ }
+
+ enableBucketLifecycleManagement();
+ // [END storage_enable_bucket_lifecycle_management]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/enableBucketVersioning.js b/storage/enableBucketVersioning.js
new file mode 100644
index 0000000000..e0bb9408d1
--- /dev/null
+++ b/storage/enableBucketVersioning.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Enable Bucket Versioning.
+// description: Enables bucket versioning.
+// usage: node enableBucketVersioning.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_enable_versioning]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function enableBucketVersioning() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ versioning: {
+ enabled: true,
+ },
+ });
+
+ console.log(`Versioning is enabled for bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing enable bucket versioning:',
+ error.message || error
+ );
+ }
+ }
+
+ enableBucketVersioning();
+ // [END storage_enable_versioning]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/enableDefaultEventBasedHold.js b/storage/enableDefaultEventBasedHold.js
new file mode 100644
index 0000000000..16efcfcf94
--- /dev/null
+++ b/storage/enableDefaultEventBasedHold.js
@@ -0,0 +1,59 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_enable_default_event_based_hold]
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function enableDefaultEventBasedHold() {
+ try {
+ // Enables a default event-based hold for the bucket.
+ await storage.bucket(bucketName).setMetadata({
+ defaultEventBasedHold: true,
+ });
+
+ console.log(`Default event-based hold was enabled for ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing enable default event-based hold:',
+ error.message || error
+ );
+ }
+ }
+
+ enableDefaultEventBasedHold();
+ // [END storage_enable_default_event_based_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/enableDefaultKMSKey.js b/storage/enableDefaultKMSKey.js
new file mode 100644
index 0000000000..9d1eef7590
--- /dev/null
+++ b/storage/enableDefaultKMSKey.js
@@ -0,0 +1,68 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ defaultKmsKeyName = process.env.GOOGLE_CLOUD_KMS_KEY_ASIA
+) {
+ // [START storage_set_bucket_default_kms_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The name of the KMS-key to use as a default
+ // const defaultKmsKeyName = 'my-key';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function enableDefaultKMSKey() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ encryption: {
+ defaultKmsKeyName,
+ },
+ });
+
+ console.log(
+ `Default KMS key for ${bucketName} was set to ${defaultKmsKeyName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing enable default KMS key:',
+ error.message || error
+ );
+ }
+ }
+
+ enableDefaultKMSKey();
+ // [END storage_set_bucket_default_kms_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/enableRequesterPays.js b/storage/enableRequesterPays.js
new file mode 100644
index 0000000000..4763f75b92
--- /dev/null
+++ b/storage/enableRequesterPays.js
@@ -0,0 +1,57 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_enable_requester_pays]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function enableRequesterPays() {
+ try {
+ await storage.bucket(bucketName).enableRequesterPays();
+
+ console.log(
+ `Requester-pays requests have been enabled for bucket ${bucketName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing enable requester pays:',
+ error.message || error
+ );
+ }
+ }
+
+ enableRequesterPays();
+ // [END storage_enable_requester_pays]
+}
+main(...process.argv.slice(2));
diff --git a/storage/enableUniformBucketLevelAccess.js b/storage/enableUniformBucketLevelAccess.js
new file mode 100644
index 0000000000..828fdf0247
--- /dev/null
+++ b/storage/enableUniformBucketLevelAccess.js
@@ -0,0 +1,63 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_enable_uniform_bucket_level_access]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Enables uniform bucket-level access for the bucket
+ async function enableUniformBucketLevelAccess() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ iamConfiguration: {
+ uniformBucketLevelAccess: {
+ enabled: true,
+ },
+ },
+ });
+
+ console.log(`Uniform bucket-level access was enabled for ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing enable uniform bucket-level access:',
+ error.message || error
+ );
+ }
+ }
+
+ enableUniformBucketLevelAccess();
+ // [END storage_enable_uniform_bucket_level_access]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/fileChangeStorageClass.js b/storage/fileChangeStorageClass.js
new file mode 100644
index 0000000000..2aad38dac5
--- /dev/null
+++ b/storage/fileChangeStorageClass.js
@@ -0,0 +1,79 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Change File's Storage Class.
+// description: Change File's Storage Class.
+// usage: node fileChangeStorageClass.js
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'file.txt',
+ storageClass = 'standard',
+ generationMatchPrecondition = 0
+) {
+ // [START storage_change_file_storage_class]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The name of a storage class
+ // See the StorageClass documentation for other valid storage classes:
+ // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/storage/StorageClass.html
+ // const storageClass = 'coldline';
+
+ async function fileChangeStorageClass() {
+ try {
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to copy is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const setStorageClassOptions = {
+ ifGenerationMatch: generationMatchPrecondition,
+ };
+
+ await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .setStorageClass(storageClass, setStorageClassOptions);
+
+ console.log(`${fileName} has been set to ${storageClass}`);
+ } catch (error) {
+ console.error(
+ 'Error executing file change storage class:',
+ error.message || error
+ );
+ }
+ }
+
+ fileChangeStorageClass();
+ // [END storage_change_file_storage_class]
+}
+main(...process.argv.slice(2));
diff --git a/storage/fileSetMetadata.js b/storage/fileSetMetadata.js
new file mode 100644
index 0000000000..4e8111abbb
--- /dev/null
+++ b/storage/fileSetMetadata.js
@@ -0,0 +1,93 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Set File Metadata.
+// description: Set file metadata.
+// usage: node fileSetMetadata.js
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'file.txt',
+ metagenerationMatchPrecondition = 0
+) {
+ // [START storage_set_metadata]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ async function setFileMetadata() {
+ try {
+ // Optional: set a meta-generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to set metadata is aborted if the
+ // object's metageneration number does not match your precondition.
+ const options = {
+ ifMetagenerationMatch: metagenerationMatchPrecondition,
+ };
+
+ // Set file metadata.
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .setMetadata(
+ {
+ // Predefined metadata for server e.g. 'cacheControl', 'contentDisposition',
+ // 'contentEncoding', 'contentLanguage', 'contentType'
+ contentDisposition:
+ 'attachment; filename*=utf-8\'\'"anotherImage.jpg"',
+ contentType: 'image/jpeg',
+
+ // A note or actionable items for user e.g. uniqueId, object description,
+ // or other useful information.
+ metadata: {
+ description: 'file description...',
+ modified: '1900-01-01',
+ },
+ },
+ options
+ );
+
+ console.log(
+ 'Updated metadata for object',
+ fileName,
+ 'in bucket ',
+ bucketName
+ );
+ console.log(metadata);
+ } catch (error) {
+ console.error(
+ 'Error executing set file metadata:',
+ error.message || error
+ );
+ }
+ }
+
+ setFileMetadata();
+ // [END storage_set_metadata]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/generateEncryptionKey.js b/storage/generateEncryptionKey.js
new file mode 100644
index 0000000000..5b41d905b8
--- /dev/null
+++ b/storage/generateEncryptionKey.js
@@ -0,0 +1,52 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on encrypted
+ * files with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main() {
+ // [START storage_generate_encryption_key]
+ const crypto = require('crypto');
+
+ function generateEncryptionKey() {
+ try {
+ /**
+ * Generates a 256 bit (32 byte) AES encryption key and prints the base64
+ * representation.
+ *
+ * This is included for demonstration purposes. You should generate your own
+ * key. Please remember that encryption keys should be handled with a
+ * comprehensive security policy.
+ */
+ const buffer = crypto.randomBytes(32);
+ const encodedKey = buffer.toString('base64');
+ console.log(`Base 64 encoded encryption key: ${encodedKey}`);
+ } catch (error) {
+ console.error(
+ 'Error executing generate encryption key:',
+ error.message || error
+ );
+ }
+ }
+ generateEncryptionKey();
+ // [END storage_generate_encryption_key]
+}
+main(...process.argv.slice(2));
diff --git a/storage/generateSignedUrl.js b/storage/generateSignedUrl.js
new file mode 100644
index 0000000000..68395acf44
--- /dev/null
+++ b/storage/generateSignedUrl.js
@@ -0,0 +1,69 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_generate_signed_url]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function generateSignedUrl() {
+ try {
+ // These options will allow temporary read access to the file
+ const options = {
+ version: 'v2', // defaults to 'v2' if missing.
+ action: 'read',
+ expires: Date.now() + 1000 * 60 * 60, // one hour
+ };
+
+ // Get a v2 signed URL for the file
+ const [url] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getSignedUrl(options);
+
+ console.log(`The signed url for ${fileName} is ${url}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing generate signed url:',
+ error.message || error
+ );
+ }
+ }
+
+ generateSignedUrl();
+ // [END storage_generate_signed_url]
+}
+main(...process.argv.slice(2));
diff --git a/storage/generateV4ReadSignedUrl.js b/storage/generateV4ReadSignedUrl.js
new file mode 100644
index 0000000000..81b6f059b7
--- /dev/null
+++ b/storage/generateV4ReadSignedUrl.js
@@ -0,0 +1,74 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_generate_signed_url_v4]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ * Note: when creating a signed URL, unless running in a GCP environment,
+ * a service account must be used for authorization.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The full path of your file inside the GCS bucket, e.g. 'yourFile.jpg' or 'folder1/folder2/yourFile.jpg'
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function generateV4ReadSignedUrl() {
+ try {
+ // These options will allow temporary read access to the file
+ const options = {
+ version: 'v4',
+ action: 'read',
+ expires: Date.now() + 15 * 60 * 1000, // 15 minutes
+ };
+
+ // Get a v4 signed URL for reading the file
+ const [url] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getSignedUrl(options);
+
+ console.log('Generated GET signed URL:');
+ console.log(url);
+ console.log('You can use this URL with any user agent, for example:');
+ console.log(`curl '${url}'`);
+ } catch (error) {
+ console.error(
+ 'Error executing generate v4 read signed url:',
+ error.message || error
+ );
+ }
+ }
+
+ generateV4ReadSignedUrl();
+ // [END storage_generate_signed_url_v4]
+}
+main(...process.argv.slice(2));
diff --git a/storage/generateV4SignedPolicy.js b/storage/generateV4SignedPolicy.js
new file mode 100644
index 0000000000..a222d02cc8
--- /dev/null
+++ b/storage/generateV4SignedPolicy.js
@@ -0,0 +1,81 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_generate_signed_post_policy_v4]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function generateV4SignedPolicy() {
+ try {
+ const bucket = storage.bucket(bucketName);
+ const file = bucket.file(fileName);
+
+ // These options will allow temporary uploading of a file
+ // through an HTML form.
+ const expires = Date.now() + 10 * 60 * 1000; // 10 minutes
+ const options = {
+ expires,
+ fields: {'x-goog-meta-test': 'data'},
+ };
+
+ // Get a v4 signed policy for uploading file
+ const [response] = await file.generateSignedPostPolicyV4(options);
+
+ // Create an HTML form with the provided policy
+ let output = `';
+
+ console.log(output);
+ } catch (error) {
+ console.error(
+ 'Error executing generate v4 signed policy:',
+ error.message || error
+ );
+ }
+ }
+
+ generateV4SignedPolicy();
+ // [END storage_generate_signed_post_policy_v4]
+}
+main(...process.argv.slice(2));
diff --git a/storage/generateV4UploadSignedUrl.js b/storage/generateV4UploadSignedUrl.js
new file mode 100644
index 0000000000..f6d8280170
--- /dev/null
+++ b/storage/generateV4UploadSignedUrl.js
@@ -0,0 +1,77 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_generate_upload_signed_url_v4]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The full path of your file inside the GCS bucket, e.g. 'yourFile.jpg' or 'folder1/folder2/yourFile.jpg'
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function generateV4UploadSignedUrl() {
+ try {
+ // These options will allow temporary uploading of the file with outgoing
+ // Content-Type: application/octet-stream header.
+ const options = {
+ version: 'v4',
+ action: 'write',
+ expires: Date.now() + 15 * 60 * 1000, // 15 minutes
+ contentType: 'application/octet-stream',
+ };
+
+ // Get a v4 signed URL for uploading file
+ const [url] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getSignedUrl(options);
+
+ console.log('Generated PUT signed URL:');
+ console.log(url);
+ console.log('You can use this URL with any user agent, for example:');
+ console.log(
+ "curl -X PUT -H 'Content-Type: application/octet-stream' " +
+ `--upload-file my-file '${url}'`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing generate v4 upload signed url:',
+ error.message || error
+ );
+ }
+ }
+
+ generateV4UploadSignedUrl();
+ // [END storage_generate_upload_signed_url_v4]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getAutoclass.js b/storage/getAutoclass.js
new file mode 100644
index 0000000000..55cf523b87
--- /dev/null
+++ b/storage/getAutoclass.js
@@ -0,0 +1,58 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_autoclass]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getAutoclass() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ console.log(
+ `Autoclass is ${
+ metadata.autoclass.enabled ? 'enabled' : 'disabled'
+ } for ${metadata.name} at ${metadata.autoclass.toggleTime}.
+ Autoclass terminal storage class is last updated to ${
+ metadata.autoclass.terminalStorageClass
+ } at ${metadata.autoclass.terminalStorageClassUpdateTime}.`
+ );
+ } catch (error) {
+ console.error('Error executing get autoclass:', error.message || error);
+ }
+ }
+
+ getAutoclass();
+ // [END storage_get_autoclass]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getDefaultEventBasedHold.js b/storage/getDefaultEventBasedHold.js
new file mode 100644
index 0000000000..b9b3837cb5
--- /dev/null
+++ b/storage/getDefaultEventBasedHold.js
@@ -0,0 +1,56 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_default_event_based_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getDefaultEventBasedHold() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ console.log(
+ `Default event-based hold: ${metadata.defaultEventBasedHold}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing get default event-based hold:',
+ error.message || error
+ );
+ }
+ }
+
+ getDefaultEventBasedHold();
+ // [END storage_get_default_event_based_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getMetadata.js b/storage/getMetadata.js
new file mode 100644
index 0000000000..8959ff1a43
--- /dev/null
+++ b/storage/getMetadata.js
@@ -0,0 +1,97 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_get_metadata]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getMetadata() {
+ try {
+ // Gets the metadata for the file
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getMetadata();
+
+ console.log(`Bucket: ${metadata.bucket}`);
+ console.log(`CacheControl: ${metadata.cacheControl}`);
+ console.log(`ComponentCount: ${metadata.componentCount}`);
+ console.log(`ContentDisposition: ${metadata.contentDisposition}`);
+ console.log(`ContentEncoding: ${metadata.contentEncoding}`);
+ console.log(`ContentLanguage: ${metadata.contentLanguage}`);
+ console.log(`ContentType: ${metadata.contentType}`);
+ console.log(`CustomTime: ${metadata.customTime}`);
+ console.log(`Crc32c: ${metadata.crc32c}`);
+ console.log(`ETag: ${metadata.etag}`);
+ console.log(`Generation: ${metadata.generation}`);
+ console.log(`Id: ${metadata.id}`);
+ console.log(`KmsKeyName: ${metadata.kmsKeyName}`);
+ console.log(`Md5Hash: ${metadata.md5Hash}`);
+ console.log(`MediaLink: ${metadata.mediaLink}`);
+ console.log(`Metageneration: ${metadata.metageneration}`);
+ console.log(`Name: ${metadata.name}`);
+ console.log(`Size: ${metadata.size}`);
+ console.log(`StorageClass: ${metadata.storageClass}`);
+ console.log(`TimeCreated: ${new Date(metadata.timeCreated)}`);
+ console.log(`Last Metadata Update: ${new Date(metadata.updated)}`);
+ console.log(`TurboReplication: ${metadata.rpo}`);
+ console.log(
+ `temporaryHold: ${metadata.temporaryHold ? 'enabled' : 'disabled'}`
+ );
+ console.log(
+ `eventBasedHold: ${metadata.eventBasedHold ? 'enabled' : 'disabled'}`
+ );
+ if (metadata.retentionExpirationTime) {
+ console.log(
+ `retentionExpirationTime: ${new Date(metadata.retentionExpirationTime)}`
+ );
+ }
+ if (metadata.metadata) {
+ console.log('\n\n\nUser metadata:');
+ for (const key in metadata.metadata) {
+ console.log(`${key}=${metadata.metadata[key]}`);
+ }
+ }
+ } catch (error) {
+ console.error('Error executing get metadata:', error.message || error);
+ }
+ }
+
+ getMetadata();
+ // [END storage_get_metadata]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getMetadataNotifications.js b/storage/getMetadataNotifications.js
new file mode 100644
index 0000000000..c1719a840f
--- /dev/null
+++ b/storage/getMetadataNotifications.js
@@ -0,0 +1,67 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', notificationId = '1') {
+ // [START storage_print_pubsub_bucket_notification]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the notification
+ // const notificationId = '1';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getMetadata() {
+ try {
+ // Get the notification metadata
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .notification(notificationId)
+ .getMetadata();
+
+ console.log(`ID: ${metadata.id}`);
+ console.log(`Topic: ${metadata.topic}`);
+ console.log(`Event Types: ${metadata.event_types}`);
+ console.log(`Custom Attributes: ${metadata.custom_attributes}`);
+ console.log(`Payload Format: ${metadata.payload_format}`);
+ console.log(`Object Name Prefix: ${metadata.object_name_prefix}`);
+ console.log(`Etag: ${metadata.etag}`);
+ console.log(`Self Link: ${metadata.selfLink}`);
+ console.log(`Kind: ${metadata.kind}`);
+ } catch (error) {
+ console.error('Error executing get metadata:', error.message || error);
+ }
+ }
+
+ getMetadata();
+ // [END storage_print_pubsub_bucket_notification]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getPublicAccessPrevention.js b/storage/getPublicAccessPrevention.js
new file mode 100644
index 0000000000..e782ed529e
--- /dev/null
+++ b/storage/getPublicAccessPrevention.js
@@ -0,0 +1,59 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_public_access_prevention]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getPublicAccessPrevention() {
+ // Gets Bucket Metadata and prints publicAccessPrevention value (either 'inherited' or 'enforced').
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ console.log(
+ `Public access prevention is ${metadata.iamConfiguration.publicAccessPrevention} for ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing get public access prevention:',
+ error.message || error
+ );
+ }
+ }
+
+ getPublicAccessPrevention();
+
+ // [END storage_get_public_access_prevention]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/getRPO.js b/storage/getRPO.js
new file mode 100644
index 0000000000..1d7bd59523
--- /dev/null
+++ b/storage/getRPO.js
@@ -0,0 +1,58 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_rpo]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket in a dual-region
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getRPO() {
+ // Gets Bucket Metadata and prints RPO value (either 'default' or 'async_turbo').
+ // If RPO is undefined, the bucket is a single region bucket
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ console.log(`RPO is ${metadata.rpo} for ${bucketName}.`);
+ } catch (error) {
+ console.error('Error executing get RPO:', error.message || error);
+ }
+ }
+
+ getRPO();
+
+ // [END storage_get_rpo]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/getRequesterPaysStatus.js b/storage/getRequesterPaysStatus.js
new file mode 100644
index 0000000000..bc530576e5
--- /dev/null
+++ b/storage/getRequesterPaysStatus.js
@@ -0,0 +1,64 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_requester_pays_status]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getRequesterPaysStatus() {
+ try {
+ // Gets the requester-pays status of a bucket
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+
+ let status;
+ if (metadata && metadata.billing && metadata.billing.requesterPays) {
+ status = 'enabled';
+ } else {
+ status = 'disabled';
+ }
+ console.log(
+ `Requester-pays requests are ${status} for bucket ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing get requester pays status:',
+ error.message || error
+ );
+ }
+ }
+
+ getRequesterPaysStatus();
+ // [END storage_get_requester_pays_status]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getRetentionPolicy.js b/storage/getRetentionPolicy.js
new file mode 100644
index 0000000000..6df1fdec3f
--- /dev/null
+++ b/storage/getRetentionPolicy.js
@@ -0,0 +1,64 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_retention_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getRetentionPolicy() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ if (metadata.retentionPolicy) {
+ const retentionPolicy = metadata.retentionPolicy;
+ console.log('A retention policy exists!');
+ console.log(`Period: ${retentionPolicy.retentionPeriod}`);
+ console.log(`Effective time: ${retentionPolicy.effectiveTime}`);
+ if (retentionPolicy.isLocked) {
+ console.log('Policy is locked');
+ } else {
+ console.log('Policy is unlocked');
+ }
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing get bucket retention policy:',
+ error.message || error
+ );
+ }
+ }
+
+ getRetentionPolicy();
+ // [END storage_get_retention_policy]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getServiceAccount.js b/storage/getServiceAccount.js
new file mode 100644
index 0000000000..e3acc72e43
--- /dev/null
+++ b/storage/getServiceAccount.js
@@ -0,0 +1,55 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Get Service Account.
+// description: Get Service Account.
+// usage: node getServiceAccount.js
+
+function main(projectId = 'serviceAccountProjectId') {
+ // [START storage_get_service_account]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCP project
+ // const projectId = 'your-project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage({
+ projectId,
+ });
+
+ async function getServiceAccount() {
+ try {
+ const [serviceAccount] = await storage.getServiceAccount();
+ console.log(
+ `The GCS service account for project ${projectId} is: ${serviceAccount.emailAddress}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing get service account:',
+ error.message || error
+ );
+ }
+ }
+
+ getServiceAccount();
+ // [END storage_get_service_account]
+}
+main(...process.argv.slice(2));
diff --git a/storage/getSoftDeletePolicy.js b/storage/getSoftDeletePolicy.js
new file mode 100644
index 0000000000..b7be0acd39
--- /dev/null
+++ b/storage/getSoftDeletePolicy.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_soft_delete_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getSoftDeletePolicy() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+
+ const softDelete = metadata.softDeletePolicy;
+ if (
+ !softDelete ||
+ !softDelete.retentionDurationSeconds ||
+ softDelete.retentionDurationSeconds === '0'
+ ) {
+ console.log(`Bucket ${metadata.name} soft delete policy was disabled`);
+ } else {
+ console.log(`Soft delete policy for ${metadata.name}`);
+ console.log(
+ `Soft delete Period: ${softDelete.retentionDurationSeconds} seconds`
+ );
+ if (softDelete.effectiveTime) {
+ console.log(`Effective Time: ${softDelete.effectiveTime}`);
+ }
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing get soft delete policy:',
+ error.message || error
+ );
+ }
+ }
+
+ getSoftDeletePolicy();
+ // [END storage_get_soft_delete_policy]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/getSoftDeletedBucket.js b/storage/getSoftDeletedBucket.js
new file mode 100644
index 0000000000..2cd3e8b39e
--- /dev/null
+++ b/storage/getSoftDeletedBucket.js
@@ -0,0 +1,52 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function main(bucketName = 'my-bucket', generation = 123456789) {
+ // [START storage_get_soft_deleted_bucket]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The generation of the bucket to restore
+ // const generation = 123456789;
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getSoftDeletedBucket() {
+ const options = {
+ generation: generation,
+ softDeleted: true,
+ };
+
+ const [metadata] = await storage.bucket(bucketName).getMetadata(options);
+
+ console.log(`Bucket: ${metadata.name}`);
+ console.log(`Generation: ${metadata.generation}`);
+ console.log(`SoftDeleteTime: ${metadata.softDeleteTime}`);
+ console.log(`HardDeleteTime: ${metadata.hardDeleteTime}`);
+ }
+
+ getSoftDeletedBucket().catch(console.error);
+ // [END storage_get_soft_deleted_bucket]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/getUniformBucketLevelAccess.js b/storage/getUniformBucketLevelAccess.js
new file mode 100644
index 0000000000..ff4dddce82
--- /dev/null
+++ b/storage/getUniformBucketLevelAccess.js
@@ -0,0 +1,71 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_get_uniform_bucket_level_access]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function getUniformBucketLevelAccess() {
+ // Gets Bucket Metadata and checks if uniform bucket-level access is enabled.
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+
+ if (metadata.iamConfiguration) {
+ const uniformBucketLevelAccess =
+ metadata.iamConfiguration.uniformBucketLevelAccess;
+ console.log(
+ `Uniform bucket-level access is enabled for ${bucketName}.`
+ );
+ console.log(
+ `Bucket will be locked on ${uniformBucketLevelAccess.lockedTime}.`
+ );
+ } else {
+ console.log(
+ `Uniform bucket-level access is not enabled for ${bucketName}.`
+ );
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing get uniform bucket-level access:',
+ error.message || error
+ );
+ }
+ }
+
+ getUniformBucketLevelAccess();
+
+ // [END storage_get_uniform_bucket_level_access]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeyActivate.js b/storage/hmacKeyActivate.js
new file mode 100644
index 0000000000..29d90070c2
--- /dev/null
+++ b/storage/hmacKeyActivate.js
@@ -0,0 +1,65 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Activate HMAC SA Key.
+// description: Activate HMAC SA Key.
+// usage: node hmacKeyActivate.js [projectId]
+
+function main(
+ hmacKeyAccessId = 'GOOG0234230X00',
+ projectId = 'serviceAccountProjectId'
+) {
+ // [START storage_activate_hmac_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The access ID of the HMAC key
+ // const hmacKeyAccessId = 'GOOG0234230X00';
+
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Activate HMAC SA Key
+ async function activateHmacKey() {
+ try {
+ const hmacKey = storage.hmacKey(hmacKeyAccessId, {projectId});
+ const [hmacKeyMetadata] = await hmacKey.setMetadata({state: 'ACTIVE'});
+
+ console.log('The HMAC key is now active.');
+ console.log('The HMAC key metadata is:');
+ for (const [key, value] of Object.entries(hmacKeyMetadata)) {
+ console.log(`${key}: ${value}`);
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing activate hmac key:',
+ error.message || error
+ );
+ }
+ }
+
+ activateHmacKey();
+ // [END storage_activate_hmac_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeyCreate.js b/storage/hmacKeyCreate.js
new file mode 100644
index 0000000000..a61871cb9f
--- /dev/null
+++ b/storage/hmacKeyCreate.js
@@ -0,0 +1,67 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Create HMAC SA Key.
+// description: Create HMAC SA Key.
+// usage: node hmacKeyCreate.js [projectId]
+
+function main(
+ serviceAccountEmail = 'service-account@example.com',
+ projectId = 'serviceAccountProjectId'
+) {
+ // [START storage_create_hmac_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The service account email for which the new HMAC key will be created
+ // const serviceAccountEmail = 'service-account@iam.gserviceaccount.com';
+
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Create HMAC SA Key
+ async function createHmacKey() {
+ try {
+ const [hmacKey, secret] = await storage.createHmacKey(
+ serviceAccountEmail,
+ {
+ projectId,
+ }
+ );
+
+ console.log(`The base64 encoded secret is: ${secret}`);
+ console.log('Do not miss that secret, there is no API to recover it.');
+ console.log('The HMAC key metadata is:');
+ for (const [key, value] of Object.entries(hmacKey.metadata)) {
+ console.log(`${key}: ${value}`);
+ }
+ } catch (error) {
+ console.error('Error executing create hmac key:', error.message || error);
+ }
+ }
+
+ createHmacKey();
+ // [END storage_create_hmac_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeyDeactivate.js b/storage/hmacKeyDeactivate.js
new file mode 100644
index 0000000000..33c6919ffa
--- /dev/null
+++ b/storage/hmacKeyDeactivate.js
@@ -0,0 +1,65 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Deactivate HMAC SA Key.
+// description: Deactivate HMAC SA Key.
+// usage: node hmacKeyDeactivate.js [projectId]
+
+function main(
+ hmacKeyAccessId = 'GOOG0234230X00',
+ projectId = 'serviceAccountProjectId'
+) {
+ // [START storage_deactivate_hmac_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The access ID of the HMAC key
+ // const hmacKeyAccessId = 'GOOG0234230X00';
+
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Deactivate HMAC SA Key
+ async function deactivateHmacKey() {
+ try {
+ const hmacKey = storage.hmacKey(hmacKeyAccessId, {projectId});
+ const [hmacKeyMetadata] = await hmacKey.setMetadata({state: 'INACTIVE'});
+
+ console.log('The HMAC key is now inactive.');
+ console.log('The HMAC key metadata is:');
+ for (const [key, value] of Object.entries(hmacKeyMetadata)) {
+ console.log(`${key}: ${value}`);
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing deactivate hmac key:',
+ error.message || error
+ );
+ }
+ }
+
+ deactivateHmacKey();
+ // [END storage_deactivate_hmac_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeyDelete.js b/storage/hmacKeyDelete.js
new file mode 100644
index 0000000000..6bc65c60e4
--- /dev/null
+++ b/storage/hmacKeyDelete.js
@@ -0,0 +1,60 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Delete HMAC SA Key.
+// description: Delete HMAC SA Key.
+// usage: node hmacKeyDelete.js [projectId]
+
+function main(
+ hmacKeyAccessId = 'GOOG0234230X00',
+ projectId = 'serviceAccountProjectId'
+) {
+ // [START storage_delete_hmac_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The access ID of the HMAC key
+ // const hmacKeyAccessId = 'GOOG0234230X00';
+
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Delete HMAC SA Key
+ async function deleteHmacKey() {
+ try {
+ const hmacKey = storage.hmacKey(hmacKeyAccessId, {projectId});
+ await hmacKey.delete();
+
+ console.log(
+ 'The key is deleted, though it may still appear in getHmacKeys() results.'
+ );
+ } catch (error) {
+ console.error('Error executing delete hmac key:', error.message || error);
+ }
+ }
+
+ deleteHmacKey();
+ // [END storage_delete_hmac_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeyGet.js b/storage/hmacKeyGet.js
new file mode 100644
index 0000000000..445e85c526
--- /dev/null
+++ b/storage/hmacKeyGet.js
@@ -0,0 +1,63 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Get HMAC SA Key Metadata.
+// description: Get HMAC SA Key Metadata.
+// usage: node hmacKeyGet.js [projectId]
+
+function main(
+ hmacKeyAccessId = 'GOOG0234230X00',
+ projectId = 'serviceAccountProjectId'
+) {
+ // [START storage_get_hmac_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The access ID of the HMAC key
+ // const hmacKeyAccessId = 'GOOG0234230X00';
+
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Get HMAC SA Key Metadata
+ async function getHmacKey() {
+ try {
+ const hmacKey = storage.hmacKey(hmacKeyAccessId, {projectId});
+
+ // Populate the hmacKey object with metadata from server.
+ await hmacKey.getMetadata();
+
+ console.log('The HMAC key metadata is:');
+ for (const [key, value] of Object.entries(hmacKey.metadata)) {
+ console.log(`${key}: ${value}`);
+ }
+ } catch (error) {
+ console.error('Error executing get hmac key:', error.message || error);
+ }
+ }
+
+ getHmacKey();
+ // [END storage_get_hmac_key]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/hmacKeysList.js b/storage/hmacKeysList.js
new file mode 100644
index 0000000000..896fb9d815
--- /dev/null
+++ b/storage/hmacKeysList.js
@@ -0,0 +1,57 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: List HMAC SA Keys Metadata.
+// description: List HMAC SA Keys Metadata.
+// usage: node hmacKeyList.js [projectId]
+
+function main(projectId = 'serviceAccountProjectId') {
+ // [START storage_list_hmac_keys]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of the project to which the service account belongs
+ // const projectId = 'project-id';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // List HMAC SA Keys' Metadata
+ async function listHmacKeys() {
+ try {
+ const [hmacKeys] = await storage.getHmacKeys({projectId});
+
+ // hmacKeys is an array of HmacKey objects.
+ for (const hmacKey of hmacKeys) {
+ console.log(
+ `Service Account Email: ${hmacKey.metadata.serviceAccountEmail}`
+ );
+ console.log(`Access Id: ${hmacKey.metadata.accessId}`);
+ }
+ } catch (error) {
+ console.error('Error executing list hmac keys:', error.message || error);
+ }
+ }
+
+ listHmacKeys();
+ // [END storage_list_hmac_keys]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/listBuckets.js b/storage/listBuckets.js
new file mode 100644
index 0000000000..033495b909
--- /dev/null
+++ b/storage/listBuckets.js
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main() {
+ // [START storage_list_buckets]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listBuckets() {
+ try {
+ const [buckets] = await storage.getBuckets();
+
+ console.log('Buckets:');
+ buckets.forEach(bucket => {
+ console.log(bucket.name);
+ });
+ } catch (error) {
+ console.error('Error executing list buckets:', error.message || error);
+ }
+ }
+
+ listBuckets();
+ // [END storage_list_buckets]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/listBucketsPartialSuccess.js b/storage/listBucketsPartialSuccess.js
new file mode 100644
index 0000000000..c1d0daf55a
--- /dev/null
+++ b/storage/listBucketsPartialSuccess.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function main() {
+ // [START storage_list_buckets_partial_success]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listBucketsPartialSuccess() {
+ const option = {
+ returnPartialSuccess: true,
+ maxResults: 5,
+ };
+ const [buckets, nextQuery, apiResponse] = await storage.getBuckets(option);
+
+ if (nextQuery && nextQuery.pageToken) {
+ console.log(`Next Page Token: ${nextQuery.pageToken}`);
+ }
+
+ console.log('\nBuckets:');
+ buckets.forEach(bucket => {
+ if (bucket.unreachable) {
+ console.log(`${bucket.name} (unreachable: ${bucket.unreachable})`);
+ } else {
+ console.log(`${bucket.name}`);
+ }
+ });
+
+ if (apiResponse.unreachable && apiResponse.unreachable.length > 0) {
+ console.log('\nUnreachable Buckets:');
+ apiResponse.unreachable.forEach(item => {
+ console.log(item);
+ });
+ }
+ }
+
+ listBucketsPartialSuccess().catch(console.error);
+ // [END storage_list_buckets_partial_success]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/listFiles.js b/storage/listFiles.js
new file mode 100644
index 0000000000..8291cb1212
--- /dev/null
+++ b/storage/listFiles.js
@@ -0,0 +1,56 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_list_files]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listFiles() {
+ try {
+ // Lists files in the bucket
+ const [files] = await storage.bucket(bucketName).getFiles();
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name);
+ });
+ } catch (error) {
+ console.error('Error executing list files:', error.message || error);
+ }
+ }
+
+ listFiles();
+ // [END storage_list_files]
+}
+main(...process.argv.slice(2));
diff --git a/storage/listFilesByPrefix.js b/storage/listFilesByPrefix.js
new file mode 100644
index 0000000000..b79bd93d67
--- /dev/null
+++ b/storage/listFilesByPrefix.js
@@ -0,0 +1,92 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', prefix = 'test', delimiter = '/') {
+ // [START storage_list_files_with_prefix]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The directory prefix to search for
+ // const prefix = 'myDirectory/';
+
+ // The delimiter to use
+ // const delimiter = '/';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listFilesByPrefix() {
+ try {
+ /**
+ * This can be used to list all blobs in a "folder", e.g. "public/".
+ *
+ * The delimiter argument can be used to restrict the results to only the
+ * "files" in the given "folder". Without the delimiter, the entire tree under
+ * the prefix is returned. For example, given these blobs:
+ *
+ * /a/1.txt
+ * /a/b/2.txt
+ *
+ * If you just specify prefix = 'a/', you'll get back:
+ *
+ * /a/1.txt
+ * /a/b/2.txt
+ *
+ * However, if you specify prefix='a/' and delimiter='/', you'll get back:
+ *
+ * /a/1.txt
+ */
+ const options = {
+ prefix: prefix,
+ };
+
+ if (delimiter) {
+ options.delimiter = delimiter;
+ }
+
+ // Lists files in the bucket, filtered by a prefix
+ const [files] = await storage.bucket(bucketName).getFiles(options);
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing list files by prefix:',
+ error.message || error
+ );
+ }
+ }
+
+ listFilesByPrefix();
+ // [END storage_list_files_with_prefix]
+}
+main(...process.argv.slice(2));
diff --git a/storage/listFilesPaginate.js b/storage/listFilesPaginate.js
new file mode 100644
index 0000000000..f2716aaa2f
--- /dev/null
+++ b/storage/listFilesPaginate.js
@@ -0,0 +1,67 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_list_files_paginated]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listFilesPaginated() {
+ try {
+ const bucket = storage.bucket(bucketName);
+ const [files, queryForPage2] = await bucket.getFiles({
+ autoPaginate: false,
+ });
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name);
+ });
+
+ // Page through the next set of results using "queryForPage2"
+ if (queryForPage2 !== null) {
+ // We only extract the files, but you could also extract the next query object
+ // const [files, queryForPage3] = await bucket.getFiles(queryForPage2);
+ const [files] = await bucket.getFiles(queryForPage2);
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name);
+ });
+
+ // If necessary, continue cursoring to subsequent pages
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing list files paginated:',
+ error.message || error
+ );
+ }
+ }
+
+ listFilesPaginated();
+ // [END storage_list_files_paginated]
+}
+main(...process.argv.slice(2));
diff --git a/storage/listFilesWithOldVersions.js b/storage/listFilesWithOldVersions.js
new file mode 100644
index 0000000000..269fcc2fb7
--- /dev/null
+++ b/storage/listFilesWithOldVersions.js
@@ -0,0 +1,57 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: List Files with Old Versions.
+// description: List Files with Old Versions.
+// usage: node listFilesWithOldVersions.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_list_file_archived_generations]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listFilesWithOldVersions() {
+ try {
+ const [files] = await storage.bucket(bucketName).getFiles({
+ versions: true,
+ });
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name, file.generation);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing list files with old versions:',
+ error.message || error
+ );
+ }
+ }
+
+ listFilesWithOldVersions();
+ // [END storage_list_file_archived_generations]
+}
+main(...process.argv.slice(2));
diff --git a/storage/listNotifications.js b/storage/listNotifications.js
new file mode 100644
index 0000000000..c41a39a1b7
--- /dev/null
+++ b/storage/listNotifications.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_list_bucket_notifications]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listNotifications() {
+ try {
+ // Lists notifications in the bucket
+ const [notifications] = await storage
+ .bucket(bucketName)
+ .getNotifications();
+
+ console.log('Notifications:');
+ notifications.forEach(notification => {
+ console.log(notification.id);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing list notifications:',
+ error.message || error
+ );
+ }
+ }
+
+ listNotifications();
+ // [END storage_list_bucket_notifications]
+}
+main(...process.argv.slice(2));
diff --git a/storage/listSoftDeletedBucket.js b/storage/listSoftDeletedBucket.js
new file mode 100644
index 0000000000..679bd6caf6
--- /dev/null
+++ b/storage/listSoftDeletedBucket.js
@@ -0,0 +1,42 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function main() {
+ // [START storage_list_soft_deleted_buckets]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listSoftDeletedBuckets() {
+ const options = {
+ softDeleted: true,
+ };
+
+ const [buckets] = await storage.getBuckets(options);
+
+ console.log('Buckets:');
+ buckets.forEach(bucket => {
+ console.log(bucket.name);
+ });
+ }
+
+ listSoftDeletedBuckets().catch(console.error);
+ // [END storage_list_soft_deleted_buckets]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/listSoftDeletedObjectVersions.js b/storage/listSoftDeletedObjectVersions.js
new file mode 100644
index 0000000000..5f5db8bb3f
--- /dev/null
+++ b/storage/listSoftDeletedObjectVersions.js
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_list_soft_deleted_object_versions]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listSoftDeletedObjectVersions() {
+ try {
+ const options = {
+ softDeleted: true,
+ matchGlob: fileName,
+ };
+
+ const [files] = await storage.bucket(bucketName).getFiles(options);
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(
+ `Name: ${file.name}, Generation: ${file.metadata.generation}`
+ );
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing list soft deleted object versions:',
+ error.message || error
+ );
+ }
+ }
+
+ listSoftDeletedObjectVersions();
+ // [END storage_list_soft_deleted_object_versions]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/listSoftDeletedObjects.js b/storage/listSoftDeletedObjects.js
new file mode 100644
index 0000000000..51707c56ad
--- /dev/null
+++ b/storage/listSoftDeletedObjects.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_list_soft_deleted_objects]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function listSoftDeletedObjects() {
+ try {
+ const options = {
+ softDeleted: true,
+ };
+
+ const [files] = await storage.bucket(bucketName).getFiles(options);
+
+ console.log('Files:');
+ files.forEach(file => {
+ console.log(file.name);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing list soft deleted objects:',
+ error.message || error
+ );
+ }
+ }
+
+ listSoftDeletedObjects();
+ // [END storage_list_soft_deleted_objects]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/lockRetentionPolicy.js b/storage/lockRetentionPolicy.js
new file mode 100644
index 0000000000..7323803579
--- /dev/null
+++ b/storage/lockRetentionPolicy.js
@@ -0,0 +1,65 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_lock_retention_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function lockRetentionPolicy() {
+ try {
+ // Gets the current metageneration value for the bucket, required by
+ // lock_retention_policy
+ const [unlockedMetadata] = await storage.bucket(bucketName).getMetadata();
+
+ // Warning: Once a retention policy is locked, it cannot be unlocked. The
+ // retention period can only be increased
+ const [lockedMetadata] = await storage
+ .bucket(bucketName)
+ .lock(unlockedMetadata.metageneration);
+ console.log(`Retention policy for ${bucketName} is now locked`);
+ console.log(
+ `Retention policy effective as of ${lockedMetadata.retentionPolicy.effectiveTime}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing lock bucket retention policy:',
+ error.message || error
+ );
+ }
+ }
+
+ lockRetentionPolicy();
+ // [END storage_lock_retention_policy]
+}
+main(...process.argv.slice(2));
diff --git a/storage/makeBucketPublic.js b/storage/makeBucketPublic.js
new file mode 100644
index 0000000000..447a0da6be
--- /dev/null
+++ b/storage/makeBucketPublic.js
@@ -0,0 +1,56 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Make Bucket Public.
+// description: Storage Make Bucket Public.
+// usage: node makeBucketPublic.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_bucket_public_iam]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function makeBucketPublic() {
+ try {
+ await storage.bucket(bucketName).makePublic();
+
+ console.log(`Bucket ${bucketName} is now publicly readable`);
+ } catch (error) {
+ console.error(
+ 'Error executing make bucket public:',
+ error.message || error
+ );
+ }
+ }
+
+ makeBucketPublic();
+ // [END storage_set_bucket_public_iam]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/makePublic.js b/storage/makePublic.js
new file mode 100644
index 0000000000..504e9503b5
--- /dev/null
+++ b/storage/makePublic.js
@@ -0,0 +1,55 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_make_public]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function makePublic() {
+ try {
+ await storage.bucket(bucketName).file(fileName).makePublic();
+
+ console.log(`gs://${bucketName}/${fileName} is now public.`);
+ } catch (error) {
+ console.error('Error executing make public:', error.message || error);
+ }
+ }
+
+ makePublic();
+ // [END storage_make_public]
+}
+main(...process.argv.slice(2));
diff --git a/storage/moveFile.js b/storage/moveFile.js
new file mode 100644
index 0000000000..530b13cea7
--- /dev/null
+++ b/storage/moveFile.js
@@ -0,0 +1,82 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ srcFileName = 'test.txt',
+ destFileName = 'test2.txt',
+ destinationGenerationMatchPrecondition = 0
+) {
+ // [START storage_move_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-source-bucket';
+
+ // The ID of your GCS file
+ // const srcFileName = 'your-file-name';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function moveFile() {
+ try {
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to copy is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const moveOptions = {
+ preconditionOpts: {
+ ifGenerationMatch: destinationGenerationMatchPrecondition,
+ },
+ };
+
+ // Moves the file within the bucket
+ await storage
+ .bucket(bucketName)
+ .file(srcFileName)
+ .move(destFileName, moveOptions);
+
+ console.log(
+ `gs://${bucketName}/${srcFileName} moved to gs://${bucketName}/${destFileName}`
+ );
+ } catch (error) {
+ console.error('Error executing move file:', error.message || error);
+ }
+ }
+
+ moveFile();
+ // [END storage_move_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/moveFileAtomic.js b/storage/moveFileAtomic.js
new file mode 100644
index 0000000000..79eea2d950
--- /dev/null
+++ b/storage/moveFileAtomic.js
@@ -0,0 +1,85 @@
+// Copyright 2025 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ srcFileName = 'test.txt',
+ destFileName = 'test2.txt',
+ destinationGenerationMatchPrecondition = 0
+) {
+ // [START storage_move_object]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-source-bucket';
+
+ // The ID of your GCS file
+ // const srcFileName = 'your-file-name';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function moveFileAtomic() {
+ try {
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to copy is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ const moveOptions = {
+ preconditionOpts: {
+ ifGenerationMatch: destinationGenerationMatchPrecondition,
+ },
+ };
+
+ // Moves the file atomically within the bucket
+ await storage
+ .bucket(bucketName)
+ .file(srcFileName)
+ .moveFileAtomic(destFileName, moveOptions);
+
+ console.log(
+ `gs://${bucketName}/${srcFileName} moved to gs://${bucketName}/${destFileName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing move file atomic:',
+ error.message || error
+ );
+ }
+ }
+
+ moveFileAtomic();
+ // [END storage_move_object]
+}
+main(...process.argv.slice(2));
diff --git a/storage/package.json b/storage/package.json
new file mode 100644
index 0000000000..71acc18ab5
--- /dev/null
+++ b/storage/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "@google-cloud/storage-samples",
+ "description": "Samples for the Cloud Storage Client Library for Node.js.",
+ "license": "Apache-2.0",
+ "author": "Google Inc.",
+ "engines": {
+ "node": ">=12"
+ },
+ "repository": "googleapis/nodejs-storage",
+ "private": true,
+ "files": [
+ "*.js"
+ ],
+ "scripts": {
+ "cleanup": "node scripts/cleanup",
+ "test": "mocha system-test/*.js --timeout 800000"
+ },
+ "dependencies": {
+ "@google-cloud/pubsub": "^4.0.0",
+ "@google-cloud/storage": "^7.19.0",
+ "node-fetch": "^2.6.7",
+ "uuid": "^8.0.0",
+ "yargs": "^16.0.0"
+ },
+ "devDependencies": {
+ "chai": "^4.2.0",
+ "mocha": "^8.0.0",
+ "p-limit": "^3.1.0"
+ }
+}
diff --git a/storage/printBucketAcl.js b/storage/printBucketAcl.js
new file mode 100644
index 0000000000..c14e682e16
--- /dev/null
+++ b/storage/printBucketAcl.js
@@ -0,0 +1,58 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_print_bucket_acl]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function printBucketAcl() {
+ try {
+ // Gets the ACL for the bucket
+ const [acls] = await storage.bucket(bucketName).acl.get();
+
+ acls.forEach(acl => {
+ console.log(`${acl.role}: ${acl.entity}`);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing print bucket ACL:',
+ error.message || error
+ );
+ }
+ }
+ printBucketAcl();
+ // [END storage_print_bucket_acl]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/printBucketAclForUser.js b/storage/printBucketAclForUser.js
new file mode 100644
index 0000000000..27420478fd
--- /dev/null
+++ b/storage/printBucketAclForUser.js
@@ -0,0 +1,65 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', userEmail = 'jdobry@google.com') {
+ // [START storage_print_bucket_acl_for_user]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The email address of the user to check
+ // const userEmail = 'user-email-to-check';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function printBucketAclForUser() {
+ try {
+ const options = {
+ // Specify the user
+ entity: `user-${userEmail}`,
+ };
+
+ // Gets the user's ACL for the bucket
+ const [aclObject] = await storage.bucket(bucketName).acl.get(options);
+
+ console.log(`${aclObject.role}: ${aclObject.entity}`);
+ } catch (error) {
+ console.error(
+ 'Error executing print bucket ACL for user:',
+ error.message || error
+ );
+ }
+ }
+
+ printBucketAclForUser();
+ // [END storage_print_bucket_acl_for_user]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/printFileAcl.js b/storage/printFileAcl.js
new file mode 100644
index 0000000000..0d9ead9b18
--- /dev/null
+++ b/storage/printFileAcl.js
@@ -0,0 +1,58 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', fileName = 'test.txt') {
+ // [START storage_print_file_acl]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function printFileAcl() {
+ try {
+ // Gets the ACL for the file
+ const [acls] = await storage.bucket(bucketName).file(fileName).acl.get();
+
+ acls.forEach(acl => {
+ console.log(`${acl.role}: ${acl.entity}`);
+ });
+ } catch (error) {
+ console.error('Error executing print file ACL:', error.message || error);
+ }
+ }
+
+ printFileAcl();
+ // [END storage_print_file_acl]
+}
+main(...process.argv.slice(2));
diff --git a/storage/printFileAclForUser.js b/storage/printFileAclForUser.js
new file mode 100644
index 0000000000..396cb393ba
--- /dev/null
+++ b/storage/printFileAclForUser.js
@@ -0,0 +1,74 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ userEmail = 'jdobry@google.com'
+) {
+ // [START storage_print_file_acl_for_user]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The email address of the user to check
+ // const userEmail = 'user-email-to-check';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function printFileAclForUser() {
+ try {
+ const options = {
+ // Specify the user
+ entity: `user-${userEmail}`,
+ };
+
+ // Gets the user's ACL for the file
+ const [aclObject] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .acl.get(options);
+
+ console.log(`${aclObject.role}: ${aclObject.entity}`);
+ } catch (error) {
+ console.error(
+ 'Error executing print file ACL for user:',
+ error.message || error
+ );
+ }
+ }
+
+ printFileAclForUser();
+ // [END storage_print_file_acl_for_user]
+}
+main(...process.argv.slice(2));
diff --git a/storage/quickstart.js b/storage/quickstart.js
new file mode 100644
index 0000000000..6e329da9fa
--- /dev/null
+++ b/storage/quickstart.js
@@ -0,0 +1,51 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(bucketName = 'my-new-bucket') {
+ // [START storage_quickstart]
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // For more information on ways to initialize Storage, please see
+ // https://googleapis.dev/nodejs/storage/latest/Storage.html
+
+ // Creates a client using Application Default Credentials
+ const storage = new Storage();
+
+ // Creates a client from a Google service account key
+ // const storage = new Storage({keyFilename: 'key.json'});
+
+ /**
+ * TODO(developer): Uncomment these variables before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ async function createBucket() {
+ try {
+ // Creates the new bucket
+ await storage.createBucket(bucketName);
+ console.log(`Bucket ${bucketName} created.`);
+ } catch (error) {
+ console.error('Error executing create bucket:', error.message || error);
+ }
+ }
+
+ createBucket();
+ // [END storage_quickstart]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/releaseEventBasedHold.js b/storage/releaseEventBasedHold.js
new file mode 100644
index 0000000000..caeb22a2b2
--- /dev/null
+++ b/storage/releaseEventBasedHold.js
@@ -0,0 +1,73 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ metagenerationMatchPrecondition = 0
+) {
+ // [START storage_release_event_based_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function releaseEventBasedHold() {
+ try {
+ // Optional: set a meta-generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to set metadata is aborted if the
+ // object's metageneration number does not match your precondition.
+ const options = {
+ ifMetagenerationMatch: metagenerationMatchPrecondition,
+ };
+
+ await storage.bucket(bucketName).file(fileName).setMetadata(
+ {
+ eventBasedHold: false,
+ },
+ options
+ );
+ console.log(`Event-based hold was released for ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing release event-based hold:',
+ error.message || error
+ );
+ }
+ }
+
+ releaseEventBasedHold();
+ // [END storage_release_event_based_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/releaseTemporaryHold.js b/storage/releaseTemporaryHold.js
new file mode 100644
index 0000000000..585d295d9f
--- /dev/null
+++ b/storage/releaseTemporaryHold.js
@@ -0,0 +1,73 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ metagenerationMatchPrecondition = 0
+) {
+ // [START storage_release_temporary_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function releaseTemporaryHold() {
+ try {
+ // Optional: set a meta-generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to set metadata is aborted if the
+ // object's metageneration number does not match your precondition.
+ const options = {
+ ifMetagenerationMatch: metagenerationMatchPrecondition,
+ };
+
+ await storage.bucket(bucketName).file(fileName).setMetadata(
+ {
+ temporaryHold: false,
+ },
+ options
+ );
+ console.log(`Temporary hold was released for ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing release temporary hold:',
+ error.message || error
+ );
+ }
+ }
+
+ releaseTemporaryHold();
+ // [END storage_release_temporary_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketConditionalBinding.js b/storage/removeBucketConditionalBinding.js
new file mode 100644
index 0000000000..12a8adf105
--- /dev/null
+++ b/storage/removeBucketConditionalBinding.js
@@ -0,0 +1,103 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ roleName = 'roles/storage.objectViewer',
+ title = 'match-prefix',
+ description = 'Applies to objects matching a prefix',
+ expression = 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")'
+) {
+ // [START storage_remove_bucket_conditional_iam_binding]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The role to grant
+ // const roleName = 'roles/storage.objectViewer';
+
+ // The members to grant the new role to
+ // const members = [
+ // 'user:jdoe@example.com',
+ // 'group:admins@example.com',
+ // ];
+
+ // Create a condition
+ // const title = 'Title';
+ // const description = 'Description';
+ // const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketConditionalBinding() {
+ try {
+ // Get a reference to a Google Cloud Storage bucket
+ const bucket = storage.bucket(bucketName);
+
+ // Gets and updates the bucket's IAM policy
+ const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
+
+ // Set the policy's version to 3 to use condition in bindings.
+ policy.version = 3;
+
+ // Finds and removes the appropriate role-member group with specific condition.
+ const index = policy.bindings.findIndex(
+ binding =>
+ binding.role === roleName &&
+ binding.condition &&
+ binding.condition.title === title &&
+ binding.condition.description === description &&
+ binding.condition.expression === expression
+ );
+
+ const binding = policy.bindings[index];
+ if (binding) {
+ policy.bindings.splice(index, 1);
+
+ // Updates the bucket's IAM policy
+ await bucket.iam.setPolicy(policy);
+
+ console.log('Conditional Binding was removed.');
+ } else {
+ // No matching role-member group with specific condition were found
+ throw new Error('No matching binding group found.');
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket conditional binding:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketConditionalBinding();
+ // [END storage_remove_bucket_conditional_iam_binding]
+}
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketCors.js b/storage/removeBucketCors.js
new file mode 100644
index 0000000000..26b30268a0
--- /dev/null
+++ b/storage/removeBucketCors.js
@@ -0,0 +1,57 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Remove Bucket Cors Configuration.
+// description: Removes bucket cors configuration.
+// usage: node removeBucketCors.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_remove_cors_configuration]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketCors() {
+ try {
+ await storage.bucket(bucketName).setCorsConfiguration([]);
+
+ console.log(`Removed CORS configuration from bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket cors:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketCors();
+ // [END storage_remove_cors_configuration]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketDefaultOwner.js b/storage/removeBucketDefaultOwner.js
new file mode 100644
index 0000000000..51087943ff
--- /dev/null
+++ b/storage/removeBucketDefaultOwner.js
@@ -0,0 +1,62 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', userEmail = 'jdobry@google.com') {
+ // [START storage_remove_bucket_default_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The email address of the user to remove
+ // const userEmail = 'user-email-to-remove';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketDefaultOwner() {
+ try {
+ // Removes the user from the access control list of the bucket. You can use
+ // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and
+ // deleteAllAuthenticatedUsers() to remove access for different types of entities.
+ await storage.bucket(bucketName).acl.default.owners.deleteUser(userEmail);
+
+ console.log(`Removed user ${userEmail} from bucket ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket default owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketDefaultOwner();
+ // [END storage_remove_bucket_default_owner]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketIamMember.js b/storage/removeBucketIamMember.js
new file mode 100644
index 0000000000..d3a5a886e9
--- /dev/null
+++ b/storage/removeBucketIamMember.js
@@ -0,0 +1,96 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ roleName = 'roles/storage.objectViewer',
+ members = 'user:test@example.com'
+) {
+ members = members.split(',');
+ // [START storage_remove_bucket_iam_member]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The role to revoke
+ // const roleName = 'roles/storage.objectViewer';
+
+ // The members to revoke the roles from
+ // const members = [
+ // 'user:jdoe@example.com',
+ // 'group:admins@example.com',
+ // ];
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketIamMember() {
+ try {
+ // Get a reference to a Google Cloud Storage bucket
+ const bucket = storage.bucket(bucketName);
+
+ // For more information please read:
+ // https://cloud.google.com/storage/docs/access-control/iam
+ const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
+
+ // Finds and updates the appropriate role-member group, without a condition.
+ const index = policy.bindings.findIndex(
+ binding => binding.role === roleName && !binding.condition
+ );
+
+ const role = policy.bindings[index];
+ if (role) {
+ role.members = role.members.filter(
+ member => members.indexOf(member) === -1
+ );
+
+ // Updates the policy object with the new (or empty) role-member group
+ if (role.members.length === 0) {
+ policy.bindings.splice(index, 1);
+ } else {
+ policy.bindings.index = role;
+ }
+
+ // Updates the bucket's IAM policy
+ await bucket.iam.setPolicy(policy);
+ } else {
+ // No matching role-member group(s) were found
+ throw new Error('No matching role-member group(s) found.');
+ }
+
+ console.log(
+ `Removed the following member(s) with role ${roleName} from ${bucketName}:`
+ );
+ members.forEach(member => {
+ console.log(` ${member}`);
+ });
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket iam member:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketIamMember();
+ // [END storage_remove_bucket_iam_member]
+}
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketLabel.js b/storage/removeBucketLabel.js
new file mode 100644
index 0000000000..0f6a547615
--- /dev/null
+++ b/storage/removeBucketLabel.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Storage Remove Bucket Label.
+// description: Removes bucket label.
+// usage: node removeBucketLabel.js labelone)
+
+function main(bucketName = 'my-bucket', labelKey = 'labelone') {
+ // [START storage_remove_bucket_label]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The key of the label to remove from the bucket
+ // const labelKey = 'label-key-to-remove';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketLabel() {
+ try {
+ const labels = {};
+ // To remove a label set the value of the key to null.
+ labels[labelKey] = null;
+ await storage.bucket(bucketName).setMetadata({labels});
+ console.log(`Removed labels from bucket ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket label:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketLabel();
+ // [END storage_remove_bucket_label]
+}
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/removeBucketOwnerAcl.js b/storage/removeBucketOwnerAcl.js
new file mode 100644
index 0000000000..2ee60765a8
--- /dev/null
+++ b/storage/removeBucketOwnerAcl.js
@@ -0,0 +1,63 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(bucketName = 'my-bucket', userEmail = 'jdobry@google.com') {
+ // [START storage_remove_bucket_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The email address of the user to remove
+ // const userEmail = 'user-email-to-remove';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeBucketOwner() {
+ try {
+ // Removes the user from the access control list of the bucket. You can use
+ // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and
+ // deleteAllAuthenticatedUsers() to remove access for different types of entities.
+ await storage.bucket(bucketName).acl.owners.deleteUser(userEmail);
+
+ console.log(`Removed user ${userEmail} from bucket ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ removeBucketOwner();
+
+ // [END storage_remove_bucket_owner]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/removeDefaultKMSKey.js b/storage/removeDefaultKMSKey.js
new file mode 100644
index 0000000000..203e5c7fbf
--- /dev/null
+++ b/storage/removeDefaultKMSKey.js
@@ -0,0 +1,61 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Remove Default KMS Key.
+// description: Remove Default KMS Key.
+// usage: node removeDefaultKMSKey.js
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_bucket_delete_default_kms_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeDefaultKMSKey() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ encryption: {
+ defaultKmsKeyName: null,
+ },
+ });
+
+ console.log(`Default KMS key was removed from ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove default KMS key:',
+ error.message || error
+ );
+ }
+ }
+
+ removeDefaultKMSKey();
+ // [END storage_bucket_delete_default_kms_key]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/removeFileOwnerAcl.js b/storage/removeFileOwnerAcl.js
new file mode 100644
index 0000000000..ccd2fec08a
--- /dev/null
+++ b/storage/removeFileOwnerAcl.js
@@ -0,0 +1,72 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on bucket and
+ * file Access Control Lists with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ userEmail = 'jdobry@google.com'
+) {
+ // [START storage_remove_file_owner]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The email address of the user to remove
+ // const userEmail = 'user-email-to-remove';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeFileOwner() {
+ try {
+ // Removes the user from the access control list of the file. You can use
+ // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and
+ // deleteAllAuthenticatedUsers() to remove access for different types of entities.
+ await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .acl.owners.deleteUser(userEmail);
+
+ console.log(`Removed user ${userEmail} from file ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing remove file owner ACL:',
+ error.message || error
+ );
+ }
+ }
+
+ removeFileOwner();
+ // [END storage_remove_file_owner]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/removeRetentionPolicy.js b/storage/removeRetentionPolicy.js
new file mode 100644
index 0000000000..05938e18a9
--- /dev/null
+++ b/storage/removeRetentionPolicy.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_remove_retention_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function removeRetentionPolicy() {
+ try {
+ const [metadata] = await storage.bucket(bucketName).getMetadata();
+ if (metadata.retentionPolicy && metadata.retentionPolicy.isLocked) {
+ console.log(
+ 'Unable to remove retention period as retention policy is locked.'
+ );
+ } else {
+ await storage.bucket(bucketName).removeRetentionPeriod();
+ console.log(`Removed bucket ${bucketName} retention policy.`);
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing remove bucket retention policy:',
+ error.message || error
+ );
+ }
+ }
+
+ removeRetentionPolicy();
+ // [END storage_remove_retention_policy]
+}
+main(...process.argv.slice(2));
diff --git a/storage/renameFile.js b/storage/renameFile.js
new file mode 100644
index 0000000000..fa352442af
--- /dev/null
+++ b/storage/renameFile.js
@@ -0,0 +1,68 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ srcBucketName = 'my-bucket',
+ srcFileName = 'test2.txt',
+ destFileName = 'test4.txt'
+) {
+ // [START storage_rename_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of the bucket the original file is in
+ // const srcBucketName = 'your-source-bucket';
+
+ // The ID of the GCS file to rename
+ // const srcFilename = 'your-file-name';
+
+ // The new ID of the GCS file
+ // const destFileName = 'target-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function renameFile() {
+ try {
+ // renames the file
+ await storage
+ .bucket(srcBucketName)
+ .file(srcFileName)
+ .rename(destFileName);
+
+ console.log(
+ `gs://${srcBucketName}/${srcFileName} renamed to gs://${srcBucketName}/${destFileName}.`
+ );
+ } catch (error) {
+ console.error('Error executing rename file:', error.message || error);
+ }
+ }
+
+ renameFile();
+ // [END storage_rename_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/resources/.gitignore b/storage/resources/.gitignore
new file mode 100644
index 0000000000..6738013702
--- /dev/null
+++ b/storage/resources/.gitignore
@@ -0,0 +1 @@
+downloaded.txt
diff --git a/storage/resources/resourcesSub1/testSub1.txt b/storage/resources/resourcesSub1/testSub1.txt
new file mode 100644
index 0000000000..51f4b307d5
--- /dev/null
+++ b/storage/resources/resourcesSub1/testSub1.txt
@@ -0,0 +1,2 @@
+Sub1
+Hello World!
\ No newline at end of file
diff --git a/storage/resources/test.txt b/storage/resources/test.txt
new file mode 100644
index 0000000000..c57eff55eb
--- /dev/null
+++ b/storage/resources/test.txt
@@ -0,0 +1 @@
+Hello World!
\ No newline at end of file
diff --git a/storage/resources/test2.txt b/storage/resources/test2.txt
new file mode 100644
index 0000000000..010302410b
--- /dev/null
+++ b/storage/resources/test2.txt
@@ -0,0 +1 @@
+Hello World 2!
\ No newline at end of file
diff --git a/storage/restoreSoftDeletedBucket.js b/storage/restoreSoftDeletedBucket.js
new file mode 100644
index 0000000000..c6a2bbff5f
--- /dev/null
+++ b/storage/restoreSoftDeletedBucket.js
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function main(bucketName = 'my-bucket', generation = 123456789) {
+ // [START storage_restore_soft_deleted_bucket]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The generation of the bucket to restore
+ // const generation = 123456789;
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function restoreSoftDeletedBucket() {
+ const options = {
+ generation: generation,
+ };
+
+ await storage.bucket(bucketName).restore(options);
+
+ console.log(`Soft deleted bucket ${bucketName} was restored.`);
+ }
+
+ restoreSoftDeletedBucket().catch(console.error);
+ // [END storage_restore_soft_deleted_bucket]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/restoreSoftDeletedObject.js b/storage/restoreSoftDeletedObject.js
new file mode 100644
index 0000000000..9c44e2ef1c
--- /dev/null
+++ b/storage/restoreSoftDeletedObject.js
@@ -0,0 +1,67 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ generation = 123456789
+) {
+ // [START storage_restore_object]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The generation of your GCS file to restore
+ // const generation = 123456789;
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function restoreSoftDeletedObject() {
+ try {
+ const options = {
+ generation: generation,
+ };
+
+ const restoredFile = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .restore(options);
+
+ console.log(`Soft deleted object ${restoredFile.name} was restored`);
+ } catch (error) {
+ console.error(
+ 'Error executing restore soft deleted object:',
+ error.message || error
+ );
+ }
+ }
+
+ restoreSoftDeletedObject();
+ // [END storage_restore_object]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/rotateEncryptionKey.js b/storage/rotateEncryptionKey.js
new file mode 100644
index 0000000000..7de0e8e292
--- /dev/null
+++ b/storage/rotateEncryptionKey.js
@@ -0,0 +1,91 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on encrypted
+ * files with the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ oldKey = process.env.GOOGLE_CLOUD_KMS_KEY_US,
+ newKey = process.env.GOOGLE_CLOUD_KMS_KEY_ASIA,
+ generationMatchPrecondition = 0
+) {
+ // [START storage_rotate_encryption_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The Base64 encoded AES-256 encryption key originally used to encrypt the
+ // object. See the documentation on Customer-Supplied Encryption keys for
+ // more info:
+ // https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys
+ // The Base64 encoded AES-256 encryption key originally used to encrypt the
+ // const oldKey = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
+
+ // The new encryption key to use
+ // const newKey = '0mMWhFvQOdS4AmxRpo8SJxXn5MjFhbz7DkKBUdUIef8=';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function rotateEncryptionKey() {
+ try {
+ const rotateEncryptionKeyOptions = {
+ encryptionKey: Buffer.from(newKey, 'base64'),
+
+ // Optional: set a generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to copy is aborted if the
+ // object's generation number does not match your precondition.
+ preconditionOpts: {
+ ifGenerationMatch: generationMatchPrecondition,
+ },
+ };
+ await storage
+ .bucket(bucketName)
+ .file(fileName, {
+ encryptionKey: Buffer.from(oldKey, 'base64'),
+ })
+ .rotateEncryptionKey({
+ rotateEncryptionKeyOptions,
+ });
+
+ console.log('Encryption key rotated successfully');
+ } catch (error) {
+ console.error(
+ 'Error executing rotate encryption key:',
+ error.message || error
+ );
+ }
+ }
+
+ rotateEncryptionKey();
+ // [END storage_rotate_encryption_key]
+}
+main(...process.argv.slice(2));
diff --git a/storage/scripts/cleanup b/storage/scripts/cleanup
new file mode 100644
index 0000000000..61bd73114f
--- /dev/null
+++ b/storage/scripts/cleanup
@@ -0,0 +1,44 @@
+#!/usr/bin/env node
+
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const storage = new Storage();
+const NAME_REG_EXP = /^nodejs-storage-samples-[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/;
+
+storage
+ .getBuckets()
+ .then(([buckets]) => {
+ let promise = Promise.resolve();
+
+ buckets
+ .filter((bucket) => NAME_REG_EXP.test(bucket.name))
+ .forEach((bucket) => {
+ promise = promise.then(() => {
+ return bucket.deleteFiles()
+ .then(() => bucket.deleteFiles(), console.error)
+ .then(() => {
+ console.log(`Deleting ${bucket.name}`);
+ return bucket.delete();
+ }, console.error)
+ .catch(console.error);
+ });
+ });
+ })
+ .catch((err) => {
+ console.error('ERROR:', err);
+ });
diff --git a/storage/setAutoclass.js b/storage/setAutoclass.js
new file mode 100644
index 0000000000..e6c8f16027
--- /dev/null
+++ b/storage/setAutoclass.js
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ toggle = true,
+ terminalStorageClass = 'ARCHIVE'
+) {
+ // [START storage_set_autoclass]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The terminal storage class to be set on your GCS bucket. Valid values are NEARLINE and ARCHIVE.
+ // const terminalStorageClass = 'NEARLINE';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function setAutoclass() {
+ // Configure the Autoclass setting for a bucket.
+ // terminalStorageClass field is optional and defaults to NEARLINE if not otherwise specified.
+ // Valid terminalStorageClass values are NEARLINE and ARCHIVE.
+ try {
+ const [metadata] = await storage.bucket(bucketName).setMetadata({
+ autoclass: {
+ enabled: toggle,
+ terminalStorageClass,
+ },
+ });
+
+ console.log(
+ `Autoclass terminal storage class is ${metadata.autoclass.terminalStorageClass}.`
+ );
+ } catch (error) {
+ console.error('Error executing set autoclass:', error.message || error);
+ }
+ }
+
+ setAutoclass();
+ // [END storage_set_autoclass]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/setClientEndpoint.js b/storage/setClientEndpoint.js
new file mode 100644
index 0000000000..6d5ed079bf
--- /dev/null
+++ b/storage/setClientEndpoint.js
@@ -0,0 +1,53 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates set a custom endpoint with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(apiEndpoint = 'https://storage.googleapis.com') {
+ // [START storage_set_client_endpoint]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The custom endpoint to which requests should be made
+ // const apiEndpoint = 'https://yourcustomendpoint.com';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+ try {
+ // Creates a client
+ const storage = new Storage({
+ apiEndpoint: apiEndpoint,
+ useAuthWithCustomEndpoint: true,
+ });
+
+ console.log(`Client initiated with endpoint: ${storage.apiEndpoint}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing set client endpoint:',
+ error.message || error
+ );
+ }
+
+ // [END storage_set_client_endpoint]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/setEventBasedHold.js b/storage/setEventBasedHold.js
new file mode 100644
index 0000000000..50c73a424b
--- /dev/null
+++ b/storage/setEventBasedHold.js
@@ -0,0 +1,74 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ metagenerationMatchPrecondition = 0
+) {
+ // [START storage_set_event_based_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function setEventBasedHold() {
+ try {
+ // Optional: set a meta-generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to set metadata is aborted if the
+ // object's metageneration number does not match your precondition.
+ const options = {
+ ifMetagenerationMatch: metagenerationMatchPrecondition,
+ };
+
+ // Set event-based hold
+ await storage.bucket(bucketName).file(fileName).setMetadata(
+ {
+ eventBasedHold: true,
+ },
+ options
+ );
+ console.log(`Event-based hold was set for ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing set event-based hold:',
+ error.message || error
+ );
+ }
+ }
+
+ setEventBasedHold();
+ // [END storage_set_event_based_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/setObjectRetentionPolicy.js b/storage/setObjectRetentionPolicy.js
new file mode 100644
index 0000000000..c7067b7673
--- /dev/null
+++ b/storage/setObjectRetentionPolicy.js
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+// sample-metadata:
+// title: Set the object retention policy of a File.
+// description: Set the object retention policy of a File.
+// usage: node setObjectRetentionPolicy.js
+
+function main(
+ bucketName = 'my-bucket',
+ destFileName = 'file.txt',
+ contents = 'this is the file content'
+) {
+ // [START storage_set_object_retention_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // The content to be uploaded in the GCS file
+ // const contents = 'your file content';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ // The bucket in the sample below will be created in the project associated with this client.
+ // For more information, please see https://cloud.google.com/docs/authentication/production or https://googleapis.dev/nodejs/storage/latest/Storage.html
+ const storage = new Storage();
+
+ async function setObjectRetentionPolicy() {
+ try {
+ // Get a reference to the bucket
+ const myBucket = storage.bucket(bucketName);
+
+ // Create a reference to a file object
+ const file = myBucket.file(destFileName);
+
+ // Save the file data
+ await file.save(contents);
+
+ // Set the retention policy for the file
+ const retentionDate = new Date();
+ retentionDate.setDate(retentionDate.getDate() + 10);
+ const [metadata] = await file.setMetadata({
+ retention: {
+ mode: 'Unlocked',
+ retainUntilTime: retentionDate.toISOString(),
+ },
+ });
+
+ console.log(
+ `Retention policy for file ${file.name} was set to: ${metadata.retention.mode}`
+ );
+
+ // To modify an existing policy on an unlocked file object, pass in the override parameter
+ const newRetentionDate = new Date(retentionDate.getDate());
+ newRetentionDate.setDate(newRetentionDate.getDate() + 9);
+ const [newMetadata] = await file.setMetadata({
+ retention: {
+ mode: 'Unlocked',
+ retainUntilTime: newRetentionDate,
+ },
+ overrideUnlockedRetention: true,
+ });
+
+ console.log(
+ `Retention policy for file ${file.name} was updated to: ${newMetadata.retention.retainUntilTime}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing set object retention policy:',
+ error.message || error
+ );
+ }
+ }
+
+ setObjectRetentionPolicy();
+ // [END storage_set_object_retention_policy]
+}
+main(...process.argv.slice(2));
diff --git a/storage/setPublicAccessPreventionEnforced.js b/storage/setPublicAccessPreventionEnforced.js
new file mode 100644
index 0000000000..71885230dd
--- /dev/null
+++ b/storage/setPublicAccessPreventionEnforced.js
@@ -0,0 +1,63 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_public_access_prevention_enforced]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Enforces public access prevention for the bucket
+ async function setPublicAccessPreventionEnforced() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ iamConfiguration: {
+ publicAccessPrevention: 'enforced',
+ },
+ });
+
+ console.log(
+ `Public access prevention is set to enforced for ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing set public access prevention enforced:',
+ error.message || error
+ );
+ }
+ }
+
+ setPublicAccessPreventionEnforced();
+ // [END storage_set_public_access_prevention_enforced]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/setPublicAccessPreventionInherited.js b/storage/setPublicAccessPreventionInherited.js
new file mode 100644
index 0000000000..c0fc042ad5
--- /dev/null
+++ b/storage/setPublicAccessPreventionInherited.js
@@ -0,0 +1,58 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_public_access_prevention_inherited]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+ async function setPublicAccessPreventionInherited() {
+ // Sets public access prevention to 'inherited' for the bucket
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ iamConfiguration: {
+ publicAccessPrevention: 'inherited',
+ },
+ });
+
+ console.log(`Public access prevention is 'inherited' for ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing set public access prevention inherited:',
+ error.message || error
+ );
+ }
+ }
+
+ setPublicAccessPreventionInherited();
+ // [END storage_set_public_access_prevention_inherited]
+}
+main(...process.argv.slice(2));
diff --git a/storage/setRPOAsyncTurbo.js b/storage/setRPOAsyncTurbo.js
new file mode 100644
index 0000000000..64fcbccfa2
--- /dev/null
+++ b/storage/setRPOAsyncTurbo.js
@@ -0,0 +1,64 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_rpo_async_turbo]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket in a dual-region
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Enable turbo replication for the bucket by setting rpo to ASYNC_TURBO.
+ // The bucket must be a dual-region bucket.
+ async function setRPOAsyncTurbo() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ rpo: 'ASYNC_TURBO',
+ });
+
+ console.log(`Turbo replication enabled for ${bucketName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing set RPO async turbo:',
+ error.message || error
+ );
+ }
+ }
+
+ setRPOAsyncTurbo();
+ // [END storage_set_rpo_async_turbo]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/setRPODefault.js b/storage/setRPODefault.js
new file mode 100644
index 0000000000..fd134b6f77
--- /dev/null
+++ b/storage/setRPODefault.js
@@ -0,0 +1,61 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * This application demonstrates how to perform basic operations on buckets with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_rpo_default]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The name of your GCS bucket in a dual-region
+ // const bucketName = 'Name of a bucket, e.g. my-bucket';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Disable turbo replication for the bucket by setting RPO to default.
+ // The bucket must be a dual-region bucket.
+ async function setRPODefault() {
+ try {
+ await storage.bucket(bucketName).setMetadata({
+ rpo: 'DEFAULT',
+ });
+
+ console.log(`Turbo replication disabled for ${bucketName}.`);
+ } catch (error) {
+ console.error('Error executing set RPO default:', error.message || error);
+ }
+ }
+
+ setRPODefault();
+ // [END storage_set_rpo_default]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/setRetentionPolicy.js b/storage/setRetentionPolicy.js
new file mode 100644
index 0000000000..cb175a8f25
--- /dev/null
+++ b/storage/setRetentionPolicy.js
@@ -0,0 +1,61 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(bucketName = 'my-bucket', retentionPeriod = 5) {
+ // [START storage_set_retention_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The retention period for objects in bucket
+ // const retentionPeriod = 3600; // 1 hour in seconds
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function setRetentionPolicy() {
+ try {
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .setRetentionPeriod(retentionPeriod);
+ console.log(
+ `Bucket ${bucketName} retention period set for ${metadata.retentionPolicy.retentionPeriod} seconds.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing set bucket retention policy:',
+ error.message || error
+ );
+ }
+ }
+
+ setRetentionPolicy();
+ // [END storage_set_retention_policy]
+}
+main(...process.argv.slice(2));
diff --git a/storage/setSoftDeletePolicy.js b/storage/setSoftDeletePolicy.js
new file mode 100644
index 0000000000..30f7da9d06
--- /dev/null
+++ b/storage/setSoftDeletePolicy.js
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2025 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_set_soft_delete_policy]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function setSoftDeletePolicy() {
+ try {
+ const options = {
+ softDeletePolicy: {
+ retentionDurationSeconds: 604800, // 7 days (in seconds)
+ },
+ };
+
+ const [metadata] = await storage.bucket(bucketName).setMetadata(options);
+
+ console.log(`Bucket ${metadata.name} soft delete policy set to 7 days`);
+ } catch (error) {
+ console.error(
+ 'Error executing set soft delete policy:',
+ error.message || error
+ );
+ }
+ }
+
+ setSoftDeletePolicy();
+ // [END storage_set_soft_delete_policy]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/setTemporaryHold.js b/storage/setTemporaryHold.js
new file mode 100644
index 0000000000..573cad7c28
--- /dev/null
+++ b/storage/setTemporaryHold.js
@@ -0,0 +1,73 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to use Bucket Lock operations on buckets
+ * and objects using the Google Cloud Storage API.
+ *
+ * For more information read the documentation
+ * at https://cloud.google.com/storage/docs/bucket-lock
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ metagenerationMatchPrecondition = 0
+) {
+ // [START storage_set_temporary_hold]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function setTemporaryHold() {
+ try {
+ // Optional: set a meta-generation-match precondition to avoid potential race
+ // conditions and data corruptions. The request to set metadata is aborted if the
+ // object's metageneration number does not match your precondition.
+ const options = {
+ ifMetagenerationMatch: metagenerationMatchPrecondition,
+ };
+
+ await storage.bucket(bucketName).file(fileName).setMetadata(
+ {
+ temporaryHold: true,
+ },
+ options
+ );
+ console.log(`Temporary hold was set for ${fileName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing set temporary hold:',
+ error.message || error
+ );
+ }
+ }
+
+ setTemporaryHold();
+ // [END storage_set_temporary_hold]
+}
+main(...process.argv.slice(2));
diff --git a/storage/streamFileDownload.js b/storage/streamFileDownload.js
new file mode 100644
index 0000000000..32dbf0fd74
--- /dev/null
+++ b/storage/streamFileDownload.js
@@ -0,0 +1,80 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+const path = require('path');
+const cwd = path.join(__dirname, '..');
+const fs = require('fs');
+
+function main(
+ bucketName = 'my-bucket',
+ fileName = 'test.txt',
+ destFileName = path.join(cwd, 'downloaded.txt')
+) {
+ // [START storage_stream_file_download]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of your GCS file
+ // const fileName = 'your-file-name';
+
+ // The filename and file path where you want to download the file
+ // const destFileName = '/local/path/to/file.txt';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function streamFileDownload() {
+ try {
+ // The example below demonstrates how we can reference a remote file, then
+ // pipe its contents to a local file.
+ // Once the stream is created, the data can be piped anywhere (process, sdout, etc)
+ await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .createReadStream() //stream is created
+ .pipe(fs.createWriteStream(destFileName))
+ .on('finish', () => {
+ // The file download is complete
+ });
+
+ console.log(
+ `gs://${bucketName}/${fileName} downloaded to ${destFileName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing stream file download:',
+ error.message || error
+ );
+ }
+ }
+
+ streamFileDownload();
+ // [END storage_stream_file_download]
+}
+main(...process.argv.slice(2));
diff --git a/storage/streamFileUpload.js b/storage/streamFileUpload.js
new file mode 100644
index 0000000000..a74297ca3a
--- /dev/null
+++ b/storage/streamFileUpload.js
@@ -0,0 +1,82 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ destFileName = 'file.txt',
+ contents = 'this is the file content'
+) {
+ // [START storage_stream_file_upload]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // The content to be uploaded in the GCS file
+ // const contents = 'your file content';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Import Node.js stream
+ const stream = require('stream');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Get a reference to the bucket
+ const myBucket = storage.bucket(bucketName);
+
+ // Create a reference to a file object
+ const file = myBucket.file(destFileName);
+
+ // Create a pass through stream from a string
+ const passthroughStream = new stream.PassThrough();
+ passthroughStream.write(contents);
+ passthroughStream.end();
+
+ async function streamFileUpload() {
+ try {
+ passthroughStream.pipe(file.createWriteStream()).on('finish', () => {
+ // The file upload is complete
+ });
+
+ console.log(`${destFileName} uploaded to ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing stream file upload:',
+ error.message || error
+ );
+ }
+ }
+
+ streamFileUpload().catch(console.error);
+ // [END storage_stream_file_upload]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/system-test/acl.test.js b/storage/system-test/acl.test.js
new file mode 100644
index 0000000000..5074b04b76
--- /dev/null
+++ b/storage/system-test/acl.test.js
@@ -0,0 +1,144 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+const path = require('path');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+const userEmail = 'jdobry@google.com';
+const fileName = 'test.txt';
+const filePath = path.join(__dirname, '..', 'resources', fileName);
+
+before(async () => {
+ await bucket.create();
+ await bucket.upload(filePath);
+});
+
+after(async () => {
+ try {
+ await bucket.deleteFiles({force: true});
+ } catch (err) {
+ // ignore error
+ }
+ try {
+ await bucket.deleteFiles({force: true});
+ } catch (err) {
+ // ignore error
+ }
+ try {
+ await bucket.delete();
+ } catch (err) {
+ // ignore error
+ }
+});
+
+it('should print acl for a bucket', () => {
+ const out = execSync(`node printBucketAcl.js ${bucketName}`);
+ assert.match(out, /OWNER: project-editors-/);
+ assert.match(out, /OWNER: project-owners-/);
+ assert.match(out, /READER: project-viewers-/);
+});
+
+it('should print acl for a file', () => {
+ const out = execSync(`node printFileAcl.js ${bucketName} ${fileName}`);
+ assert.match(out, /OWNER: project-editors-/);
+ assert.match(out, /OWNER: project-owners-/);
+ assert.match(out, /READER: project-viewers-/);
+});
+
+it('should print a users acl for a bucket', async () => {
+ await bucket.acl.readers.addUser(userEmail);
+ const out = execSync(
+ `node printBucketAclForUser.js ${bucketName} ${userEmail}`
+ );
+ assert.match(out, new RegExp(`READER: user-${userEmail}`));
+ await bucket.acl.readers.deleteUser(userEmail);
+});
+
+it('should add a user as an owner on a bucket', () => {
+ const out = execSync(`node addBucketOwnerAcl.js ${bucketName} ${userEmail}`);
+ assert.match(
+ out,
+ new RegExp(`Added user ${userEmail} as an owner on bucket ${bucketName}.`)
+ );
+});
+
+it('should remove a user from a bucket', () => {
+ const out = execSync(
+ `node removeBucketOwnerAcl.js ${bucketName} ${userEmail}`
+ );
+ assert.match(
+ out,
+ new RegExp(`Removed user ${userEmail} from bucket ${bucketName}.`)
+ );
+});
+
+it('should add a user as a default owner on a bucket', () => {
+ const out = execSync(
+ `node addBucketDefaultOwnerAcl.js ${bucketName} ${userEmail}`
+ );
+ assert.match(
+ out,
+ new RegExp(`Added user ${userEmail} as an owner on bucket ${bucketName}.`)
+ );
+});
+
+it('should remove a default user from a bucket', () => {
+ const out = execSync(
+ `node removeBucketDefaultOwner.js ${bucketName} ${userEmail}`
+ );
+ assert.match(
+ out,
+ new RegExp(`Removed user ${userEmail} from bucket ${bucketName}.`)
+ );
+});
+
+it('should print a users acl for a file', async () => {
+ await bucket.file(fileName).acl.readers.addUser(userEmail);
+ const out = execSync(
+ `node printFileAclForUser.js ${bucketName} ${fileName} ${userEmail}`
+ );
+ assert.match(out, new RegExp(`READER: user-${userEmail}`));
+ await bucket.file(fileName).acl.readers.deleteUser(userEmail);
+});
+
+it('should add a user as an owner on a bucket', () => {
+ const out = execSync(
+ `node addFileOwnerAcl.js ${bucketName} ${fileName} ${userEmail}`
+ );
+ assert.match(
+ out,
+ new RegExp(`Added user ${userEmail} as an owner on file ${fileName}.`)
+ );
+});
+
+it('should remove a user from a bucket', () => {
+ const out = execSync(
+ `node removeFileOwnerAcl.js ${bucketName} ${fileName} ${userEmail}`
+ );
+ assert.match(
+ out,
+ new RegExp(`Removed user ${userEmail} from file ${fileName}.`)
+ );
+});
diff --git a/storage/system-test/bucketLifecycle.test.js b/storage/system-test/bucketLifecycle.test.js
new file mode 100644
index 0000000000..8b1adf9b55
--- /dev/null
+++ b/storage/system-test/bucketLifecycle.test.js
@@ -0,0 +1,80 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, beforeEach, after, describe, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+
+describe('Bucket lifecycle management', () => {
+ before(async () => {
+ await bucket.create();
+ });
+
+ beforeEach(async () => {
+ await bucket.setMetadata({lifecycle: null});
+ });
+
+ after(async () => {
+ await bucket.delete().catch(console.error);
+ });
+
+ it('should add a lifecycle delete rule', async () => {
+ const output = execSync(
+ `node enableBucketLifecycleManagement.js ${bucketName}`
+ );
+ assert.include(
+ output,
+ `Lifecycle management is enabled for bucket ${bucketName} and the rules are:`
+ );
+ const [metadata] = await bucket.getMetadata();
+ assert.deepStrictEqual(metadata.lifecycle.rule[0], {
+ action: {type: 'Delete'},
+ condition: {age: 100},
+ });
+ });
+
+ it('should disable all lifecycle rules', async () => {
+ // Add a lifecycle rule in order for the sample to delete.
+ await bucket.addLifecycleRule({
+ action: {type: 'Delete'},
+ condition: {age: 100},
+ });
+
+ const [metadata] = await bucket.getMetadata();
+ assert.deepStrictEqual(metadata.lifecycle.rule[0], {
+ action: {type: 'Delete'},
+ condition: {age: 100},
+ });
+
+ const output = execSync(
+ `node disableBucketLifecycleManagement.js ${bucketName}`
+ );
+ assert.include(
+ output,
+ `Lifecycle management is disabled for bucket ${bucketName}`
+ );
+ const [newMetadata] = await bucket.getMetadata();
+ assert.isUndefined(newMetadata.lifecycle);
+ });
+});
diff --git a/storage/system-test/bucketLock.test.js b/storage/system-test/bucketLock.test.js
new file mode 100644
index 0000000000..7f4693adeb
--- /dev/null
+++ b/storage/system-test/bucketLock.test.js
@@ -0,0 +1,145 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const path = require('path');
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const cwd = path.join(__dirname, '..');
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+const fileName = 'test.txt';
+
+const uploadFilePath = path.join(cwd, 'resources', fileName);
+
+before(async () => {
+ await bucket.create();
+ await bucket.upload(uploadFilePath);
+});
+
+after(async () => {
+ try {
+ await bucket.deleteFiles({force: true});
+ } catch (err) {
+ // ignore error
+ }
+ try {
+ await bucket.delete();
+ } catch (err) {
+ // ignore error
+ }
+});
+
+it('should set a retention policy on a bucket', () => {
+ const retentionPeriod = 5;
+ const output = execSync(
+ `node setRetentionPolicy.js ${bucketName} ${retentionPeriod}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `Bucket ${bucketName} retention period set for ${retentionPeriod} seconds`
+ )
+ );
+});
+
+it('should get a retention policy on a bucket', () => {
+ const output = execSync(`node getRetentionPolicy.js ${bucketName}`);
+ assert.match(output, /A retention policy exists!/);
+});
+
+it('should enable default event-based hold on a bucket', () => {
+ const output = execSync(`node enableDefaultEventBasedHold.js ${bucketName}`);
+ assert.match(
+ output,
+ new RegExp(`Default event-based hold was enabled for ${bucketName}.`)
+ );
+});
+
+it('should get default event-based hold on a bucket', () => {
+ const output = execSync(`node getDefaultEventBasedHold.js ${bucketName}`);
+ assert.match(output, /Default event-based hold: true./);
+});
+
+it('should disable default event-based hold on a bucket', () => {
+ const output = execSync(`node disableDefaultEventBasedHold.js ${bucketName}`);
+ assert.match(
+ output,
+ new RegExp(`Default event-based hold was disabled for ${bucketName}`)
+ );
+});
+
+it('should set an event-based hold on a file', async () => {
+ const [metadata] = await bucket.file(fileName).getMetadata();
+ const output = execSync(
+ `node setEventBasedHold.js ${bucketName} ${fileName} ${metadata.metageneration}`
+ );
+ assert.match(output, new RegExp(`Event-based hold was set for ${fileName}`));
+});
+
+it('should release an event-based hold on a file', async () => {
+ const [metadata] = await bucket.file(fileName).getMetadata();
+ const output = execSync(
+ `node releaseEventBasedHold.js ${bucketName} ${fileName} ${metadata.metageneration}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Event-based hold was released for ${fileName}.`)
+ );
+});
+
+it('should remove a retention policy on a bucket', () => {
+ const output = execSync(`node removeRetentionPolicy.js ${bucketName}`);
+ assert.match(
+ output,
+ new RegExp(`Removed bucket ${bucketName} retention policy.`)
+ );
+});
+
+it('should set an temporary hold on a file', async () => {
+ const [metadata] = await bucket.file(fileName).getMetadata();
+ const output = execSync(
+ `node setTemporaryHold.js ${bucketName} ${fileName} ${metadata.metageneration}`
+ );
+ assert.match(output, new RegExp(`Temporary hold was set for ${fileName}.`));
+});
+
+it('should release an temporary hold on a file', async () => {
+ const [metadata] = await bucket.file(fileName).getMetadata();
+ const output = execSync(
+ `node releaseTemporaryHold.js ${bucketName} ${fileName} ${metadata.metageneration}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Temporary hold was released for ${fileName}.`)
+ );
+});
+
+it('should lock a bucket with a retention policy', () => {
+ const retentionPeriod = 5;
+ execSync(`node setRetentionPolicy.js ${bucketName} ${retentionPeriod}`);
+ const output = execSync(`node lockRetentionPolicy.js ${bucketName}`);
+ assert.match(
+ output,
+ new RegExp(`Retention policy for ${bucketName} is now locked`)
+ );
+});
diff --git a/storage/system-test/buckets.test.js b/storage/system-test/buckets.test.js
new file mode 100644
index 0000000000..4e2a03ebe9
--- /dev/null
+++ b/storage/system-test/buckets.test.js
@@ -0,0 +1,485 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const samplesTestBucketPrefix = `nodejs-storage-samples-${uuid.v4()}`;
+const bucketName = `${samplesTestBucketPrefix}-a`;
+const bucketNameDualRegion = `${samplesTestBucketPrefix}-b`;
+const bucketNameDualRegionTurbo = `${samplesTestBucketPrefix}-c`;
+const bucketNameWithClassAndLocation = `${samplesTestBucketPrefix}-d`;
+const bucketNameAutoclass = `${samplesTestBucketPrefix}-e`;
+const bucketNameObjectRetention = `${samplesTestBucketPrefix}-f`;
+const bucketNameHierarchicalNamespace = `${samplesTestBucketPrefix}-g`;
+const defaultKmsKeyName = process.env.GOOGLE_CLOUD_KMS_KEY_ASIA;
+const bucket = storage.bucket(bucketName);
+const bucketWithClassAndLocation = storage.bucket(
+ bucketNameWithClassAndLocation
+);
+const dualRegionBucket = storage.bucket(bucketNameDualRegion);
+const dualRegionBucketTurbo = storage.bucket(bucketNameDualRegionTurbo);
+const objectRetentionBucket = storage.bucket(bucketNameObjectRetention);
+
+const PUBLIC_ACCESS_PREVENTION_INHERITED = 'inherited';
+const PUBLIC_ACCESS_PREVENTION_ENFORCED = 'enforced';
+
+const DUAL_REGION = {
+ LOCATION: 'US',
+ REGIONS: ['US-EAST1', 'US-WEST1'],
+};
+const RPO_ASYNC_TURBO = 'ASYNC_TURBO';
+const RPO_DEFAULT = 'DEFAULT';
+
+async function deleteAllBucketsAsync() {
+ const [buckets] = await storage.getBuckets({prefix: samplesTestBucketPrefix});
+
+ for (const bucket of buckets) {
+ await bucket.deleteFiles({force: true});
+ await bucket.delete({ignoreNotFound: true});
+ }
+}
+
+after(deleteAllBucketsAsync);
+afterEach(async () => {
+ await new Promise(res => setTimeout(res, 1000));
+});
+
+it('should create a bucket', async () => {
+ const output = execSync(`node createNewBucket.js ${bucketName}`);
+ assert.match(output, new RegExp(`Bucket ${bucketName} created`));
+ const [exists] = await bucket.exists();
+ assert.strictEqual(exists, true);
+});
+
+it('should list buckets', () => {
+ const output = execSync('node listBuckets.js');
+ assert.match(output, /Buckets:/);
+ assert.match(output, new RegExp(bucketName));
+});
+
+it('should get bucket metadata', async () => {
+ const output = execSync(`node bucketMetadata.js ${bucketName}`);
+ assert.include(output, bucketName);
+});
+
+it('should set autoclass terminal storage class to ARCHIVE', async () => {
+ await storage.createBucket(bucketNameAutoclass, {
+ autoclass: {
+ enabled: true,
+ terminalStorageClass: 'NEARLINE',
+ },
+ });
+ const output = execSync(
+ `node setAutoclass.js ${bucketNameAutoclass} ${true} ARCHIVE`
+ );
+ assert.include(output, 'ARCHIVE');
+});
+
+it('should disable autoclass', async () => {
+ const output = execSync(
+ `node setAutoclass.js ${bucketNameAutoclass} ${false}`
+ );
+ assert.include(output, 'Autoclass');
+});
+
+it('should get autoclass', async () => {
+ const output = execSync(`node getAutoclass.js ${bucketNameAutoclass}`);
+ assert.include(output, `Autoclass is disabled for ${bucketNameAutoclass}`);
+});
+
+it('should set a buckets default KMS key', async () => {
+ const output = execSync(
+ `node enableDefaultKMSKey.js ${bucketName} ${defaultKmsKeyName}`
+ );
+ assert.include(
+ output,
+ `Default KMS key for ${bucketName} was set to ${defaultKmsKeyName}`
+ );
+ const metadata = await bucket.getMetadata();
+ assert.strictEqual(
+ metadata[0].encryption.defaultKmsKeyName,
+ defaultKmsKeyName
+ );
+});
+
+it('should remove a buckets default KMS key', async () => {
+ const output = execSync(`node removeDefaultKMSKey.js ${bucketName}`);
+ assert.include(output, `Default KMS key was removed from ${bucketName}`);
+ const [metadata] = await bucket.getMetadata();
+ assert.ok(!metadata.encryption);
+});
+
+it("should enable a bucket's uniform bucket-level access", async () => {
+ const output = execSync(
+ `node enableUniformBucketLevelAccess.js ${bucketName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Uniform bucket-level access was enabled for ${bucketName}`)
+ );
+
+ const metadata = await bucket.getMetadata();
+ assert.strictEqual(
+ metadata[0].iamConfiguration.uniformBucketLevelAccess.enabled,
+ true
+ );
+});
+
+it("should get a bucket's uniform bucket-level access metadata", async () => {
+ const output = execSync(`node getUniformBucketLevelAccess.js ${bucketName}`);
+
+ assert.match(
+ output,
+ new RegExp(`Uniform bucket-level access is enabled for ${bucketName}`)
+ );
+
+ const [metadata] = await bucket.getMetadata();
+ assert.ok(metadata.iamConfiguration.uniformBucketLevelAccess.enabled);
+ assert.strictEqual(
+ metadata.iamConfiguration.uniformBucketLevelAccess.lockedTime !== null,
+ true
+ );
+});
+
+it("should disable a bucket's uniform bucket-level access", async () => {
+ const output = execSync(
+ `node disableUniformBucketLevelAccess.js ${bucketName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Uniform bucket-level access was disabled for ${bucketName}`)
+ );
+
+ const metadata = await bucket.getMetadata();
+ assert.strictEqual(
+ metadata[0].iamConfiguration.uniformBucketLevelAccess.enabled,
+ false
+ );
+});
+
+it('should configure a bucket cors', async () => {
+ execSync(
+ `node configureBucketCors.js ${bucketName} 3600 POST http://example.appspot.com content-type`
+ );
+ await bucket.getMetadata();
+ assert.deepStrictEqual(bucket.metadata.cors[0], {
+ origin: ['http://example.appspot.com'],
+ method: ['POST'],
+ responseHeader: ['content-type'],
+ maxAgeSeconds: 3600,
+ });
+});
+
+it('should remove a bucket cors configuration', async () => {
+ const output = execSync(`node removeBucketCors.js ${bucketName}`);
+ assert.include(
+ output,
+ `Removed CORS configuration from bucket ${bucketName}`
+ );
+ await bucket.getMetadata();
+ assert.ok(!bucket.metadata.cors);
+});
+
+it('should set public access prevention to enforced', async () => {
+ const output = execSync(
+ `node setPublicAccessPreventionEnforced.js ${bucketName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Public access prevention is set to enforced for ${bucketName}.`)
+ );
+
+ const metadata = await bucket.getMetadata();
+ assert.strictEqual(
+ metadata[0].iamConfiguration.publicAccessPrevention,
+ PUBLIC_ACCESS_PREVENTION_ENFORCED
+ );
+});
+
+it("should get a bucket's public access prevention metadata", async () => {
+ await storage.bucket(bucketName).setMetadata({
+ iamConfiguration: {
+ publicAccessPrevention: PUBLIC_ACCESS_PREVENTION_ENFORCED,
+ },
+ });
+
+ const output = execSync(`node getPublicAccessPrevention.js ${bucketName}`);
+
+ assert.match(
+ output,
+ new RegExp(`Public access prevention is enforced for ${bucketName}.`)
+ );
+
+ const [metadata] = await bucket.getMetadata();
+ assert.ok(metadata.iamConfiguration.publicAccessPrevention);
+});
+
+it('should set public access prevention to inherited', async () => {
+ const output = execSync(
+ `node setPublicAccessPreventionInherited.js ${bucketName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Public access prevention is 'inherited' for ${bucketName}.`)
+ );
+
+ const metadata = await bucket.getMetadata();
+ assert.strictEqual(
+ metadata[0].iamConfiguration.publicAccessPrevention,
+ PUBLIC_ACCESS_PREVENTION_INHERITED
+ );
+});
+
+it('should create a dual-region bucket', async () => {
+ const output = execSync(
+ `node createBucketWithDualRegion.js ${bucketNameDualRegion} ${DUAL_REGION.LOCATION} ${DUAL_REGION.REGIONS[0]} ${DUAL_REGION.REGIONS[1]}`
+ );
+
+ // Ensure the sample outputs the desired result
+ assert.include(output, bucketNameDualRegion);
+ assert.include(output, DUAL_REGION.LOCATION);
+ assert.include(output, DUAL_REGION.REGIONS[0]);
+ assert.include(output, DUAL_REGION.REGIONS[1]);
+ assert.include(output, 'dual-region');
+
+ // Make API request for further verification
+ const [exists] = await dualRegionBucket.exists();
+ assert.strictEqual(exists, true);
+
+ const [metadata] = await dualRegionBucket.getMetadata();
+
+ assert.strictEqual(metadata.location, DUAL_REGION.LOCATION);
+
+ assert(metadata.customPlacementConfig);
+ assert(Array.isArray(metadata.customPlacementConfig.dataLocations));
+
+ const dataLocations = metadata.customPlacementConfig.dataLocations;
+
+ assert(dataLocations.includes(DUAL_REGION.REGIONS[0]));
+ assert(dataLocations.includes(DUAL_REGION.REGIONS[1]));
+
+ assert.strictEqual(metadata.locationType, 'dual-region');
+});
+
+it('should create a dual-region bucket with turbo replication enabled', async () => {
+ const output = execSync(
+ `node createBucketWithTurboReplication.js ${bucketNameDualRegionTurbo}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `${bucketNameDualRegionTurbo} created with the recovery point objective \\(RPO\\) set to ASYNC_TURBO in NAM4.`
+ )
+ );
+ const [exists] = await dualRegionBucketTurbo.exists();
+ assert.strictEqual(exists, true);
+});
+
+it("should get a bucket's RPO metadata", async () => {
+ await storage.bucket(bucketNameDualRegionTurbo).setMetadata({
+ rpo: RPO_ASYNC_TURBO,
+ });
+
+ const output = execSync(`node getRPO.js ${bucketNameDualRegionTurbo}`);
+ assert.match(
+ output,
+ new RegExp(`RPO is ASYNC_TURBO for ${bucketNameDualRegionTurbo}.`)
+ );
+
+ const metadata = await dualRegionBucketTurbo.getMetadata();
+ assert.strictEqual(metadata[0].rpo, RPO_ASYNC_TURBO);
+});
+
+it("should set a bucket's RPO to ASYNC_TURBO", async () => {
+ const output = execSync(
+ `node setRPOAsyncTurbo.js ${bucketNameDualRegionTurbo}`
+ );
+ assert.match(
+ output,
+ new RegExp(`Turbo replication enabled for ${bucketNameDualRegionTurbo}.`)
+ );
+
+ const metadata = await dualRegionBucketTurbo.getMetadata();
+ assert.strictEqual(metadata[0].rpo, RPO_ASYNC_TURBO);
+});
+
+it("should set a bucket's RPO to DEFAULT", async () => {
+ const output = execSync(`node setRPODefault.js ${bucketNameDualRegionTurbo}`);
+ assert.match(
+ output,
+ new RegExp(`Turbo replication disabled for ${bucketNameDualRegionTurbo}.`)
+ );
+
+ const metadata = await dualRegionBucketTurbo.getMetadata();
+ assert.strictEqual(metadata[0].rpo, RPO_DEFAULT);
+});
+
+it('should create a hierarchical namespace enabled bucket', async () => {
+ const output = execSync(
+ `node createBucketWithHierarchicalNamespace.js ${bucketNameHierarchicalNamespace}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `Created '${bucketNameHierarchicalNamespace}' with hierarchical namespace enabled.`
+ )
+ );
+
+ const metadata = await dualRegionBucketTurbo.getMetadata();
+ assert.strictEqual(metadata[0].rpo, RPO_DEFAULT);
+});
+
+it("should add a bucket's website configuration", async () => {
+ const output = execSync(
+ `node addBucketWebsiteConfiguration.js ${bucketName} http://example.com http://example.com/404.html`
+ );
+
+ assert.include(
+ output,
+ `Static website bucket ${bucketName} is set up to use http://example.com as the index page and http://example.com/404.html as the 404 page`
+ );
+
+ const [metadata] = await bucket.getMetadata();
+ assert.deepStrictEqual(metadata.website, {
+ mainPageSuffix: 'http://example.com',
+ notFoundPage: 'http://example.com/404.html',
+ });
+});
+
+/**
+ * TODO: Re-enable once the test environment allows public IAM roles.
+ * Currently disabled to avoid 403 errors when adding 'allUsers' or
+ * 'allAuthenticatedUsers' permissions.
+ */
+it.skip('should make bucket publicly readable', async () => {
+ const output = execSync(`node makeBucketPublic.js ${bucketName}`);
+ assert.match(
+ output,
+ new RegExp(`Bucket ${bucketName} is now publicly readable`)
+ );
+ const [policy] = await bucket.iam.getPolicy();
+ const objectViewerBinding = policy.bindings.filter(binding => {
+ return binding.role === 'roles/storage.legacyBucketReader';
+ })[0];
+
+ assert(objectViewerBinding.members.includes('allUsers'));
+});
+
+it("should enable a bucket's versioning", async () => {
+ const output = execSync(`node enableBucketVersioning.js ${bucketName}`);
+ assert.include(output, `Versioning is enabled for bucket ${bucketName}`);
+ await bucket.getMetadata();
+ assert.strictEqual(bucket.metadata.versioning.enabled, true);
+});
+
+it("should disable a bucket's versioning", async () => {
+ const output = execSync(`node disableBucketVersioning.js ${bucketName}`);
+ assert.include(output, `Versioning is disabled for bucket ${bucketName}`);
+ await bucket.getMetadata();
+ assert.strictEqual(bucket.metadata.versioning.enabled, false);
+});
+
+it('should add label to bucket', async () => {
+ const output = execSync(
+ `node addBucketLabel.js ${bucketName} labelone labelonevalue`
+ );
+ assert.include(output, `Added label to bucket ${bucketName}`);
+ const [labels] = await storage.bucket(bucketName).getLabels();
+ assert.isTrue('labelone' in labels);
+});
+
+it('should remove label to bucket', async () => {
+ const output = execSync(`node removeBucketLabel.js ${bucketName} labelone`);
+ assert.include(output, `Removed labels from bucket ${bucketName}`);
+ const [labels] = await storage.bucket(bucketName).getLabels();
+ assert.isFalse('labelone' in labels);
+});
+
+it("should change a bucket's default storage class", async () => {
+ const output = execSync(
+ `node changeDefaultStorageClass.js ${bucketName} coldline`
+ );
+ assert.include(output, `${bucketName} has been set to coldline`);
+ const [metadata] = await bucket.getMetadata();
+ assert.strictEqual(metadata.storageClass, 'COLDLINE');
+});
+
+it('should create bucket with storage class and location', async () => {
+ const output = execSync(
+ `node createBucketWithStorageClassAndLocation.js ${bucketNameWithClassAndLocation} coldline ASIA`
+ );
+ assert.include(
+ output,
+ `${bucketNameWithClassAndLocation} created with coldline class in ASIA`
+ );
+ const [metadata] = await bucketWithClassAndLocation.getMetadata();
+ assert.strictEqual(metadata.storageClass, 'COLDLINE');
+ assert.strictEqual(metadata.location, 'ASIA');
+});
+
+it("should set a bucket's soft delete policy", async () => {
+ const output = execSync(`node setSoftDeletePolicy.js ${bucketName}`);
+ assert.include(
+ output,
+ `Bucket ${bucketName} soft delete policy set to 7 days`
+ );
+});
+
+it("should get a bucket's soft delete policy", async () => {
+ const output = execSync(`node getSoftDeletePolicy.js ${bucketName}`);
+ assert.include(output, `Soft delete policy for ${bucketName}`);
+ assert.include(output, 'Soft delete Period: 604800 seconds');
+ assert.match(output, new RegExp('Effective Time:'));
+});
+
+it("should disable a bucket's soft delete policy", async () => {
+ const output = execSync(`node disableSoftDelete.js ${bucketName}`);
+ assert.include(
+ output,
+ `Bucket ${bucketName} soft delete policy was disabled`
+ );
+ await bucket.getMetadata();
+ assert.strictEqual(
+ bucket.metadata.softDeletePolicy.retentionDurationSeconds,
+ '0'
+ );
+});
+
+it('should delete a bucket', async () => {
+ const output = execSync(`node deleteBucket.js ${bucketName}`);
+ assert.match(output, new RegExp(`Bucket ${bucketName} deleted`));
+ const [exists] = await bucket.exists();
+ assert.strictEqual(exists, false);
+});
+
+it('should create a bucket with object retention enabled', async () => {
+ const output = execSync(
+ `node createBucketWithObjectRetention.js ${bucketNameObjectRetention}`
+ );
+ assert.include(
+ output,
+ `Created '${bucketNameObjectRetention}' with object retention enabled setting: Enabled`
+ );
+ const [metadata] = await objectRetentionBucket.getMetadata();
+ assert.strictEqual(metadata.objectRetention.mode, 'Enabled');
+});
diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js
new file mode 100644
index 0000000000..e970df61e3
--- /dev/null
+++ b/storage/system-test/encryption.test.js
@@ -0,0 +1,110 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const crypto = require('crypto');
+const fs = require('fs');
+const path = require('path');
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+const {promisify} = require('util');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+const kmsKeyName = process.env.GOOGLE_CLOUD_KMS_KEY_US;
+
+const fileName = 'test.txt';
+const filePath = path.join(__dirname, '../resources', fileName);
+const downloadFilePath = path.join(__dirname, '../resources/downloaded.txt');
+const doesNotExistPrecondition = 0;
+
+const key = crypto.randomBytes(32).toString('base64');
+
+before(async () => {
+ await bucket.create(bucketName);
+});
+
+after(async () => {
+ promisify(fs.unlink)(downloadFilePath).catch(console.error);
+ // Try deleting all files twice, just to make sure
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.delete().catch(console.error);
+});
+
+it('should generate a key', () => {
+ const output = execSync('node generateEncryptionKey.js');
+ assert.match(output, /Base 64 encoded encryption key:/);
+});
+
+it('should upload a file', async () => {
+ const output = execSync(
+ `node uploadEncryptedFile.js ${bucketName} ${filePath} ${fileName} ${key} ${doesNotExistPrecondition}`
+ );
+ assert.match(
+ output,
+ new RegExp(`File ${filePath} uploaded to gs://${bucketName}/${fileName}`)
+ );
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+});
+
+it('should download a file', () => {
+ const output = execSync(
+ `node downloadEncryptedFile.js ${bucketName} ${fileName} ${downloadFilePath} ${key}`
+ );
+ assert.match(
+ output,
+ new RegExp(`File ${fileName} downloaded to ${downloadFilePath}`)
+ );
+ fs.statSync(downloadFilePath);
+});
+
+it('should rotate keys', async () => {
+ const newKey = crypto.randomBytes(32).toString('base64');
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getMetadata();
+ const output = execSync(
+ `node rotateEncryptionKey.js ${bucketName} ${fileName} ${key} ${newKey} ${metadata.generation}`
+ );
+ assert.include(output, 'Encryption key rotated successfully');
+});
+
+it('should convert CSEK to KMS key', async () => {
+ const encryptedFileName = 'encrypted-file';
+ const file = bucket.file(encryptedFileName, {
+ encryptionKey: Buffer.from(key, 'base64'),
+ });
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .file(fileName)
+ .getMetadata();
+ await file.save('secret data', {resumable: false});
+ const output = execSync(
+ `node changeFileCSEKToCMEK.js ${bucketName} ${encryptedFileName} ${key} ${kmsKeyName} ${metadata.generation}`
+ );
+ assert.include(
+ output,
+ `file ${encryptedFileName} in bucket ${bucketName} is now managed by KMS key ${kmsKeyName} instead of customer-supplied encryption key`
+ );
+});
diff --git a/storage/system-test/files.test.js b/storage/system-test/files.test.js
new file mode 100644
index 0000000000..2578f33978
--- /dev/null
+++ b/storage/system-test/files.test.js
@@ -0,0 +1,683 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const fs = require('fs');
+const path = require('path');
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it, describe} = require('mocha');
+const cp = require('child_process');
+const fetch = require('node-fetch');
+const uuid = require('uuid');
+const {promisify} = require('util');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const cwd = path.join(__dirname, '..');
+const bucketName = generateName();
+const bucket = storage.bucket(bucketName);
+const softDeleteBucketName = generateName();
+const softDeleteBucket = storage.bucket(softDeleteBucketName);
+const objectRetentionBucketName = generateName();
+const objectRetentionBucket = storage.bucket(objectRetentionBucketName);
+const fileContents = 'these-are-my-contents';
+const fileName = 'test.txt';
+const memoryFileName = 'testmemory.txt';
+const movedFileName = 'test2.txt';
+const copiedFileName = 'test3.txt';
+const renamedFileName = 'test4.txt';
+const signedFileName = 'signed-upload.txt';
+const kmsKeyName = process.env.GOOGLE_CLOUD_KMS_KEY_US;
+const filePath = path.join(cwd, 'resources', fileName);
+const folderPath = path.join(cwd, 'resources');
+const downloadFilePath = path.join(cwd, 'downloaded.txt');
+const startByte = 0;
+const endByte = 20;
+const doesNotExistPrecondition = 0;
+
+const fileContent = fs.readFileSync(filePath, 'utf-8');
+
+describe('file', () => {
+ before(async () => {
+ await bucket.create();
+ });
+
+ after(async () => {
+ await promisify(fs.unlink)(downloadFilePath).catch(console.error);
+ // Try deleting all files twice, just to make sure
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.delete().catch(console.error);
+ });
+
+ it('should upload a file', async () => {
+ const output = execSync(
+ `node uploadFile.js ${bucketName} ${filePath} ${fileName} ${doesNotExistPrecondition}`
+ );
+ assert.match(output, new RegExp(`${filePath} uploaded to ${bucketName}`));
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should upload a file from memory', async () => {
+ const output = execSync(
+ `node uploadFromMemory.js ${bucketName} ${fileContents} ${memoryFileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `${memoryFileName} with contents ${fileContents} uploaded to ${bucketName}.`
+ )
+ );
+ const [exists] = await bucket.file(memoryFileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should upload a file without authentication', async () => {
+ const output = execSync(
+ `node uploadWithoutAuthentication.js ${bucketName} ${fileContents} ${fileName} ${doesNotExistPrecondition}`
+ );
+ assert.match(output, new RegExp(`${fileName} uploaded to ${bucketName}`));
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should upload a file without authentication using signed url strategy', async () => {
+ const output = execSync(
+ `node uploadWithoutAuthenticationSignedUrl.js ${bucketName} ${fileContents} ${fileName}`
+ );
+ assert.match(output, new RegExp(`${fileName} uploaded to ${bucketName}`));
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should upload a file using a stream', async () => {
+ const output = execSync(
+ `node streamFileUpload.js ${bucketName} ${fileName} ${fileContents}`
+ );
+ assert.match(output, new RegExp(`${fileName} uploaded to ${bucketName}`));
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ const response = await bucket.file(fileName).download();
+ assert.strictEqual(response[0].toString(), fileContents);
+ });
+
+ it('should upload a file with a kms key', async () => {
+ const [metadata] = await bucket.file(fileName).getMetadata();
+ const output = execSync(
+ `node uploadFileWithKmsKey.js ${bucketName} ${filePath} ${kmsKeyName} ${metadata.generation}`
+ );
+ assert.include(
+ output,
+ `${filePath} uploaded to ${bucketName} using ${kmsKeyName}`
+ );
+ const [exists] = await bucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should upload a local directory', done => {
+ const output = execSync(
+ `node uploadDirectory.js ${bucketName} ${folderPath}`
+ );
+
+ const fileList = [];
+ getFileList(folderPath);
+
+ function getFileList(directory) {
+ const items = fs.readdirSync(directory);
+ items.forEach(item => {
+ const fullPath = path.join(directory, item);
+ const stat = fs.lstatSync(fullPath);
+ if (stat.isFile()) {
+ fileList.push(fullPath);
+ } else {
+ getFileList(fullPath);
+ }
+ });
+ }
+
+ assert.match(
+ output,
+ new RegExp(
+ `${fileList.length} files uploaded to ${bucketName} successfully.`
+ )
+ );
+
+ Promise.all(
+ fileList.map(file =>
+ bucket
+ .file(
+ path.relative(path.dirname(folderPath), file).replace(/\\/g, '/')
+ )
+ .exists()
+ )
+ ).then(resps => {
+ const ctr = resps.reduce((acc, cur) => {
+ return acc + cur[0];
+ }, 0);
+ assert.strictEqual(ctr, fileList.length);
+ done();
+ }, assert.ifError);
+ });
+
+ it('should download a file', () => {
+ const output = execSync(
+ `node downloadFile.js ${bucketName} ${fileName} ${downloadFilePath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${fileName} downloaded to ${downloadFilePath}.`
+ )
+ );
+ fs.statSync(downloadFilePath);
+ });
+
+ it('should download a file into memory', () => {
+ const output = execSync(
+ `node downloadIntoMemory.js ${bucketName} ${memoryFileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `Contents of gs://${bucketName}/${memoryFileName} are ${fileContents}.`
+ )
+ );
+ });
+
+ it('should download a file using a stream', () => {
+ const output = execSync(
+ `node streamFileDownload.js ${bucketName} ${fileName} ${downloadFilePath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${fileName} downloaded to ${downloadFilePath}.`
+ )
+ );
+ fs.statSync(downloadFilePath);
+ });
+
+ it('should download a file using a given byte range', () => {
+ const output = execSync(
+ `node downloadByteRange.js ${bucketName} ${fileName} ${startByte} ${endByte} ${downloadFilePath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${fileName} downloaded to ${downloadFilePath} from byte ${startByte} to byte ${endByte}.`
+ )
+ );
+ fs.statSync(downloadFilePath);
+ });
+
+ it('should move a file', async () => {
+ const output = execSync(
+ `node moveFile.js ${bucketName} ${fileName} ${movedFileName} ${doesNotExistPrecondition}`
+ );
+ assert.include(
+ output,
+ `gs://${bucketName}/${fileName} moved to gs://${bucketName}/${movedFileName}`
+ );
+ const [exists] = await bucket.file(movedFileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should atomically move a file', async () => {
+ const movedFileName = 'test1.txt';
+ const file = bucket.file(fileName);
+ await file.save(fileName);
+ const output = execSync(
+ `node moveFileAtomic.js ${bucketName} ${fileName} ${movedFileName} ${doesNotExistPrecondition}`
+ );
+ assert.include(
+ output,
+ `gs://${bucketName}/${fileName} moved to gs://${bucketName}/${movedFileName}`
+ );
+ const [[destExists], [sourceExists]] = await Promise.all([
+ bucket.file(movedFileName).exists(),
+ bucket.file(fileName).exists(),
+ ]);
+ assert.strictEqual(destExists, true);
+ assert.strictEqual(sourceExists, false);
+ });
+
+ it('should copy a file', async () => {
+ const output = execSync(
+ `node copyFile.js ${bucketName} ${movedFileName} ${bucketName} ${copiedFileName} ${doesNotExistPrecondition}`
+ );
+ assert.include(
+ output,
+ `gs://${bucketName}/${movedFileName} copied to gs://${bucketName}/${copiedFileName}`
+ );
+ const [exists] = await bucket.file(copiedFileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should list files', () => {
+ const output = execSync(`node listFiles.js ${bucketName}`);
+ assert.match(output, /Files:/);
+ assert.match(output, new RegExp(movedFileName));
+ assert.match(output, new RegExp(copiedFileName));
+ });
+
+ it('should list files by a prefix', () => {
+ let output = execSync(`node listFilesByPrefix.js ${bucketName} test "/"`);
+ assert.match(output, /Files:/);
+ assert.match(output, new RegExp(movedFileName));
+ assert.match(output, new RegExp(copiedFileName));
+
+ output = execSync(`node listFilesByPrefix.js ${bucketName} foo`);
+ assert.match(output, /Files:/);
+ assert.notMatch(output, new RegExp(movedFileName));
+ assert.notMatch(output, new RegExp(copiedFileName));
+ });
+
+ it('should list files with pagination', () => {
+ const output = execSync(`node listFilesPaginate.js ${bucketName}`);
+ assert.match(output, /Files:/);
+ assert.match(output, new RegExp(movedFileName));
+ assert.match(output, new RegExp(copiedFileName));
+ });
+
+ it('should rename a file', async () => {
+ const output = execSync(
+ `node renameFile.js ${bucketName} ${movedFileName} ${renamedFileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${movedFileName} renamed to gs://${bucketName}/${renamedFileName}.`
+ )
+ );
+ const [exists] = await bucket.file(renamedFileName).exists();
+ assert.strictEqual(exists, true);
+
+ const [oldFileExists] = await bucket.file(movedFileName).exists();
+ assert.strictEqual(oldFileExists, false);
+ });
+
+ describe('public data', () => {
+ let GOOGLE_APPLICATION_CREDENTIALS;
+ let GOOGLE_CLOUD_PROJECT;
+ const publicFileName = 'public.txt';
+ const downloadPublicFilePath = path.join(cwd, 'public-downloaded.txt');
+
+ before(async () => {
+ // CI authentication is done with ADC. Cache it here, restore it `after`
+ // Incase of sample fails it's restore from here.
+ await bucket.file(publicFileName).save('public data');
+ GOOGLE_APPLICATION_CREDENTIALS =
+ process.env.GOOGLE_APPLICATION_CREDENTIALS;
+ GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT;
+ });
+
+ after(async () => {
+ await promisify(fs.unlink)(downloadPublicFilePath).catch(console.error);
+ process.env.GOOGLE_APPLICATION_CREDENTIALS =
+ GOOGLE_APPLICATION_CREDENTIALS;
+ process.env.GOOGLE_CLOUD_PROJECT = GOOGLE_CLOUD_PROJECT;
+ await bucket.file(publicFileName).delete();
+ });
+
+ /**
+ * TODO: Re-enable once the test environment allows public IAM roles.
+ * Currently disabled to avoid 403 errors when adding 'allUsers' or
+ * 'allAuthenticatedUsers' permissions.
+ */
+ it.skip('should make a file public', () => {
+ const output = execSync(
+ `node makePublic.js ${bucketName} ${publicFileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`gs://${bucketName}/${publicFileName} is now public`)
+ );
+ });
+
+ it('should download public file', () => {
+ const output = execSync(
+ `node downloadPublicFile.js ${bucketName} ${publicFileName} ${downloadPublicFilePath}`
+ );
+ assert.include(
+ output,
+ `Downloaded public file ${publicFileName} from bucket name ${bucketName} to ${downloadPublicFilePath}`
+ );
+ fs.statSync(downloadPublicFilePath);
+ });
+ });
+
+ it('should generate a v2 signed URL for a file', async () => {
+ const output = await execSync(
+ `node generateSignedUrl ${bucketName} ${copiedFileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`The signed url for ${copiedFileName} is `)
+ );
+ });
+
+ it('should generate a v4 signed URL and read a file', async () => {
+ const output = await execSync(
+ `node generateV4ReadSignedUrl.js ${bucketName} ${copiedFileName}`
+ );
+
+ const expected = /URL:\n([^\s]+)/;
+ assert.match(output, expected);
+
+ const match = output.match(expected);
+ const res = await fetch(match[1]);
+ const text = await res.text();
+ assert.strictEqual(text, fileContent);
+ });
+
+ it('should generate a v4 signed URL and upload a file', async () => {
+ const output = execSync(
+ `node generateV4UploadSignedUrl.js ${bucketName} ${signedFileName}`
+ );
+
+ const expected = /URL:\n([^\s]+)/;
+ assert.match(output, expected);
+
+ const match = output.match(expected);
+ const req = {
+ method: 'PUT',
+ headers: {'Content-Type': 'application/octet-stream'},
+ body: fileContent,
+ };
+ await fetch(match[1], req);
+
+ await new Promise((resolve, reject) => {
+ let remoteContent = '';
+ bucket
+ .file(signedFileName)
+ .createReadStream()
+ .on('response', res => {
+ assert.strictEqual(
+ res.headers['content-type'],
+ 'application/octet-stream'
+ );
+ })
+ .on('data', buf => (remoteContent += buf.toString()))
+ .on('end', () => {
+ assert.strictEqual(remoteContent, fileContent);
+ resolve();
+ })
+ .on('error', reject);
+ });
+ });
+
+ it('should generate a v4 signed policy', async () => {
+ const output = execSync(
+ `node generateV4SignedPolicy.js ${bucketName} ${signedFileName}`
+ );
+
+ assert.include(
+ output,
+ `');
+ });
+
+ it('should get metadata for a file', () => {
+ const output = execSync(
+ `node getMetadata.js ${bucketName} ${copiedFileName}`
+ );
+ assert.include(output, `Bucket: ${bucketName}`);
+ assert.include(output, `Name: ${copiedFileName}`);
+ });
+
+ it('should set metadata for a file', async () => {
+ const [metadata] = await bucket.file(copiedFileName).getMetadata();
+
+ // used in sample
+ const userMetadata = {
+ description: 'file description...',
+ modified: '1900-01-01',
+ };
+ const output = execSync(
+ `node fileSetMetadata.js ${bucketName} ${copiedFileName} ${metadata.metageneration} `
+ );
+
+ assert.match(
+ output,
+ new RegExp(`description: '${userMetadata.description}'`)
+ );
+ assert.match(output, new RegExp(`modified: '${userMetadata.modified}'`));
+ });
+
+ it('should set storage class for a file', async () => {
+ const output = execSync(
+ `node fileChangeStorageClass.js ${bucketName} ${copiedFileName} standard ${doesNotExistPrecondition}`
+ );
+ assert.include(output, `${copiedFileName} has been set to standard`);
+ const [metadata] = await storage
+ .bucket(bucketName)
+ .file(copiedFileName)
+ .getMetadata();
+ assert.strictEqual(metadata.storageClass, 'STANDARD');
+ });
+
+ it('should combine multiple files into one new file', async () => {
+ const firstFileName = 'file-one.txt';
+ const secondFileName = 'file-two.txt';
+ const destinationFileName = 'file-one-two.txt';
+
+ const files = [
+ {file: bucket.file(firstFileName), contents: '123'},
+ {file: bucket.file(secondFileName), contents: '456'},
+ ];
+
+ await Promise.all(files.map(file => createFileAsync(file)));
+ const destinationFile = bucket.file(destinationFileName);
+
+ const output = execSync(
+ `node composeFile.js ${bucketName} ${firstFileName} ${secondFileName} ${destinationFileName}`
+ );
+ assert.include(
+ output,
+ `New composite file ${destinationFileName} was created by combining ${firstFileName} and ${secondFileName}`
+ );
+
+ const [contents] = await destinationFile.download();
+ assert.strictEqual(
+ contents.toString(),
+ files.map(x => x.contents).join('')
+ );
+ });
+
+ it('should delete a file', async () => {
+ const [metadata] = await bucket.file(copiedFileName).getMetadata();
+ const output = execSync(
+ `node deleteFile.js ${bucketName} ${copiedFileName} ${metadata.generation}`
+ );
+ assert.match(
+ output,
+ new RegExp(`gs://${bucketName}/${copiedFileName} deleted`)
+ );
+ const [exists] = await bucket.file(copiedFileName).exists();
+ assert.strictEqual(exists, false);
+ });
+
+ describe('file archived generations', () => {
+ const bucketNameWithVersioning = generateName();
+ const fileName = 'file-one.txt';
+ const bucketWithVersioning = storage.bucket(bucketNameWithVersioning);
+
+ before(async () => {
+ const versionedFile = bucketWithVersioning.file(fileName);
+ const filesToCreate = [
+ {file: versionedFile, contents: '123'},
+ {file: versionedFile, contents: '456'},
+ ];
+ await storage.createBucket(bucketNameWithVersioning, {
+ versioning: {
+ enabled: true,
+ },
+ });
+ await Promise.all(filesToCreate.map(file => createFileAsync(file)));
+ });
+
+ after(async () => {
+ await bucketWithVersioning.deleteFiles({
+ versions: true,
+ force: true,
+ });
+ await bucketWithVersioning.delete();
+ });
+
+ it('should list file with old versions', async () => {
+ const output = execSync(
+ `node listFilesWithOldVersions.js ${bucketNameWithVersioning}`
+ );
+ assert.notEqual(output.indexOf(fileName), output.lastIndexOf(fileName));
+ });
+
+ it('should copy file with old versions', async () => {
+ const destFileName = 'file-two.txt';
+ const [files] = await bucketWithVersioning.getFiles({versions: true});
+ const generation = files[0].metadata.generation;
+ const output = execSync(
+ `node copyOldVersionOfFile.js ${bucketNameWithVersioning} ${fileName} ${bucketNameWithVersioning} ${destFileName} ${generation}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `Generation ${generation} of file ${fileName} in bucket ${bucketNameWithVersioning} was copied to ${destFileName} in bucket ${bucketNameWithVersioning}`
+ )
+ );
+ const [exists] = await bucketWithVersioning.file(destFileName).exists();
+ assert.strictEqual(exists, true);
+ });
+
+ it('should delete a file with customized retry settings', () => {
+ const output = execSync(
+ `node configureRetries.js ${bucketName} ${fileName}`
+ );
+ assert.match(
+ output,
+ new RegExp(`File ${fileName} deleted with a customized retry strategy.`)
+ );
+ });
+
+ it('should delete file with versions', async () => {
+ const [files] = await bucketWithVersioning.getFiles({versions: true});
+ const generation = files[0].metadata.generation;
+ const output = execSync(
+ `node deleteOldVersionOfFile.js ${bucketNameWithVersioning} ${fileName} ${generation}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `Generation ${generation} of file ${fileName} was deleted from ${bucketNameWithVersioning}`
+ )
+ );
+ const [exists] = await bucketWithVersioning
+ .file(fileName, {
+ generation,
+ })
+ .exists();
+ assert.strictEqual(exists, false);
+ });
+ });
+
+ describe('Object Retention', () => {
+ before(async () => {
+ await storage.createBucket(objectRetentionBucketName, {
+ enableObjectRetention: true,
+ });
+ });
+
+ it('should create a file with unlocked retention and then override it', async () => {
+ const output = execSync(
+ `node setObjectRetentionPolicy.js ${objectRetentionBucketName} ${fileName} ${fileContent}`
+ );
+ assert.include(output, 'Retention policy for file');
+ const file = objectRetentionBucket.file(fileName);
+ const [metadata] = await file.getMetadata();
+ assert(metadata.retention.retainUntilTime);
+ assert(metadata.retention.mode.toUpperCase(), 'UNLOCKED');
+ });
+ });
+
+ describe('Object Soft Delete', () => {
+ let generation;
+ before(async () => {
+ await storage.createBucket(softDeleteBucketName, {
+ softDeletePolicy: {
+ retentionDurationSeconds: 604800,
+ },
+ });
+ const file = softDeleteBucket.file(fileName);
+ await file.save(fileName);
+ const [metadata] = await softDeleteBucket.file(fileName).getMetadata();
+ generation = metadata.generation;
+ await file.delete();
+ });
+
+ after(async () => {
+ await softDeleteBucket.deleteFiles();
+ await softDeleteBucket.delete();
+ });
+
+ it('should list soft deleted objects', async () => {
+ const output = await execSync(
+ `node listSoftDeletedObjects.js ${softDeleteBucketName}`
+ );
+ assert.match(output, /Files:/);
+ assert.match(output, new RegExp(fileName));
+ });
+
+ it('should list soft deleted object versions', async () => {
+ const output = await execSync(
+ `node listSoftDeletedObjectVersions.js ${softDeleteBucketName} ${fileName}`
+ );
+ assert.match(output, /Files:/);
+ assert.match(
+ output,
+ new RegExp(`Name: ${fileName}, Generation: ${generation}`)
+ );
+ });
+
+ it('should restore soft deleted object', async () => {
+ const output = await execSync(
+ `node restoreSoftDeletedObject.js ${softDeleteBucketName} ${fileName} ${generation}`
+ );
+ assert.include(output, `Soft deleted object ${fileName} was restored`);
+ const [exists] = await softDeleteBucket.file(fileName).exists();
+ assert.strictEqual(exists, true);
+ });
+ });
+});
+
+function generateName() {
+ return `nodejs-storage-samples-${uuid.v4()}`;
+}
+
+function createFileAsync(fileObject) {
+ return fileObject.file.save(fileObject.contents);
+}
diff --git a/storage/system-test/hmacKey.test.js b/storage/system-test/hmacKey.test.js
new file mode 100644
index 0000000000..20c4e149bf
--- /dev/null
+++ b/storage/system-test/hmacKey.test.js
@@ -0,0 +1,116 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, describe, it} = require('mocha');
+const cp = require('child_process');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+const pLimit = require('p-limit');
+const storage = new Storage();
+const SERVICE_ACCOUNT_EMAIL = process.env.HMAC_KEY_TEST_SERVICE_ACCOUNT;
+const SERVICE_ACCOUNT_PROJECT = process.env.HMAC_PROJECT;
+
+describe('HMAC SA Key samples', () => {
+ let hmacKey;
+
+ before(async () => {
+ await deleteStaleHmacKeys(SERVICE_ACCOUNT_EMAIL, SERVICE_ACCOUNT_PROJECT);
+ [hmacKey] = await storage.createHmacKey(SERVICE_ACCOUNT_EMAIL, {
+ projectId: SERVICE_ACCOUNT_PROJECT,
+ });
+ });
+
+ after(async () => {
+ await deleteStaleHmacKeys(SERVICE_ACCOUNT_EMAIL, SERVICE_ACCOUNT_PROJECT);
+ });
+
+ it('should create an HMAC Key', async () => {
+ const output = execSync(
+ `node hmacKeyCreate.js ${SERVICE_ACCOUNT_EMAIL} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ assert.include(output, 'The base64 encoded secret is:');
+ });
+
+ it('should list HMAC Keys', async () => {
+ const output = execSync(`node hmacKeysList.js ${SERVICE_ACCOUNT_PROJECT}`);
+ assert.include(output, `Service Account Email: ${SERVICE_ACCOUNT_EMAIL}`);
+ });
+
+ it('should get HMAC Key', async () => {
+ const output = execSync(
+ `node hmacKeyGet.js ${hmacKey.metadata.accessId} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ assert.include(output, 'The HMAC key metadata is:');
+ });
+
+ it('should deactivate HMAC Key', async () => {
+ const output = execSync(
+ `node hmacKeyDeactivate.js ${hmacKey.metadata.accessId} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ assert.include(output, 'The HMAC key is now inactive.');
+ });
+
+ it('should activate HMAC Key', async () => {
+ const output = execSync(
+ `node hmacKeyActivate.js ${hmacKey.metadata.accessId} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ assert.include(output, 'The HMAC key is now active.');
+ });
+
+ it('should delete HMAC key', async () => {
+ // Deactivate then delete
+ execSync(
+ `node hmacKeyDeactivate.js ${hmacKey.metadata.accessId} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ const output = execSync(
+ `node hmacKeyDelete.js ${hmacKey.metadata.accessId} ${SERVICE_ACCOUNT_PROJECT}`
+ );
+ assert.include(
+ output,
+ 'The key is deleted, though it may still appear in getHmacKeys() results.'
+ );
+ });
+});
+
+/*
+ * Delete HMAC Keys older than 1 hour
+ */
+async function deleteStaleHmacKeys(serviceAccountEmail, projectId) {
+ const old = new Date();
+ old.setHours(old.getHours() - 1);
+ // list all HMAC keys for the given service account.
+ const [hmacKeys] = await storage.getHmacKeys({
+ serviceAccountEmail,
+ projectId,
+ });
+
+ const limit = pLimit(10);
+ await Promise.all(
+ hmacKeys
+ .filter(hmacKey => {
+ const hmacKeyCreated = new Date(hmacKey.metadata.timeCreated);
+ return hmacKey.metadata.state !== 'DELETED' && hmacKeyCreated < old;
+ })
+ .map(hmacKey =>
+ limit(async () => {
+ await hmacKey.setMetadata({state: 'INACTIVE'});
+ await hmacKey.delete();
+ })
+ )
+ );
+}
diff --git a/storage/system-test/iam.test.js b/storage/system-test/iam.test.js
new file mode 100644
index 0000000000..22da024e15
--- /dev/null
+++ b/storage/system-test/iam.test.js
@@ -0,0 +1,103 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+const userEmail = 'test@example.com';
+const roleName = 'roles/storage.objectViewer';
+
+// Condition
+const title = 'match-prefix';
+const description = 'Applies to objects matching a prefix';
+const expression =
+ 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")';
+
+before(async () => {
+ await bucket.create();
+ // UniformBucketLevelAccess must be enabled to add a conditional binding.
+ await bucket.setMetadata({
+ iamConfiguration: {
+ uniformBucketLevelAccess: {
+ enabled: true,
+ },
+ },
+ });
+});
+
+after(async () => {
+ await bucket.delete().catch(console.error);
+});
+
+it('should add multiple members to a role on a bucket', async () => {
+ const output = execSync(
+ `node addBucketIamMember.js ${bucketName} ${roleName} "user:${userEmail}"`
+ );
+ assert.include(
+ output,
+ `Added the following member(s) with role ${roleName} to ${bucketName}:`
+ );
+ assert.match(output, new RegExp(`user:${userEmail}`));
+});
+
+it('should add conditional binding to a bucket', async () => {
+ const output = execSync(
+ `node addBucketConditionalBinding.js ${bucketName} ${roleName} '${title}' '${description}' '${expression}' "user:${userEmail}"`
+ );
+ assert.include(
+ output,
+ `Added the following member(s) with role ${roleName} to ${bucketName}:`
+ );
+ assert.include(output, 'with condition:');
+ assert.include(output, `Title: ${title}`);
+ assert.include(output, `Description: ${description}`);
+ assert.include(output, `Expression: ${expression}`);
+});
+
+it('should list members of a role on a bucket', async () => {
+ const output = execSync(`node viewBucketIamMembers.js ${bucketName}`);
+ assert.match(output, new RegExp(`Bindings for bucket ${bucketName}:`));
+ assert.match(output, new RegExp(`Role: ${roleName}`));
+ assert.match(output, new RegExp('Members:'));
+ assert.match(output, new RegExp(`user:${userEmail}`));
+});
+
+it('should remove multiple members from a role on a bucket', async () => {
+ const output = execSync(
+ `node removeBucketIamMember.js ${bucketName} ${roleName} "user:${userEmail}"`
+ );
+ assert.ok(
+ output.includes(
+ `Removed the following member(s) with role ${roleName} from ${bucketName}:`
+ )
+ );
+ assert.match(output, new RegExp(`user:${userEmail}`));
+});
+
+it('should remove conditional binding to a bucket', async () => {
+ const output = execSync(
+ `node removeBucketConditionalBinding.js ${bucketName} ${roleName} '${title}' '${description}' '${expression}'`
+ );
+ assert.include(output, 'Conditional Binding was removed');
+});
diff --git a/storage/system-test/notifications.test.js b/storage/system-test/notifications.test.js
new file mode 100644
index 0000000000..ef88d8b07c
--- /dev/null
+++ b/storage/system-test/notifications.test.js
@@ -0,0 +1,99 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {PubSub} = require('@google-cloud/pubsub');
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const bucket = storage.bucket(bucketName);
+const notificationId = '1';
+const notification = bucket.notification(notificationId);
+const topicName = `nodejs-storage-samples-${uuid.v4()}`;
+const pubsub = new PubSub();
+const topic = pubsub.topic(topicName);
+
+before(async () => {
+ await bucket.create();
+ await topic.create();
+ await topic.iam.setPolicy({
+ bindings: [
+ {
+ role: 'roles/pubsub.editor',
+ members: ['allUsers'],
+ },
+ ],
+ });
+});
+
+after(async () => {
+ await bucket.delete().catch(console.error);
+ await topic.delete().catch(console.error);
+});
+
+it('should create a notification', async () => {
+ const output = execSync(
+ `node createNotification.js ${bucketName} ${topicName}`
+ );
+ assert.match(output, /Notification subscription created./);
+ const [exists] = await notification.exists();
+ assert.strictEqual(exists, true);
+});
+
+it('should list notifications', async () => {
+ const output = execSync(`node listNotifications.js ${bucketName}`);
+ assert.match(output, /Notifications:/);
+ assert.match(output, new RegExp(notificationId));
+});
+
+it('should get metadata', async () => {
+ const metadata = await notification.getMetadata();
+ const output = execSync(
+ `node getMetadataNotifications.js ${bucketName} ${notificationId}`
+ );
+ assert.match(output, /ID:/);
+ assert.match(output, new RegExp(metadata.id));
+ assert.match(output, /Topic:/);
+ assert.match(output, new RegExp(metadata.topic));
+ assert.match(output, /Event Types:/);
+ assert.match(output, new RegExp(metadata.event_types));
+ assert.match(output, /Custom Attributes:/);
+ assert.match(output, new RegExp(metadata.custom_attributes));
+ assert.match(output, /Payload Format:/);
+ assert.match(output, new RegExp(metadata.payload_format));
+ assert.match(output, /Object Name Prefix:/);
+ assert.match(output, new RegExp(metadata.object_name_prefix));
+ assert.match(output, /Etag:/);
+ assert.match(output, /Self Link:/);
+ assert.match(output, new RegExp(metadata.selfLink));
+ assert.match(output, /Kind:/);
+ assert.match(output, new RegExp(metadata.kind));
+});
+
+it('should delete a notification', async () => {
+ const output = execSync(
+ `node deleteNotification.js ${bucketName} ${notificationId}`
+ );
+ assert.match(output, new RegExp(`Notification ${notificationId} deleted.`));
+ const [exists] = await notification.exists();
+ assert.strictEqual(exists, false);
+});
diff --git a/storage/system-test/quickstart.test.js b/storage/system-test/quickstart.test.js
new file mode 100644
index 0000000000..4e3ffe0038
--- /dev/null
+++ b/storage/system-test/quickstart.test.js
@@ -0,0 +1,36 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {assert} = require('chai');
+const {after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+const {Storage} = require('@google-cloud/storage');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+
+after(async () => {
+ const bucket = storage.bucket(bucketName);
+ await bucket.delete().catch(console.error);
+});
+
+it('should run the quickstart', async () => {
+ const stdout = execSync(`node quickstart ${bucketName}`);
+ assert.match(stdout, /Bucket .* created./);
+});
diff --git a/storage/system-test/requesterPays.test.js b/storage/system-test/requesterPays.test.js
new file mode 100644
index 0000000000..76611db164
--- /dev/null
+++ b/storage/system-test/requesterPays.test.js
@@ -0,0 +1,109 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const fs = require('fs');
+const {Storage} = require('@google-cloud/storage');
+const {assert} = require('chai');
+const {before, after, it} = require('mocha');
+const cp = require('child_process');
+const uuid = require('uuid');
+const path = require('path');
+const {promisify} = require('util');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+const storage = new Storage();
+const cwd = path.join(__dirname, '..');
+const bucketName = `nodejs-storage-samples-${uuid.v4()}`;
+const fileName = 'test.txt';
+const bucket = storage.bucket(bucketName);
+const projectId = process.env.GCLOUD_PROJECT;
+
+const uploadFilePath = path.join(cwd, 'resources', fileName);
+const downloadFilePath = path.join(__dirname, `test_${uuid.v4()}.txt`);
+
+before(async () => {
+ await bucket.create();
+ // Upload a test file (to download later)
+ await bucket.upload(uploadFilePath);
+});
+
+after(async () => {
+ await promisify(fs.unlink)(downloadFilePath).catch(console.error);
+ // Try deleting all files twice, just to make sure
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.delete().catch(console.error);
+});
+
+it.skip('should error on requester-pays requests if they are disabled', () => {
+ const result = execSync(
+ `node downloadFileUsingRequesterPays.js ${projectId} ${bucketName} ${fileName} ${downloadFilePath}`
+ );
+ assert.ok(result.stderr);
+ assert.match(
+ result.stderr,
+ /User project prohibited for non requester pays bucket/
+ );
+});
+
+it('should fetch requester-pays status on a default bucket', () => {
+ const out = execSync(`node getRequesterPaysStatus.js ${bucketName}`);
+ assert.include(
+ out,
+ `Requester-pays requests are disabled for bucket ${bucketName}`
+ );
+});
+
+it('should enable requester-pays requests', () => {
+ const out = execSync(`node enableRequesterPays.js ${bucketName}`);
+ assert.include(
+ out,
+ `Requester-pays requests have been enabled for bucket ${bucketName}`
+ );
+});
+
+it('should fetch requester-pays status on a modified bucket', () => {
+ const out = execSync(`node getRequesterPaysStatus.js ${bucketName}`);
+ assert.include(
+ out,
+ `Requester-pays requests are enabled for bucket ${bucketName}.`
+ );
+});
+
+it('should download a file using requester-pays requests', () => {
+ const out = execSync(
+ `node downloadFileUsingRequesterPays.js ${projectId} ${bucketName} ${fileName} ${downloadFilePath}`
+ );
+ assert.include(
+ out,
+ `gs://${bucketName}/${fileName} downloaded to ${downloadFilePath} using requester-pays requests`
+ );
+ fs.statSync(downloadFilePath);
+});
+
+it('should disable requester-pays requests', () => {
+ const out = execSync(`node disableRequesterPays.js ${bucketName}`);
+ assert.include(
+ out,
+ `Requester-pays requests have been disabled for bucket ${bucketName}`
+ );
+});
+
+it('should get service account', () => {
+ const out = execSync(`node getServiceAccount.js ${projectId}`);
+ assert.include(out, '@gs-project-accounts.iam.gserviceaccount.com');
+});
diff --git a/storage/system-test/storage.test.js b/storage/system-test/storage.test.js
new file mode 100644
index 0000000000..9aacf774be
--- /dev/null
+++ b/storage/system-test/storage.test.js
@@ -0,0 +1,30 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const {assert} = require('chai');
+const {it} = require('mocha');
+const cp = require('child_process');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+
+it('should intialize storage with a custom api endpoint', async () => {
+ const apiEndpoint = 'https://storage.googleapis.com';
+ const output = execSync(`node setClientEndpoint.js ${apiEndpoint}`);
+ assert.match(
+ output,
+ new RegExp(`Client initiated with endpoint: ${apiEndpoint}.`)
+ );
+});
diff --git a/storage/system-test/test_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt b/storage/system-test/test_9d800329-00da-4cdd-9a3e-7ac6743d5813.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/storage/system-test/transfer-manager.test.js b/storage/system-test/transfer-manager.test.js
new file mode 100644
index 0000000000..f6180bed3a
--- /dev/null
+++ b/storage/system-test/transfer-manager.test.js
@@ -0,0 +1,118 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const path = require('path');
+const {Storage} = require('@google-cloud/storage');
+const {before, after, it, describe} = require('mocha');
+const uuid = require('uuid');
+const cp = require('child_process');
+const {assert} = require('chai');
+
+const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'});
+const storage = new Storage();
+const cwd = path.join(__dirname, '..');
+const bucketName = generateName();
+const bucket = storage.bucket(bucketName);
+const firstFileName = 'test.txt';
+const secondFileName = 'test2.txt';
+const resourcesPath = path.join(cwd, 'resources');
+const firstFilePath = path.join(resourcesPath, firstFileName);
+const secondFilePath = path.join(resourcesPath, secondFileName);
+const downloadFilePath = path.join(cwd, 'downloaded.txt');
+const chunkSize = 1024;
+
+describe('transfer manager', () => {
+ before(async () => {
+ await bucket.create();
+ });
+
+ after(async () => {
+ await bucket.deleteFiles({force: true}).catch(console.error);
+ await bucket.delete().catch(console.error);
+ });
+
+ it('should upload multiple files', async () => {
+ const output = execSync(
+ `node uploadManyFilesWithTransferManager.js ${bucketName} ${firstFilePath} ${secondFilePath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `${firstFilePath} uploaded to ${bucketName}.\n${secondFilePath} uploaded to ${bucketName}`
+ )
+ );
+ });
+
+ it('should download mulitple files', async () => {
+ const output = execSync(
+ `node downloadManyFilesWithTransferManager.js ${bucketName} ${firstFilePath} ${secondFilePath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${firstFilePath} downloaded to ${firstFilePath}.\ngs://${bucketName}/${secondFilePath} downloaded to ${secondFilePath}.`
+ )
+ );
+ });
+
+ it('should download a file utilizing chunked download', async () => {
+ const output = execSync(
+ `node downloadFileInChunksWithTransferManager.js ${bucketName} ${firstFilePath} ${downloadFilePath} ${chunkSize}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${firstFilePath} downloaded to ${downloadFilePath}.`
+ )
+ );
+ });
+
+ it('should upload a file utilizing chunked upload', async () => {
+ const output = execSync(
+ `node uploadFileInChunksWithTransferManager.js ${bucketName} ${firstFilePath} ${chunkSize}`
+ );
+ assert.match(
+ output,
+ new RegExp(`${firstFilePath} uploaded to ${bucketName}.`)
+ );
+ });
+
+ it('should upload a directory', async () => {
+ const output = execSync(
+ `node uploadDirectoryWithTransferManager.js ${bucketName} ${resourcesPath}`
+ );
+ assert.match(
+ output,
+ new RegExp(`${resourcesPath} uploaded to ${bucketName}.`)
+ );
+ });
+
+ it('should download a directory', async () => {
+ const output = execSync(
+ `node downloadFolderWithTransferManager.js ${bucketName} ${resourcesPath}`
+ );
+ assert.match(
+ output,
+ new RegExp(
+ `gs://${bucketName}/${resourcesPath} downloaded to ${resourcesPath}.`
+ )
+ );
+ });
+});
+
+function generateName() {
+ return `nodejs-storage-samples-${uuid.v4()}`;
+}
diff --git a/storage/uploadDirectory.js b/storage/uploadDirectory.js
new file mode 100644
index 0000000000..e15d6e6746
--- /dev/null
+++ b/storage/uploadDirectory.js
@@ -0,0 +1,98 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+// sample-metadata:
+// title: Upload a directory to a bucket.
+// description: Uploads full hierarchy of a local directory to a bucket.
+// usage: node files.js upload-directory
+
+function main(
+ bucketName = 'your-unique-bucket-name',
+ directoryPath = './local/path/to/directory'
+) {
+ // [START upload_directory]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The local directory to upload
+ // const directoryPath = './local/path/to/directory';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ const {promisify} = require('util');
+ const fs = require('fs');
+ const path = require('path');
+
+ const readdir = promisify(fs.readdir);
+ const stat = promisify(fs.stat);
+
+ async function* getFiles(directory = '.') {
+ for (const file of await readdir(directory)) {
+ const fullPath = path.join(directory, file);
+ const stats = await stat(fullPath);
+
+ if (stats.isDirectory()) {
+ yield* getFiles(fullPath);
+ }
+
+ if (stats.isFile()) {
+ yield fullPath;
+ }
+ }
+ }
+
+ async function uploadDirectory() {
+ try {
+ const bucket = storage.bucket(bucketName);
+ let successfulUploads = 0;
+
+ for await (const filePath of getFiles(directoryPath)) {
+ try {
+ const dirname = path.dirname(directoryPath);
+ const destination = path.relative(dirname, filePath);
+
+ await bucket.upload(filePath, {destination});
+
+ console.log(`Successfully uploaded: ${filePath}`);
+ successfulUploads++;
+ } catch (e) {
+ console.error(`Error uploading ${filePath}:`, e);
+ }
+ }
+
+ console.log(
+ `${successfulUploads} files uploaded to ${bucketName} successfully.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing upload directory:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadDirectory();
+ // [END upload_directory]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/uploadDirectoryWithTransferManager.js b/storage/uploadDirectoryWithTransferManager.js
new file mode 100644
index 0000000000..28f29ec0e0
--- /dev/null
+++ b/storage/uploadDirectoryWithTransferManager.js
@@ -0,0 +1,58 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// sample-metadata:
+// title: Upload Directory With Transfer Manager
+// description: Uploads a directory in parallel utilizing transfer manager.
+// usage: node uploadFolderWithTransferManager.js
+
+function main(bucketName = 'my-bucket', directoryName = 'my-directory') {
+ // [START storage_transfer_manager_upload_directory]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The local directory to upload
+ // const directoryName = 'your-directory';
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function uploadDirectoryWithTransferManager() {
+ // Uploads the directory
+ await transferManager.uploadManyFiles(directoryName);
+
+ console.log(`${directoryName} uploaded to ${bucketName}.`);
+ }
+
+ uploadDirectoryWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_upload_directory]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/uploadEncryptedFile.js b/storage/uploadEncryptedFile.js
new file mode 100644
index 0000000000..4f26d889c7
--- /dev/null
+++ b/storage/uploadEncryptedFile.js
@@ -0,0 +1,80 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+const path = require('path');
+
+function main(
+ bucketName = 'my-bucket',
+ filePath = path.join(__dirname, '../resources', 'test.txt'),
+ destFileName = 'test.txt',
+ key = process.env.GOOGLE_CLOUD_KMS_KEY_US,
+ generationMatchPrecondition = 0
+) {
+ // [START storage_upload_encrypted_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The path to your file to upload
+ // const filePath = 'path/to/your/file';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // The key to encrypt the object with
+ // const key = 'TIbv/fjexq+VmtXzAlc63J4z5kFmWJ6NdAPQulQBT7g=';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadEncryptedFile() {
+ try {
+ const options = {
+ destination: destFileName,
+ encryptionKey: Buffer.from(key, 'base64'),
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to upload is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ preconditionOpts: {ifGenerationMatch: generationMatchPrecondition},
+ };
+
+ await storage.bucket(bucketName).upload(filePath, options);
+
+ console.log(
+ `File ${filePath} uploaded to gs://${bucketName}/${destFileName}`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing upload encrypted file:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadEncryptedFile();
+ // [END storage_upload_encrypted_file]
+}
+main(...process.argv.slice(2));
diff --git a/storage/uploadFile.js b/storage/uploadFile.js
new file mode 100644
index 0000000000..a54af5eb9b
--- /dev/null
+++ b/storage/uploadFile.js
@@ -0,0 +1,67 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ filePath = './local/path/to/file.txt',
+ destFileName = 'file.txt',
+ generationMatchPrecondition = 0
+) {
+ // [START storage_upload_file]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The path to your file to upload
+ // const filePath = 'path/to/your/file';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadFile() {
+ try {
+ const options = {
+ destination: destFileName,
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to upload is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ preconditionOpts: {ifGenerationMatch: generationMatchPrecondition},
+ };
+
+ await storage.bucket(bucketName).upload(filePath, options);
+ console.log(`${filePath} uploaded to ${bucketName}`);
+ } catch (error) {
+ console.error('Error executing upload file:', error.message || error);
+ }
+ }
+
+ uploadFile();
+ // [END storage_upload_file]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/uploadFileInChunksWithTransferManager.js b/storage/uploadFileInChunksWithTransferManager.js
new file mode 100644
index 0000000000..02e8437849
--- /dev/null
+++ b/storage/uploadFileInChunksWithTransferManager.js
@@ -0,0 +1,67 @@
+/**
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// sample-metadata:
+// title: Upload a File in Chunks With Transfer Manager
+// description: Uploads a single file in in chunks in parallel utilizing transfer manager.
+// usage: node uploadFileInChunksWithTransferManager.js
+
+function main(
+ bucketName = 'my-bucket',
+ filePath = './local/path/to/file.txt',
+ chunkSize = 32 * 1024 * 1024
+) {
+ // [START storage_transfer_manager_upload_chunks_concurrently]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The path of file to upload
+ // const filePath = 'path/to/your/file';
+
+ // The size of each chunk to be uploaded
+ // const chunkSize = 32 * 1024 * 1024;
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function uploadFileInChunksWithTransferManager() {
+ // Uploads the files
+ await transferManager.uploadFileInChunks(filePath, {
+ chunkSizeBytes: chunkSize,
+ });
+
+ console.log(`${filePath} uploaded to ${bucketName}.`);
+ }
+
+ uploadFileInChunksWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_upload_chunks_concurrently]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/uploadFileWithKmsKey.js b/storage/uploadFileWithKmsKey.js
new file mode 100644
index 0000000000..b94d718bc4
--- /dev/null
+++ b/storage/uploadFileWithKmsKey.js
@@ -0,0 +1,78 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+/**
+ * This application demonstrates how to perform basic operations on files with
+ * the Google Cloud Storage API.
+ *
+ * For more information, see the README.md under /storage and the documentation
+ * at https://cloud.google.com/storage/docs.
+ */
+
+function main(
+ bucketName = 'my-bucket',
+ filePath = 'test.txt',
+ kmsKeyName = process.env.GOOGLE_CLOUD_KMS_KEY_US,
+ generationMatchPrecondition = 0
+) {
+ // [START storage_upload_with_kms_key]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The path to your file to upload
+ // const filePath = 'path/to/your/file';
+
+ // The name of the KMS-key
+ // const kmsKeyName = 'my-key';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadFileWithKmsKey() {
+ try {
+ const options = {
+ kmsKeyName,
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to upload is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ preconditionOpts: {ifGenerationMatch: generationMatchPrecondition},
+ };
+
+ await storage.bucket(bucketName).upload(filePath, options);
+
+ console.log(`${filePath} uploaded to ${bucketName} using ${kmsKeyName}.`);
+ } catch (error) {
+ console.error(
+ 'Error executing upload file with kms key:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadFileWithKmsKey().catch(console.error);
+ // [END storage_upload_with_kms_key]
+}
+main(...process.argv.slice(2));
diff --git a/storage/uploadFromMemory.js b/storage/uploadFromMemory.js
new file mode 100644
index 0000000000..919439c882
--- /dev/null
+++ b/storage/uploadFromMemory.js
@@ -0,0 +1,60 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ contents = 'these are my file contents',
+ destFileName = 'file.txt'
+) {
+ // [START storage_file_upload_from_memory]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The contents that you want to upload
+ // const contents = 'these are my contents';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud Node.js client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadFromMemory() {
+ try {
+ await storage.bucket(bucketName).file(destFileName).save(contents);
+
+ console.log(
+ `${destFileName} with contents ${contents} uploaded to ${bucketName}.`
+ );
+ } catch (error) {
+ console.error(
+ 'Error executing file upload from memory:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadFromMemory();
+ // [END storage_file_upload_from_memory]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/uploadManyFilesWithTransferManager.js b/storage/uploadManyFilesWithTransferManager.js
new file mode 100644
index 0000000000..cc0019f509
--- /dev/null
+++ b/storage/uploadManyFilesWithTransferManager.js
@@ -0,0 +1,67 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// sample-metadata:
+// title: Upload Many Files With Transfer Manager
+// description: Uploads many files in parallel utilizing transfer manager.
+// usage: node uploadManyFilesWithTransferManager.js
+
+function main(
+ bucketName = 'my-bucket',
+ firstFilePath = './local/path/to/file1.txt',
+ secondFilePath = './local/path/to/file2.txt'
+) {
+ // [START storage_transfer_manager_upload_many]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The ID of the first GCS file to upload
+ // const firstFilePath = 'your-first-file-name';
+
+ // The ID of the second GCS file to upload
+ // const secondFilePath = 'your-second-file-name';
+
+ // Imports the Google Cloud client library
+ const {Storage, TransferManager} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ // Creates a transfer manager client
+ const transferManager = new TransferManager(storage.bucket(bucketName));
+
+ async function uploadManyFilesWithTransferManager() {
+ // Uploads the files
+ await transferManager.uploadManyFiles([firstFilePath, secondFilePath]);
+
+ for (const filePath of [firstFilePath, secondFilePath]) {
+ console.log(`${filePath} uploaded to ${bucketName}.`);
+ }
+ }
+
+ uploadManyFilesWithTransferManager().catch(console.error);
+ // [END storage_transfer_manager_upload_many]
+}
+
+process.on('unhandledRejection', err => {
+ console.error(err.message);
+ process.exitCode = 1;
+});
+main(...process.argv.slice(2));
diff --git a/storage/uploadWithoutAuthentication.js b/storage/uploadWithoutAuthentication.js
new file mode 100644
index 0000000000..254509d33b
--- /dev/null
+++ b/storage/uploadWithoutAuthentication.js
@@ -0,0 +1,82 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ contents = 'these are my file contents',
+ destFileName = 'file.txt',
+ generationMatchPrecondition = 0
+) {
+ // [START storage_upload_without_authentication]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The contents that you want to upload
+ // const contents = 'these are my contents';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud Node.js client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadWithoutAuthentication() {
+ try {
+ const file = storage.bucket(bucketName).file(destFileName);
+
+ // Returns an authenticated endpoint to which
+ // you can make requests without credentials.
+ const [location] = await file.createResumableUpload(); //auth required
+
+ const options = {
+ uri: location,
+ resumable: true,
+ validation: false,
+
+ // Optional:
+ // Set a generation-match precondition to avoid potential race conditions
+ // and data corruptions. The request to upload is aborted if the object's
+ // generation number does not match your precondition. For a destination
+ // object that does not yet exist, set the ifGenerationMatch precondition to 0
+ // If the destination object already exists in your bucket, set instead a
+ // generation-match precondition using its generation number.
+ preconditionOpts: {ifGenerationMatch: generationMatchPrecondition},
+ };
+
+ // Passes the location to file.save so you don't need to
+ // authenticate this call
+ await file.save(contents, options);
+
+ console.log(`${destFileName} uploaded to ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing upload without authentication:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadWithoutAuthentication();
+ // [END storage_upload_without_authentication]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/uploadWithoutAuthenticationSignedUrl.js b/storage/uploadWithoutAuthenticationSignedUrl.js
new file mode 100644
index 0000000000..61096b444a
--- /dev/null
+++ b/storage/uploadWithoutAuthenticationSignedUrl.js
@@ -0,0 +1,90 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(
+ bucketName = 'my-bucket',
+ contents = 'these are my file contents',
+ destFileName = 'file.txt'
+) {
+ // [START storage_upload_without_authentication_signed_url]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // The contents that you want to upload
+ // const contents = 'these are my contents';
+
+ // The new ID for your GCS file
+ // const destFileName = 'your-new-file-name';
+
+ // Imports the Google Cloud Node.js client library
+ const {Storage} = require('@google-cloud/storage');
+
+ const fetch = require('node-fetch');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function uploadWithoutAuthenticationSignedUrlStrategy() {
+ try {
+ const file = storage.bucket(bucketName).file(destFileName);
+
+ // Use signed URLs to manually start resumable uploads.
+ // Authenticating is required to get the signed URL, but isn't
+ // required to start the resumable upload
+ const options = {
+ version: 'v4',
+ action: 'resumable',
+ expires: Date.now() + 30 * 60 * 1000, // 30 mins
+ };
+ //auth required
+ const [signedUrl] = await file.getSignedUrl(options);
+
+ // no auth required
+ const resumableSession = await fetch(signedUrl, {
+ method: 'POST',
+ headers: {
+ 'x-goog-resumable': 'start',
+ },
+ });
+
+ // Endpoint to which we should upload the file
+ const location = resumableSession.headers.location;
+
+ // Passes the location to file.save so you don't need to
+ // authenticate this call
+ await file.save(contents, {
+ uri: location,
+ resumable: true,
+ validation: false,
+ });
+
+ console.log(`${destFileName} uploaded to ${bucketName}`);
+ } catch (error) {
+ console.error(
+ 'Error executing upload without authentication signed url strategy:',
+ error.message || error
+ );
+ }
+ }
+
+ uploadWithoutAuthenticationSignedUrlStrategy();
+ // [END storage_upload_without_authentication_signed_url]
+}
+
+main(...process.argv.slice(2));
diff --git a/storage/viewBucketIamMembers.js b/storage/viewBucketIamMembers.js
new file mode 100644
index 0000000000..21d0d8af23
--- /dev/null
+++ b/storage/viewBucketIamMembers.js
@@ -0,0 +1,70 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+'use strict';
+
+function main(bucketName = 'my-bucket') {
+ // [START storage_view_bucket_iam_members]
+ /**
+ * TODO(developer): Uncomment the following lines before running the sample.
+ */
+ // The ID of your GCS bucket
+ // const bucketName = 'your-unique-bucket-name';
+
+ // Imports the Google Cloud client library
+ const {Storage} = require('@google-cloud/storage');
+
+ // Creates a client
+ const storage = new Storage();
+
+ async function viewBucketIamMembers() {
+ try {
+ // For more information please read:
+ // https://cloud.google.com/storage/docs/access-control/iam
+ const results = await storage
+ .bucket(bucketName)
+ .iam.getPolicy({requestedPolicyVersion: 3});
+
+ const bindings = results[0].bindings;
+
+ console.log(`Bindings for bucket ${bucketName}:`);
+ for (const binding of bindings) {
+ console.log(` Role: ${binding.role}`);
+ console.log(' Members:');
+
+ const members = binding.members;
+ for (const member of members) {
+ console.log(` ${member}`);
+ }
+
+ const condition = binding.condition;
+ if (condition) {
+ console.log(' Condition:');
+ console.log(` Title: ${condition.title}`);
+ console.log(` Description: ${condition.description}`);
+ console.log(` Expression: ${condition.expression}`);
+ }
+ }
+ } catch (error) {
+ console.error(
+ 'Error executing view bucket iam members:',
+ error.message || error
+ );
+ }
+ }
+
+ viewBucketIamMembers();
+ // [END storage_view_bucket_iam_members]
+}
+main(...process.argv.slice(2));