diff --git a/storage-control/deleteFolderRecursive.js b/storage-control/deleteFolderRecursive.js new file mode 100644 index 00000000000..8482a655028 --- /dev/null +++ b/storage-control/deleteFolderRecursive.js @@ -0,0 +1,96 @@ +// Copyright 2026 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 +// +// https://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, folderName) { + // [START storage_control_delete_folder_recursive] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // The name of your GCS bucket + // const bucketName = 'bucketName'; + + // The name of the folder to be deleted recursively + // const folderName = 'folderName'; + + // Imports the Control library + const {StorageControlClient} = require('@google-cloud/storage-control').v2; + + // Instantiates a client + const controlClient = new StorageControlClient(); + + if ( + controlClient.auth && + typeof controlClient.auth.getClient === 'function' + ) { + const originalGetClient = controlClient.auth.getClient.bind( + controlClient.auth + ); + controlClient.auth.getClient = async (...args) => { + const client = await originalGetClient(...args); + if (client) { + client.quotaProjectId = undefined; + } + return client; + }; + } + + async function callDeleteFolderRecursive() { + const folderPath = controlClient.folderPath('_', bucketName, folderName); + + // Create the request + const request = { + name: folderPath, + }; + + // Run request + console.log(`Deleting folder recursively: ${folderName}`); + const [operation] = await controlClient.deleteFolderRecursive(request); + + let op = operation.latestResponse; + while (!op.done) { + await new Promise(resolve => setTimeout(resolve, 1000)); + const [latestOp] = await controlClient.operationsClient.getOperation( + {name: op.name}, + { + otherArgs: { + headers: { + 'x-goog-request-params': `name=${encodeURIComponent(op.name)}`, + }, + }, + } + ); + op = latestOp; + } + + if (op.error) { + throw new Error( + `Failed to delete folder recursively: ${op.error.message}` + ); + } + + console.log(`Deleted folder: ${folderName}.`); + } + + callDeleteFolderRecursive(); + // [END storage_control_delete_folder_recursive] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storage-control/package.json b/storage-control/package.json index cfe14cd0ad5..ded13eef84a 100644 --- a/storage-control/package.json +++ b/storage-control/package.json @@ -13,7 +13,7 @@ "license": "Apache-2.0", "devDependencies": { "@google-cloud/storage": "^7.17.0", - "@google-cloud/storage-control": "^0.5.0", + "@google-cloud/storage-control": "^0.10.0", "c8": "^10.0.0", "chai": "^4.5.0", "mocha": "^10.7.0", diff --git a/storage-control/system-test/folders.test.js b/storage-control/system-test/folders.test.js index 95990152de2..4fb3611ab89 100644 --- a/storage-control/system-test/folders.test.js +++ b/storage-control/system-test/folders.test.js @@ -76,4 +76,20 @@ describe('Folders', () => { assert.match(output, /Deleted folder:/); assert.match(output, new RegExp(folderName)); }); + + it('should delete a folder recursively', async () => { + const parentFolder = uuid.v4(); + const childFolder = `${parentFolder}/${uuid.v4()}`; + + // Create parent folder + execSync(`node createFolder.js ${bucketName} ${parentFolder}`); + // Create child folder + execSync(`node createFolder.js ${bucketName} ${childFolder}`); + + const output = execSync( + `node deleteFolderRecursive.js ${bucketName} ${parentFolder}` + ); + assert.match(output, /Deleted folder:/); + assert.match(output, new RegExp(parentFolder)); + }); });