Skip to content

Commit bfc5594

Browse files
authored
Merge branch 'main' into chore/update-document-warehouse-deps
2 parents a7c7558 + b2feb4b commit bfc5594

14 files changed

Lines changed: 559 additions & 17 deletions

File tree

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ webrisk @GoogleCloudPlatform/nodejs-samples-reviewers @GoogleCloudPlatform/cloud
3232
# SDK teams
3333
cloud-sql @GoogleCloudPlatform/cloud-sql-connectors @GoogleCloudPlatform/nodejs-samples-reviewers @GoogleCloudPlatform/cloud-samples-reviewers
3434
datastore @GoogleCloudPlatform/cloud-native-db-dpes @GoogleCloudPlatform/nodejs-samples-reviewers @GoogleCloudPlatform/cloud-samples-reviewers
35+
storage @GoogleCloudPlatform/gcs-sdk-team @GoogleCloudPlatform/nodejs-samples-reviewers @GoogleCloudPlatform/cloud-samples-reviewers
3536
storagetransfer @GoogleCloudPlatform/gcs-sdk-team @GoogleCloudPlatform/nodejs-samples-reviewers @GoogleCloudPlatform/cloud-samples-reviewers
3637

3738
# One-offs

cloudbuild/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99
"author": "Google Inc.",
1010
"repository": "googleapis/nodejs-cloudbuild",
1111
"engines": {
12-
"node": ">=16.0.0"
12+
"node": ">=20.0.0"
1313
},
1414
"scripts": {
1515
"test": "c8 mocha -p -j 2 system-test --timeout=800000"
1616
},
1717
"dependencies": {
18-
"@google-cloud/cloudbuild": "^4.0.0"
18+
"@google-cloud/cloudbuild": "^5.0.0"
1919
},
2020
"devDependencies": {
21-
"c8": "^10.0.0",
22-
"chai": "^4.5.0",
21+
"c8": "^12.0.0",
22+
"chai": "^6.0.0",
2323
"mocha": "^10.0.0"
2424
}
2525
}

endpoints/getting-started-grpc/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@
1010
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
1111
},
1212
"engines": {
13-
"node": ">=16.0.0"
13+
"node": ">=20.0.0"
1414
},
1515
"scripts": {
1616
"start": "node server.js",
1717
"test": "mocha --exit system-test/*.test.js --timeout=60000"
1818
},
1919
"dependencies": {
20-
"@grpc/grpc-js": "^1.13.3",
21-
"@grpc/proto-loader": "^0.7.15",
20+
"@grpc/grpc-js": "^1.14.0",
21+
"@grpc/proto-loader": "^0.8.1",
2222
"yargs": "^17.0.0"
2323
},
2424
"devDependencies": {
25-
"chai": "^4.5.0",
25+
"chai": "^6.0.0",
2626
"mocha": "^10.0.0",
2727
"wait-port": "^1.0.4"
2828
}

endpoints/getting-started/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
1111
},
1212
"engines": {
13-
"node": ">=16.0.0"
13+
"node": ">=20.0.0"
1414
},
1515
"scripts": {
1616
"start": "node app.js",
1717
"test": "c8 mocha -p -j 2 -- test/*.test.js --timeout=20000"
1818
},
1919
"dependencies": {
20-
"express": "^4.16.4"
20+
"express": "^5.0.0"
2121
},
2222
"devDependencies": {
23-
"c8": "^10.0.0",
23+
"c8": "^12.0.0",
2424
"mocha": "^10.0.0",
2525
"proxyquire": "^2.1.0",
2626
"sinon": "^18.0.0",

error-reporting/package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99
"!test/"
1010
],
1111
"engines": {
12-
"node": ">=16.0.0"
12+
"node": ">=20.0.0"
1313
},
1414
"scripts": {
1515
"test": "c8 mocha -p -j 2 --timeout=600000"
1616
},
1717
"dependencies": {
18-
"@google-cloud/error-reporting": "^3.0.4",
19-
"express": "^4.16.3"
18+
"@google-cloud/error-reporting": "^4.0.0",
19+
"express": "^5.0.0"
2020
},
2121
"devDependencies": {
22-
"c8": "^10.0.0",
23-
"chai": "^4.5.0",
24-
"gaxios": "^6.0.0",
22+
"c8": "^12.0.0",
23+
"chai": "^6.0.0",
24+
"gaxios": "^7.0.0",
2525
"mocha": "^10.0.0"
2626
}
2727
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
function main(bucketName, folderName) {
18+
// [START storage_control_delete_folder_recursive]
19+
/**
20+
* TODO(developer): Uncomment these variables before running the sample.
21+
*/
22+
23+
// The name of your GCS bucket
24+
// const bucketName = 'bucketName';
25+
26+
// The name of the folder to be deleted recursively
27+
// const folderName = 'folderName';
28+
29+
// Imports the Control library
30+
const {StorageControlClient} = require('@google-cloud/storage-control').v2;
31+
32+
// Instantiates a client
33+
const controlClient = new StorageControlClient();
34+
35+
if (
36+
controlClient.auth &&
37+
typeof controlClient.auth.getClient === 'function'
38+
) {
39+
const originalGetClient = controlClient.auth.getClient.bind(
40+
controlClient.auth
41+
);
42+
controlClient.auth.getClient = async (...args) => {
43+
const client = await originalGetClient(...args);
44+
if (client) {
45+
client.quotaProjectId = undefined;
46+
}
47+
return client;
48+
};
49+
}
50+
51+
async function callDeleteFolderRecursive() {
52+
const folderPath = controlClient.folderPath('_', bucketName, folderName);
53+
54+
// Create the request
55+
const request = {
56+
name: folderPath,
57+
};
58+
59+
// Run request
60+
console.log(`Deleting folder recursively: ${folderName}`);
61+
const [operation] = await controlClient.deleteFolderRecursive(request);
62+
63+
let op = operation.latestResponse;
64+
while (!op.done) {
65+
await new Promise(resolve => setTimeout(resolve, 1000));
66+
const [latestOp] = await controlClient.operationsClient.getOperation(
67+
{name: op.name},
68+
{
69+
otherArgs: {
70+
headers: {
71+
'x-goog-request-params': `name=${encodeURIComponent(op.name)}`,
72+
},
73+
},
74+
}
75+
);
76+
op = latestOp;
77+
}
78+
79+
if (op.error) {
80+
throw new Error(
81+
`Failed to delete folder recursively: ${op.error.message}`
82+
);
83+
}
84+
85+
console.log(`Deleted folder: ${folderName}.`);
86+
}
87+
88+
callDeleteFolderRecursive();
89+
// [END storage_control_delete_folder_recursive]
90+
}
91+
92+
process.on('unhandledRejection', err => {
93+
console.error(err.message);
94+
process.exitCode = 1;
95+
});
96+
main(...process.argv.slice(2));

storage-control/system-test/folders.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,20 @@ describe('Folders', () => {
7676
assert.match(output, /Deleted folder:/);
7777
assert.match(output, new RegExp(folderName));
7878
});
79+
80+
it('should delete a folder recursively', async () => {
81+
const parentFolder = uuid.v4();
82+
const childFolder = `${parentFolder}/${uuid.v4()}`;
83+
84+
// Create parent folder
85+
execSync(`node createFolder.js ${bucketName} ${parentFolder}`);
86+
// Create child folder
87+
execSync(`node createFolder.js ${bucketName} ${childFolder}`);
88+
89+
const output = execSync(
90+
`node deleteFolderRecursive.js ${bucketName} ${parentFolder}`
91+
);
92+
assert.match(output, /Deleted folder:/);
93+
assert.match(output, new RegExp(parentFolder));
94+
});
7995
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
function main(bucketName = 'my-bucket', filterMode = 'Enabled') {
18+
// [START storage_create_bucket_ip_filtering]
19+
/**
20+
* TODO(developer): Uncomment the following lines before running the sample.
21+
*/
22+
// The ID of your GCS bucket
23+
// const bucketName = 'your-unique-bucket-name';
24+
25+
// Toggle data filtering (e.g., 'Enabled' | 'Disabled')
26+
// const filterMode = 'Enabled';
27+
28+
// Imports the Google Cloud client library
29+
const {Storage} = require('@google-cloud/storage');
30+
31+
// Creates a client
32+
const storage = new Storage();
33+
34+
async function createBucketWithIpFilter() {
35+
const ipFilter = {
36+
mode: filterMode,
37+
publicNetworkSource: {
38+
allowedIpCidrRanges: ['8.8.8.8/32'],
39+
},
40+
allowCrossOrgVpcs: false,
41+
allowAllServiceAgentAccess: false,
42+
};
43+
44+
const [bucket] = await storage.createBucket(bucketName, {
45+
ipFilter: ipFilter,
46+
});
47+
48+
console.log(
49+
`Bucket ${bucket.name} created with IP filter mode ${bucket.metadata.ipFilter.mode}.`
50+
);
51+
}
52+
53+
createBucketWithIpFilter().catch(console.error);
54+
// [END storage_create_bucket_ip_filtering]
55+
}
56+
57+
main(...process.argv.slice(2));
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
'use strict';
16+
17+
function main(bucketName = 'my-bucket', cidrToDelete = '8.8.8.8/32') {
18+
// [START storage_delete_ip_filtering_rules]
19+
/**
20+
* TODO(developer): Uncomment the following lines before running the sample.
21+
*/
22+
// The ID of your GCS bucket
23+
// const bucketName = 'your-unique-bucket-name';
24+
25+
// Target IP address/CIDR block to remove
26+
// const cidrToDelete = '8.8.8.8/32';
27+
28+
// Imports the Google Cloud client library
29+
const {Storage} = require('@google-cloud/storage');
30+
31+
// Creates a client
32+
const storage = new Storage();
33+
34+
async function deleteBucketIpFilterRules() {
35+
// Note: To delete specific rules, you fetch the existing config, filter out the rules, and update.
36+
const [metadata] = await storage.bucket(bucketName).getMetadata();
37+
38+
if (!metadata.ipFilter || !metadata.ipFilter.publicNetworkSource) {
39+
console.log(
40+
`No IP Filter public network configuration found for bucket ${bucketName}.`
41+
);
42+
return;
43+
}
44+
45+
const currentIpRanges =
46+
metadata.ipFilter.publicNetworkSource.allowedIpCidrRanges || [];
47+
if (!currentIpRanges.includes(cidrToDelete)) {
48+
console.log(
49+
`CIDR range ${cidrToDelete} not found in bucket ${bucketName}. No changes made.`
50+
);
51+
return;
52+
}
53+
54+
const updatedIpRanges = currentIpRanges.filter(
55+
range => range !== cidrToDelete
56+
);
57+
58+
const updatedIpFilter = {
59+
...metadata.ipFilter,
60+
publicNetworkSource: {
61+
...metadata.ipFilter.publicNetworkSource,
62+
allowedIpCidrRanges: updatedIpRanges,
63+
},
64+
};
65+
66+
const [updatedMetadata] = await storage.bucket(bucketName).setMetadata({
67+
ipFilter: updatedIpFilter,
68+
});
69+
70+
console.log(`Specific IP Filter rules deleted for bucket ${bucketName}.`);
71+
console.log(JSON.stringify(updatedMetadata.ipFilter, null, 2));
72+
}
73+
74+
deleteBucketIpFilterRules().catch(console.error);
75+
// [END storage_delete_ip_filtering_rules]
76+
}
77+
78+
main(...process.argv.slice(2));

0 commit comments

Comments
 (0)