From dfad2cfb73c1d0354134833cce903a3bde2266a9 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 11 Sep 2025 06:49:15 +0000 Subject: [PATCH 01/39] feat: add storage batch operations samples --- storagebatchoperations/cancelJob.js | 69 ++++++++++++++++++++++ storagebatchoperations/createJob.js | 87 ++++++++++++++++++++++++++++ storagebatchoperations/deleteJob.js | 64 ++++++++++++++++++++ storagebatchoperations/getJob.js | 64 ++++++++++++++++++++ storagebatchoperations/listJobs.js | 63 ++++++++++++++++++++ storagebatchoperations/package.json | 23 ++++++++ storagebatchoperations/quickstart.js | 63 ++++++++++++++++++++ 7 files changed, 433 insertions(+) create mode 100644 storagebatchoperations/cancelJob.js create mode 100644 storagebatchoperations/createJob.js create mode 100644 storagebatchoperations/deleteJob.js create mode 100644 storagebatchoperations/getJob.js create mode 100644 storagebatchoperations/listJobs.js create mode 100644 storagebatchoperations/package.json create mode 100644 storagebatchoperations/quickstart.js diff --git a/storagebatchoperations/cancelJob.js b/storagebatchoperations/cancelJob.js new file mode 100644 index 00000000000..39fa4d8b023 --- /dev/null +++ b/storagebatchoperations/cancelJob.js @@ -0,0 +1,69 @@ +// 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 +// +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +function main(projectId, jobId) { + // [START storage_batch_cancel_job] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // A unique identifier for this job. + // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; + + // Imports the Control library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + // Instantiates a client + const client = new StorageBatchOperationsClient(); + + async function cancelJob() { + const name = client.jobPath(projectId, 'global', jobId); + + // Create the request + const request = { + name, + }; + + // Run request + try { + await client.cancelJob(request); + console.log(`Cancelled job: ${name}`); + } catch (err) { + // This might be expected if the job completed quickly or failed creation + console.log(`INFO: cancelJob threw: ${err.message}`); + } + } + + cancelJob().catch(console.error); + // [END storage_batch_cancel_job] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storagebatchoperations/createJob.js b/storagebatchoperations/createJob.js new file mode 100644 index 00000000000..1c29cda0135 --- /dev/null +++ b/storagebatchoperations/createJob.js @@ -0,0 +1,87 @@ +// 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 +// +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +function main(projectId, jobId, bucketName, objectPrefix) { + // [START storage_batch_create_job] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // The name of your GCS bucket + // const bucketName = 'bucketName'; + + // A unique identifier for this job. + // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; + + // The prefix of objects to include in the operation. + // const objectPrefix = 'prefix1'; + + // Imports the Control library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + // Instantiates a client + const client = new StorageBatchOperationsClient(); + + async function createJob() { + const parent = await client.locationPath(projectId, 'global'); + + // Create the request + const request = { + parent, + jobId, + job: { + bucketList: { + buckets: [ + { + bucket: bucketName, + prefixList: { + includedObjectPrefixes: [objectPrefix], + }, + }, + ], + }, + deleteObject: { + permanentObjectDeletionEnabled: false, + }, + }, + }; + + // Run request + const [operation] = await client.createJob(request); + const [response] = await operation.promise(); + console.log(`Created job: ${response.name}`); + } + + createJob(); + // [END storage_batch_create_job] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storagebatchoperations/deleteJob.js b/storagebatchoperations/deleteJob.js new file mode 100644 index 00000000000..b452b2634b9 --- /dev/null +++ b/storagebatchoperations/deleteJob.js @@ -0,0 +1,64 @@ +// 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 +// +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +function main(projectId, jobId) { + // [START storage_batch_delete_job] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // A unique identifier for this job. + // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; + + // Imports the Control library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + // Instantiates a client + const client = new StorageBatchOperationsClient(); + + async function deleteJob() { + const name = client.jobPath(projectId, 'global', jobId); + + // Create the request + const request = { + name, + }; + + // Run request + await client.deleteJob(request); + console.log(`Deleted job: ${name}`); + } + + deleteJob(); + // [END storage_batch_delete_job] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storagebatchoperations/getJob.js b/storagebatchoperations/getJob.js new file mode 100644 index 00000000000..dbe4948c981 --- /dev/null +++ b/storagebatchoperations/getJob.js @@ -0,0 +1,64 @@ +// 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 +// +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +function main(projectId, jobId) { + // [START storage_batch_get_job] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // A unique identifier for this job. + // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; + + // Imports the Control library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + // Instantiates a client + const client = new StorageBatchOperationsClient(); + + async function getJob() { + const name = client.jobPath(projectId, 'global', jobId); + + // Create the request + const request = { + name, + }; + + // Run request + const [response] = await client.getJob(request); + console.log(`Got job: ${response.name}`); + } + + getJob(); + // [END storage_batch_get_job] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storagebatchoperations/listJobs.js b/storagebatchoperations/listJobs.js new file mode 100644 index 00000000000..4e79d1b822f --- /dev/null +++ b/storagebatchoperations/listJobs.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 +// +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +function main(projectId) { + // [START storage_batch_list_jobs] + /** + * TODO(developer): Uncomment these variables before running the sample. + */ + + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // Imports the Control library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + // Instantiates a client + const client = new StorageBatchOperationsClient(); + + async function listJobs() { + const parent = await client.locationPath(projectId, 'global'); + + // Create the request + const request = { + parent, + }; + + // Run request + const [response] = await client.listJobs(request); + for (const jobs of response) { + console.log(jobs.name); + } + } + + listJobs(); + // [END storage_batch_list_jobs] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/storagebatchoperations/package.json b/storagebatchoperations/package.json new file mode 100644 index 00000000000..867abcb1d34 --- /dev/null +++ b/storagebatchoperations/package.json @@ -0,0 +1,23 @@ +{ + "name": "storage-batch-operations-samples", + "version": "0.0.1", + "author": "Google Inc.", + "license": "Apache-2.0", + "description": "Examples of how to utilize the @google-cloud/storagebatchoperations library.", + "scripts": { + "test": "c8 mocha -p -j 2 system-test --timeout 600000" + }, + "repository": { + "type": "git", + "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" + }, + "devDependencies": { + "@google-cloud/storage": "^7.17.1", + "@google-cloud/storagebatchoperations": "^0.1.0", + "c8": "^10.0.0", + "chai": "^4.5.0", + "mocha": "^10.7.0", + "uuid": "^10.0.0" + } + } + \ No newline at end of file diff --git a/storagebatchoperations/quickstart.js b/storagebatchoperations/quickstart.js new file mode 100644 index 00000000000..9d5e9302e34 --- /dev/null +++ b/storagebatchoperations/quickstart.js @@ -0,0 +1,63 @@ +// 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'; + +/** + * This application demonstrates how to perform basic operations on an Batch Operations + * instance with the Google Cloud Storage API. + * + * For more information, see the documentation at https://cloud.google.com/storage/docs/batch-operations/overview. + */ + +async function main(projectId, jobId) { + // [START storage_batch_quickstart] + + // Imports the Google Cloud client library + const {StorageBatchOperationsClient} = + require('@google-cloud/storagebatchoperations').v1; + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // Your Google Cloud project ID. + // const projectId = 'my-project-id'; + + // A unique identifier for this job. + // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; + + // Creates a client + const client = new StorageBatchOperationsClient(); + + async function quickstart() { + const name = client.jobPath(projectId, 'global', jobId); + + // Create the request + const request = { + name, + }; + + // Run request + const [response] = await client.getJob(request); + console.log(`Got job: ${response.name}`); + } + quickstart(); + // [END storage_batch_quickstart] +} + +main(...process.argv.slice(2)); + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); From 8b9d2a27183d2e18554c5296446846ac7e7871a5 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Thu, 11 Sep 2025 06:57:38 +0000 Subject: [PATCH 02/39] bug fix --- storagebatchoperations/quickstart.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storagebatchoperations/quickstart.js b/storagebatchoperations/quickstart.js index 9d5e9302e34..7fd6e42a0d7 100644 --- a/storagebatchoperations/quickstart.js +++ b/storagebatchoperations/quickstart.js @@ -1,3 +1,5 @@ +// 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 @@ -9,7 +11,6 @@ // 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'; From 3ea4225065d41edc3f942aaf9749734e506a2646 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 12 Sep 2025 07:16:57 +0000 Subject: [PATCH 03/39] added test case --- storagebatchoperations/listJobs.js | 4 +- .../storagebatchoperations.test.js | 87 +++++++++++++++++++ 2 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 storagebatchoperations/system-test/storagebatchoperations.test.js diff --git a/storagebatchoperations/listJobs.js b/storagebatchoperations/listJobs.js index 4e79d1b822f..fd872665857 100644 --- a/storagebatchoperations/listJobs.js +++ b/storagebatchoperations/listJobs.js @@ -47,8 +47,8 @@ function main(projectId) { // Run request const [response] = await client.listJobs(request); - for (const jobs of response) { - console.log(jobs.name); + for (const job of response) { + console.log(job.name); } } diff --git a/storagebatchoperations/system-test/storagebatchoperations.test.js b/storagebatchoperations/system-test/storagebatchoperations.test.js new file mode 100644 index 00000000000..42113a02862 --- /dev/null +++ b/storagebatchoperations/system-test/storagebatchoperations.test.js @@ -0,0 +1,87 @@ +// 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 +// +// 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. + +const {Storage, Bucket} = require('@google-cloud/storage'); +const cp = require('child_process'); +const {assert} = require('chai'); +const {describe, it, before, after} = require('mocha'); +const uuid = require('uuid'); + +const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); +const projectId = process.env.GCLOUD_PROJECT; +const bucketPrefix = 'sbo-samples'; +const bucketName = `${bucketPrefix}-${uuid.v4()}`; +const storage = new Storage(); +const bucket = new Bucket(storage, bucketName); +const jobId = uuid.v4(); +const jobName = `projects/${projectId}/locations/global/jobs/${jobId}`; + +describe('Batch Operations', () => { + before(async () => { + await storage.createBucket(bucketName, { + iamConfiguration: { + uniformBucketLevelAccess: { + enabled: true, + }, + }, + hierarchicalNamespace: {enabled: true}, + }); + }); + + after(async () => { + await bucket.delete(); + }); + + it('should create a job', async () => { + const output = execSync( + `node createJob.js ${projectId} ${jobId} ${bucketName} objectPrefix` + ); + assert.match(output, /Created job:/); + assert.match(output, new RegExp(jobName)); + }); + + it('should list jobs', async () => { + const output = execSync(`node listJobs.js ${projectId}`); + assert.match(output, new RegExp(jobName)); + }); + + it('should run quickstart', async () => { + const output = execSync(`node quickstart.js ${projectId} ${jobId}`); + assert.match(output, /Got job:/); + assert.match(output, new RegExp(jobName)); + }); + + it('should get a job', async () => { + const output = execSync(`node getJob.js ${projectId} ${jobId}`); + assert.match(output, /Got job:/); + assert.match(output, new RegExp(jobName)); + }); + + it('should cancel a job', async () => { + try { + const output = execSync(`node cancelJob.js ${projectId} ${jobId}`); + assert.match(output, /Cancelled job:/); + assert.match(output, new RegExp(jobName)); + } catch (error) { + // This might be expected if the job completed quickly or failed creation + assert.match(error.message, /INFO: cancelJob threw: /); + } + }); + + it('should delete a job', async () => { + const output = execSync(`node deleteJob.js ${projectId} ${jobId}`); + assert.match(output, /Deleted job:/); + assert.match(output, new RegExp(jobName)); + }); +}); From 7b85f347eda195ce7d126f5b2303d8649cf25e4c Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 12 Sep 2025 07:28:54 +0000 Subject: [PATCH 04/39] lint fix --- storagebatchoperations/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/storagebatchoperations/package.json b/storagebatchoperations/package.json index 867abcb1d34..e382054dda5 100644 --- a/storagebatchoperations/package.json +++ b/storagebatchoperations/package.json @@ -20,4 +20,3 @@ "uuid": "^10.0.0" } } - \ No newline at end of file From 7dceecc7a2802d08101fd7f79d367484fddde5e7 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 17 Oct 2025 12:27:40 +0000 Subject: [PATCH 05/39] feat(storage-batch): Improve Batch Operation API samples (Documentation & Error Handling) Improve the robustness and clarity of the Storage Batch Operations API samples: * **Error Handling:** Wraps all asynchronous Batch Operations API samples (Create, Get, List, Cancel) in `try...catch` blocks for production readiness. * **Specific Diagnostics:** Adds specific gRPC error code checks (`NOT_FOUND`, `FAILED_PRECONDITION`) within the `catch` blocks to provide detailed diagnostic feedback to users regarding job state or non-existence. * **Documentation:** Clarifies JSDoc for all function parameters (e.g., `projectId`, `jobId`, `objectPrefix`), ensuring examples and types are clear for developers. --- storagebatchoperations/cancelJob.js | 40 ++++++++++++----- storagebatchoperations/createJob.js | 40 +++++++++-------- storagebatchoperations/deleteJob.js | 37 +++++++++++----- storagebatchoperations/getJob.js | 43 ++++++++++++++----- storagebatchoperations/listJobs.js | 36 ++++++++++++---- storagebatchoperations/quickstart.js | 42 ++++++++++++++---- .../storagebatchoperations.test.js | 22 +++++++--- 7 files changed, 191 insertions(+), 69 deletions(-) diff --git a/storagebatchoperations/cancelJob.js b/storagebatchoperations/cancelJob.js index 39fa4d8b023..7e739fc0765 100644 --- a/storagebatchoperations/cancelJob.js +++ b/storagebatchoperations/cancelJob.js @@ -23,16 +23,19 @@ function main(projectId, jobId) { // [START storage_batch_cancel_job] + /** - * TODO(developer): Uncomment these variables before running the sample. + * Cancel a batch job instance. + * + * The operation to cancel a batch job instance in Google Cloud Storage (GCS) is used to stop + * a running or queued asynchronous task that is currently processing a large number of GCS objects. + * + * @param {string} projectId The Google Cloud project ID. + * Example: 'my-project-id' + * @param {string} jobId A unique identifier for this job. + * Example: '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - - // A unique identifier for this job. - // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; - // Imports the Control library const {StorageBatchOperationsClient} = require('@google-cloud/storagebatchoperations').v1; @@ -52,13 +55,30 @@ function main(projectId, jobId) { try { await client.cancelJob(request); console.log(`Cancelled job: ${name}`); - } catch (err) { + } catch (error) { // This might be expected if the job completed quickly or failed creation - console.log(`INFO: cancelJob threw: ${err.message}`); + console.error( + `Error canceling batch jobs for jobId ${jobId}:`, + error.message + ); + + if (error.code === 5) { + // NOT_FOUND (gRPC code 5) error can occur if the batch job does not exist. + console.error( + `Ensure the job '${jobId}' exists in project '${projectId}'.` + ); + } else if (error.code === 9) { + // FAILED_PRECONDITION (gRPC code 9) can occur if the job is already being cancelled + // or is not in a RUNNING state that allows the cancel operation. + console.error( + `Batch job '${jobId}' may not be in a state that allows canceling (e.g., must be RUNNING).` + ); + } + throw error; } } - cancelJob().catch(console.error); + cancelJob(); // [END storage_batch_cancel_job] } diff --git a/storagebatchoperations/createJob.js b/storagebatchoperations/createJob.js index 1c29cda0135..0f6eba41348 100644 --- a/storagebatchoperations/createJob.js +++ b/storagebatchoperations/createJob.js @@ -23,22 +23,20 @@ function main(projectId, jobId, bucketName, objectPrefix) { // [START storage_batch_create_job] + /** - * TODO(developer): Uncomment these variables before running the sample. + * Create a new batch job instance. + * + * @param {string} projectId Your Google Cloud project ID. + * Example: 'my-project-id' + * @param {string} bucketName The name of your GCS bucket. + * Example: 'your-gcp-bucket-name' + * @param {string} jobId A unique identifier for this job. + * Example: '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5' + * @param {string} objectPrefix The prefix of objects to include in the operation. + * Example: 'prefix1' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - - // The name of your GCS bucket - // const bucketName = 'bucketName'; - - // A unique identifier for this job. - // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; - - // The prefix of objects to include in the operation. - // const objectPrefix = 'prefix1'; - // Imports the Control library const {StorageBatchOperationsClient} = require('@google-cloud/storagebatchoperations').v1; @@ -70,10 +68,18 @@ function main(projectId, jobId, bucketName, objectPrefix) { }, }; - // Run request - const [operation] = await client.createJob(request); - const [response] = await operation.promise(); - console.log(`Created job: ${response.name}`); + try { + // Run the request, which returns an Operation object + const [operation] = await client.createJob(request); + console.log(`Waiting for operation ${operation.name} to complete...`); + + // Wait for the operation to complete and get the final resource + const [response] = await operation.promise(); + console.log(`Created job: ${response.name}`); + } catch (error) { + console.error('Failed to create batch job:', error.message); + throw error; + } } createJob(); diff --git a/storagebatchoperations/deleteJob.js b/storagebatchoperations/deleteJob.js index b452b2634b9..0934a2311fb 100644 --- a/storagebatchoperations/deleteJob.js +++ b/storagebatchoperations/deleteJob.js @@ -24,15 +24,17 @@ function main(projectId, jobId) { // [START storage_batch_delete_job] /** - * TODO(developer): Uncomment these variables before running the sample. + * Delete a batch job instance. + * + * This operation is used to remove a completed, failed, or cancelled Batch Operation + * job from the system's list. It is essentially a cleanup action. + * + * @param {string} projectId Your Google Cloud project ID. + * Example: 'my-project-id' + * @param {string} jobId A unique identifier for this job. + * Example: '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - - // A unique identifier for this job. - // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; - // Imports the Control library const {StorageBatchOperationsClient} = require('@google-cloud/storagebatchoperations').v1; @@ -48,9 +50,24 @@ function main(projectId, jobId) { name, }; - // Run request - await client.deleteJob(request); - console.log(`Deleted job: ${name}`); + try { + // Run request + await client.deleteJob(request); + console.log(`Deleted job: ${name}`); + } catch (error) { + console.error( + `Error deleting batch jobs for jobId ${jobId}:`, + error.message + ); + + if (error.code === 5) { + // NOT_FOUND (gRPC code 5) error can occur if the batch job does not exist. + console.error( + `Ensure the job '${jobId}' exists in project '${projectId}'.` + ); + } + throw error; + } } deleteJob(); diff --git a/storagebatchoperations/getJob.js b/storagebatchoperations/getJob.js index dbe4948c981..f7478f1d128 100644 --- a/storagebatchoperations/getJob.js +++ b/storagebatchoperations/getJob.js @@ -24,15 +24,18 @@ function main(projectId, jobId) { // [START storage_batch_get_job] /** - * TODO(developer): Uncomment these variables before running the sample. + * Retrieves details of a specific batch job instance. + * + * This operation is used to retrieve the detailed current state, execution status, + * and original configuration of a specific Batch Operation job that was previously + * created for a Google Cloud Storage bucket. + * + * @param {string} projectId Your Google Cloud project ID. + * Example: 'my-project-id' + * @param {string} jobId A unique identifier for this job. + * Example: '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - - // A unique identifier for this job. - // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; - // Imports the Control library const {StorageBatchOperationsClient} = require('@google-cloud/storagebatchoperations').v1; @@ -48,9 +51,29 @@ function main(projectId, jobId) { name, }; - // Run request - const [response] = await client.getJob(request); - console.log(`Got job: ${response.name}`); + try { + // Run request + const [response] = await client.getJob(request); + console.log(`Batch job details for '${jobId}':`); + console.log(` Name: ${response.name}`); + console.log(` State: ${response.state}`); + console.log( + ` Create Time: ${new Date(response.createTime.seconds * 1000).toISOString()}` + ); + } catch (error) { + console.error( + `Error retrieving batch jobs for jobId ${jobId}:`, + error.message + ); + + if (error.code === 5) { + // NOT_FOUND (gRPC code 5) error can occur if the batch job does not exist. + console.error( + `Ensure the job '${jobId}' exists in project '${projectId}'.` + ); + } + throw error; + } } getJob(); diff --git a/storagebatchoperations/listJobs.js b/storagebatchoperations/listJobs.js index fd872665857..a72dbd4878e 100644 --- a/storagebatchoperations/listJobs.js +++ b/storagebatchoperations/listJobs.js @@ -24,12 +24,16 @@ function main(projectId) { // [START storage_batch_list_jobs] /** - * TODO(developer): Uncomment these variables before running the sample. + * Lists all Jobs operation is used to query the status and configuration of all + * Storage Batch Operations jobs within a specific Google Cloud project. + * This feature is essential for tasks that affect a large number of objects, + * such as changing storage classes, deleting objects, or running custom functions + * on object metadata. + * + * @param {string} projectId Your Google Cloud project ID. + * Example: 'my-project-id' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - // Imports the Control library const {StorageBatchOperationsClient} = require('@google-cloud/storagebatchoperations').v1; @@ -45,10 +49,26 @@ function main(projectId) { parent, }; - // Run request - const [response] = await client.listJobs(request); - for (const job of response) { - console.log(job.name); + try { + // Run request. The response is an array where the first element is the list of jobs. + const [response] = await client.listJobs(request); + if (response && response.length > 0) { + console.log( + `Found ${response.length} batch jobs for project: ${projectId}` + ); + for (const job of response) { + console.log(job.name); + } + } else { + // Case: Successful but empty list (No batch jobs found) + console.log(`No batch jobs found for project: ${projectId}.`); + } + } catch (error) { + console.error( + `Error listing batch jobs for project ${projectId}:`, + error.message + ); + throw error; } } diff --git a/storagebatchoperations/quickstart.js b/storagebatchoperations/quickstart.js index 7fd6e42a0d7..4a022041e19 100644 --- a/storagebatchoperations/quickstart.js +++ b/storagebatchoperations/quickstart.js @@ -29,13 +29,17 @@ async function main(projectId, jobId) { require('@google-cloud/storagebatchoperations').v1; /** - * TODO(developer): Uncomment the following lines before running the sample. + * Retrieves details of a specific batch job instance. + * + * This operation is used to retrieve the detailed current state, execution status, + * and original configuration of a specific Batch Operation job that was previously + * created for a Google Cloud Storage bucket. + * + * @param {string} projectId Your Google Cloud project ID. + * Example: 'my-project-id' + * @param {string} jobId A unique identifier for this job. + * Example: '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5' */ - // Your Google Cloud project ID. - // const projectId = 'my-project-id'; - - // A unique identifier for this job. - // const jobId = '94d60cc1-2d95-41c5-b6e3-ff66cd3532d5'; // Creates a client const client = new StorageBatchOperationsClient(); @@ -48,9 +52,29 @@ async function main(projectId, jobId) { name, }; - // Run request - const [response] = await client.getJob(request); - console.log(`Got job: ${response.name}`); + try { + // Run request + const [response] = await client.getJob(request); + console.log(`Batch job details for '${jobId}':`); + console.log(` Name: ${response.name}`); + console.log(` State: ${response.state}`); + console.log( + ` Create Time: ${new Date(response.createTime.seconds * 1000).toISOString()}` + ); + } catch (error) { + console.error( + `Error retrieving batch jobs for jobId ${jobId}:`, + error.message + ); + + if (error.code === 5) { + // NOT_FOUND (gRPC code 5) error can occur if the batch job does not exist. + console.error( + `Ensure the job '${jobId}' exists in project '${projectId}'.` + ); + } + throw error; + } } quickstart(); // [END storage_batch_quickstart] diff --git a/storagebatchoperations/system-test/storagebatchoperations.test.js b/storagebatchoperations/system-test/storagebatchoperations.test.js index 42113a02862..2c05879bc62 100644 --- a/storagebatchoperations/system-test/storagebatchoperations.test.js +++ b/storagebatchoperations/system-test/storagebatchoperations.test.js @@ -22,7 +22,7 @@ const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const projectId = process.env.GCLOUD_PROJECT; const bucketPrefix = 'sbo-samples'; const bucketName = `${bucketPrefix}-${uuid.v4()}`; -const storage = new Storage(); +const storage = new Storage(projectId); const bucket = new Bucket(storage, bucketName); const jobId = uuid.v4(); const jobName = `projects/${projectId}/locations/global/jobs/${jobId}`; @@ -58,24 +58,36 @@ describe('Batch Operations', () => { it('should run quickstart', async () => { const output = execSync(`node quickstart.js ${projectId} ${jobId}`); - assert.match(output, /Got job:/); + const detailsHeader = `Batch job details for '${jobId}':`; + assert.match(output, new RegExp(detailsHeader)); + assert.match(output, /Name:/); assert.match(output, new RegExp(jobName)); + assert.match(output, /State:/); + assert.match(output, /Create Time:/); }); it('should get a job', async () => { const output = execSync(`node getJob.js ${projectId} ${jobId}`); - assert.match(output, /Got job:/); + const detailsHeader = `Batch job details for '${jobId}':`; + assert.match(output, new RegExp(detailsHeader)); + assert.match(output, /Name:/); assert.match(output, new RegExp(jobName)); + assert.match(output, /State:/); + assert.match(output, /Create Time:/); }); - it('should cancel a job', async () => { + it('should cancel a job (or gracefully handle terminal state)', async () => { try { const output = execSync(`node cancelJob.js ${projectId} ${jobId}`); assert.match(output, /Cancelled job:/); assert.match(output, new RegExp(jobName)); } catch (error) { // This might be expected if the job completed quickly or failed creation - assert.match(error.message, /INFO: cancelJob threw: /); + const errorMessage = error.stderr.toString(); + assert.match( + errorMessage, + /9 FAILED_PRECONDITION: Job run.* is in a terminal state and can not be changed./ + ); } }); From a2f6598111ecdc354212cbea4218d0a70e25aa70 Mon Sep 17 00:00:00 2001 From: Thiyagu K Date: Fri, 24 Oct 2025 07:21:14 +0000 Subject: [PATCH 06/39] Incorporated feedback from review comments --- storagebatchoperations/getJob.js | 6 +++--- .../system-test/storagebatchoperations.test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/storagebatchoperations/getJob.js b/storagebatchoperations/getJob.js index f7478f1d128..b81bf7c33cd 100644 --- a/storagebatchoperations/getJob.js +++ b/storagebatchoperations/getJob.js @@ -55,10 +55,10 @@ function main(projectId, jobId) { // Run request const [response] = await client.getJob(request); console.log(`Batch job details for '${jobId}':`); - console.log(` Name: ${response.name}`); - console.log(` State: ${response.state}`); + console.log(`Name: ${response.name}`); + console.log(`State: ${response.state}`); console.log( - ` Create Time: ${new Date(response.createTime.seconds * 1000).toISOString()}` + `Create Time: ${new Date(response.createTime.seconds * 1000).toISOString()}` ); } catch (error) { console.error( diff --git a/storagebatchoperations/system-test/storagebatchoperations.test.js b/storagebatchoperations/system-test/storagebatchoperations.test.js index 2c05879bc62..608240bcc4e 100644 --- a/storagebatchoperations/system-test/storagebatchoperations.test.js +++ b/storagebatchoperations/system-test/storagebatchoperations.test.js @@ -22,7 +22,7 @@ const execSync = cmd => cp.execSync(cmd, {encoding: 'utf-8'}); const projectId = process.env.GCLOUD_PROJECT; const bucketPrefix = 'sbo-samples'; const bucketName = `${bucketPrefix}-${uuid.v4()}`; -const storage = new Storage(projectId); +const storage = new Storage({projectId: projectId}); const bucket = new Bucket(storage, bucketName); const jobId = uuid.v4(); const jobName = `projects/${projectId}/locations/global/jobs/${jobId}`; From cf497b12b8bf66c053bfdeb4e48599eed395beba Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 14 Sep 2026 14:55:55 -0600 Subject: [PATCH 07/39] chore(routeoptimization): update dependencies (#4464) --- routeoptimization/snippets/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routeoptimization/snippets/package.json b/routeoptimization/snippets/package.json index 4bfa6f1968a..33916282d43 100644 --- a/routeoptimization/snippets/package.json +++ b/routeoptimization/snippets/package.json @@ -8,17 +8,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@googlemaps/routeoptimization": "^0.1.0" + "@googlemaps/routeoptimization": "^0.7.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0" } } From 073626bbe79e43a303489a3d6d3b22a632c2f4ef Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 14 Sep 2026 15:00:41 -0600 Subject: [PATCH 08/39] chore(secret-manager): update dependencies (#4462) --- secret-manager/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/secret-manager/package.json b/secret-manager/package.json index f7d5bea392c..667e2908117 100644 --- a/secret-manager/package.json +++ b/secret-manager/package.json @@ -8,18 +8,18 @@ "author": "Google LLC", "repository": "googleapis/nodejs-secret-manager", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 --recursive test/ --timeout=800000" }, "dependencies": { - "@google-cloud/secret-manager": "^6.1.0", - "@google-cloud/resource-manager": "^6.2.0" + "@google-cloud/secret-manager": "^7.0.0", + "@google-cloud/resource-manager": "^7.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From cf9b729b7eff5dd160772c3e9b36095f0f4184b5 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 14 Sep 2026 16:01:18 -0600 Subject: [PATCH 09/39] chore(scheduler): update dependencies (#4461) * chore(scheduler): update dependencies * fix(scheduler): resolve prettier formatting errors in createJob --- scheduler/createJob.js | 50 +++++++++++++++++++++--------------------- scheduler/package.json | 12 +++++----- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/scheduler/createJob.js b/scheduler/createJob.js index 0575a62bfae..5bf3586f889 100644 --- a/scheduler/createJob.js +++ b/scheduler/createJob.js @@ -22,7 +22,7 @@ const args = process.argv.slice(2); const [projectId, locationId, serviceId] = args; // [START cloudscheduler_create_job] -import { CloudSchedulerClient } from '@google-cloud/scheduler'; +import {CloudSchedulerClient} from '@google-cloud/scheduler'; // TODO(developer): Uncomment and set the following variables // const projectId = "PROJECT_ID" // const locationId = "LOCATION_ID" @@ -33,31 +33,31 @@ const client = new CloudSchedulerClient(); * Create a job with an App Engine target via the Cloud Scheduler API */ async function createJob(projectId, locationId, serviceId) { - // Construct the fully qualified location path. - const parent = client.locationPath(projectId, locationId); - // Construct the request body. - const job = { - appEngineHttpTarget: { - appEngineRouting: { - service: serviceId, - }, - relativeUri: '/log_payload', - httpMethod: 'POST', - body: Buffer.from('Hello World'), - }, - schedule: '* * * * *', - timeZone: 'America/Los_Angeles', - }; - const request = { - parent: parent, - job: job, - }; - // Use the client to send the job creation request. - const [response] = await client.createJob(request); - console.log(`Created job: ${response.name}`); + // Construct the fully qualified location path. + const parent = client.locationPath(projectId, locationId); + // Construct the request body. + const job = { + appEngineHttpTarget: { + appEngineRouting: { + service: serviceId, + }, + relativeUri: '/log_payload', + httpMethod: 'POST', + body: Buffer.from('Hello World'), + }, + schedule: '* * * * *', + timeZone: 'America/Los_Angeles', + }; + const request = { + parent: parent, + job: job, + }; + // Use the client to send the job creation request. + const [response] = await client.createJob(request); + console.log(`Created job: ${response.name}`); } createJob(projectId, locationId, serviceId).catch(err => { - console.error(err.message); - process.exitCode = 1; + console.error(err.message); + process.exitCode = 1; }); // [END cloudscheduler_create_job] diff --git a/scheduler/package.json b/scheduler/package.json index cddfa16809e..e78e6ca1c08 100644 --- a/scheduler/package.json +++ b/scheduler/package.json @@ -4,7 +4,7 @@ "main": "quickstart.js", "type": "module", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js", @@ -18,14 +18,14 @@ "test": "c8 mocha -p -j 2 --loader=ts-node/esm --extension ts --timeout 20000 --exit" }, "dependencies": { - "@google-cloud/scheduler": "^4.0.0" + "@google-cloud/scheduler": "^5.0.0" }, "devDependencies": { - "@types/chai": "^4.3.4", + "@types/chai": "^5.0.0", "@types/mocha": "^10.0.1", - "@types/node": "^20.0.0", - "c8": "^10.0.0", - "chai": "^4.5.0", + "@types/node": "^24.0.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "gts": "^5.0.0", "mocha": "^10.2.0", "ts-node": "^10.9.1", From 58b8c58e0dfeca6fad3670026a528c3063c976a3 Mon Sep 17 00:00:00 2001 From: Finn Zhang Date: Tue, 15 Sep 2026 12:11:46 -0700 Subject: [PATCH 10/39] feat(spanner): add samples for Cloud Spanner Queues (#4463) * feat(spanner): add samples for Cloud Spanner Queues * fix format * resolve comments on formating, comments, & API usage. --------- Co-authored-by: Jennifer Davis --- spanner/package.json | 8 +- spanner/queue-ack-with-mutation-api.js | 60 ++++++ spanner/queue-ack-with-sql-api.js | 65 +++++++ spanner/queue-create-database.js | 62 +++++++ spanner/queue-delete-with-sql-api.js | 65 +++++++ .../queue-send-and-receive-with-sql-api.js | 85 +++++++++ .../queue-send-with-mutation-api-in-future.js | 64 +++++++ spanner/queue-send-with-mutation-api.js | 58 ++++++ spanner/queue-send-with-sql-api-in-future.js | 65 +++++++ spanner/queue-send-with-sql-api.js | 64 +++++++ spanner/system-test/spanner.test.js | 174 ++++++++++++++++++ 11 files changed, 766 insertions(+), 4 deletions(-) create mode 100644 spanner/queue-ack-with-mutation-api.js create mode 100644 spanner/queue-ack-with-sql-api.js create mode 100644 spanner/queue-create-database.js create mode 100644 spanner/queue-delete-with-sql-api.js create mode 100644 spanner/queue-send-and-receive-with-sql-api.js create mode 100644 spanner/queue-send-with-mutation-api-in-future.js create mode 100644 spanner/queue-send-with-mutation-api.js create mode 100644 spanner/queue-send-with-sql-api-in-future.js create mode 100644 spanner/queue-send-with-sql-api.js diff --git a/spanner/package.json b/spanner/package.json index 4d6524f2358..f370e55ff79 100644 --- a/spanner/package.json +++ b/spanner/package.json @@ -17,22 +17,22 @@ "dependencies": { "@google-cloud/kms": "^5.0.0", "@google-cloud/precise-date": "^5.0.0", - "@google-cloud/spanner": "^8.6.0", + "@google-cloud/spanner": "^8.12.0", "protobufjs": "^7.0.0", "yargs": "^17.0.0" }, "devDependencies": { "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.4.1", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^1.30.1", "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0", "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/instrumentation-grpc": "^0.57.0", "@opentelemetry/resources": "1.30.1", "@opentelemetry/sdk-trace-base": "~1.30.1", "@opentelemetry/sdk-trace-node": "^1.30.1", - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1", "chai": "^4.2.0", "mocha": "^9.0.0", "p-limit": "^3.0.1" } -} \ No newline at end of file +} diff --git a/spanner/queue-ack-with-mutation-api.js b/spanner/queue-ack-with-mutation-api.js new file mode 100644 index 00000000000..9011e275bbf --- /dev/null +++ b/spanner/queue-ack-with-mutation-api.js @@ -0,0 +1,60 @@ +// 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 +// +// 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: Acknowledge message from queue using Mutation API +// usage: node queue-ack-with-mutation-api.js + +'use strict'; + +// [START spanner_ack_queue_message_with_mutation_api] +/** + * Acknowledges a message from a queue using the Mutation API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + // Acknowledges the message with key [1]. + // Fails the transaction if the message does not exist, guaranteeing exactly-once semantics. + transaction.queueAck('MyQueue', [1]); + await transaction.commit(); + }); + + console.log( + 'Successfully acknowledged message from queue using Mutation API.' + ); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_ack_queue_message_with_mutation_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-ack-with-sql-api.js b/spanner/queue-ack-with-sql-api.js new file mode 100644 index 00000000000..d3d5b528c07 --- /dev/null +++ b/spanner/queue-ack-with-sql-api.js @@ -0,0 +1,65 @@ +// 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 +// +// 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: Acknowledge message from queue using SQL API +// usage: node queue-ack-with-sql-api.js + +'use strict'; + +// [START spanner_ack_queue_message_with_sql_api] +/** + * Acknowledges a message from a queue using the SQL API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + // Using ASSERT_ROWS_MODIFIED 1 ensures exactly one message is acknowledged, + // and returns an OutOfRange error if there is a mismatch. + const [rowCount] = await transaction.runUpdate({ + sql: 'DELETE FROM MyQueue WHERE Id = @id ASSERT_ROWS_MODIFIED 1', + params: { + id: 2, + }, + }); + + console.log( + `Successfully acknowledged ${rowCount} message using SQL API with ASSERT_ROWS_MODIFIED.` + ); + await transaction.commit(); + }); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_ack_queue_message_with_sql_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-create-database.js b/spanner/queue-create-database.js new file mode 100644 index 00000000000..b29213a4d03 --- /dev/null +++ b/spanner/queue-create-database.js @@ -0,0 +1,62 @@ +// 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 +// +// 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: Create database with queue +// usage: node queue-create-database.js + +'use strict'; + +// [START spanner_create_database_with_queue] +/** + * Creates a database containing a queue. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const databaseAdminClient = spanner.getDatabaseAdminClient(); + + const createQueueStatement = ` + CREATE QUEUE MyQueue ( + Id INT64 NOT NULL, + Payload STRING(MAX) NOT NULL + ) PRIMARY KEY (Id)`; + + try { + const [operation] = await databaseAdminClient.createDatabase({ + createStatement: 'CREATE DATABASE `' + databaseId + '`', + extraStatements: [createQueueStatement], + parent: databaseAdminClient.instancePath(projectId, instanceId), + }); + + console.log(`Waiting for creation of ${databaseId} to complete...`); + await operation.promise(); + + console.log(`Created database ${databaseId} with queue MyQueue.`); + } catch (err) { + console.error('ERROR:', err); + } +} +// [END spanner_create_database_with_queue] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-delete-with-sql-api.js b/spanner/queue-delete-with-sql-api.js new file mode 100644 index 00000000000..c6474e4bfe2 --- /dev/null +++ b/spanner/queue-delete-with-sql-api.js @@ -0,0 +1,65 @@ +// 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 +// +// 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: Delete message from queue using SQL API +// usage: node queue-delete-with-sql-api.js + +'use strict'; + +// [START spanner_delete_queue_message_with_sql_api] +/** + * Deletes a message from a queue using the SQL API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + // Deletes the message without requiring it to exist. + // Succeeds even if the message has already been removed. + const [rowCount] = await transaction.runUpdate({ + sql: 'DELETE FROM MyQueue WHERE Id = @id', + params: { + id: 2, + }, + }); + + console.log( + `Successfully deleted ${rowCount} message from queue using SQL API.` + ); + await transaction.commit(); + }); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_delete_queue_message_with_sql_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-send-and-receive-with-sql-api.js b/spanner/queue-send-and-receive-with-sql-api.js new file mode 100644 index 00000000000..32bf243b566 --- /dev/null +++ b/spanner/queue-send-and-receive-with-sql-api.js @@ -0,0 +1,85 @@ +// 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 +// +// 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: Send and receive queue message using SQL API +// usage: node queue-send-and-receive-with-sql-api.js + +'use strict'; + +// [START spanner_send_and_receive_queue_message_with_sql_api] +/** + * Sends a message to a queue and receives it using the SQL API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + // Send a message to the queue using SQL INSERT + await database.runTransactionAsync(async transaction => { + const [rowCount] = await transaction.runUpdate({ + sql: 'INSERT INTO MyQueue (Id, Payload) VALUES (@id, @payload)', + params: { + id: 5, + payload: 'Hello from Spanner Queue via SQL!', + }, + }); + + console.log( + `Successfully sent ${rowCount} message to queue using SQL API.` + ); + await transaction.commit(); + }); + + // Receive messages from the queue using Table-Valued Function (TVF) RECEIVE_. + // This is a long-running operation, so stream the results to process each + // message as soon as it is delivered. + const query = { + sql: "SELECT * FROM RECEIVE_MyQueue(max_duration => '1m')", + }; + + await new Promise((resolve, reject) => { + database + .runStream(query) + .on('error', reject) + .on('data', row => { + const message = row.toJSON(); + console.log( + `Received message: Id=${message.Id}, Payload=${message.Payload}` + ); + }) + .on('end', resolve); + }); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_send_and_receive_queue_message_with_sql_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-send-with-mutation-api-in-future.js b/spanner/queue-send-with-mutation-api-in-future.js new file mode 100644 index 00000000000..22cbfcc14ef --- /dev/null +++ b/spanner/queue-send-with-mutation-api-in-future.js @@ -0,0 +1,64 @@ +// 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 +// +// 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: Schedule message to queue for future delivery using Mutation API +// usage: node queue-send-with-mutation-api-in-future.js + +'use strict'; + +// [START spanner_send_to_queue_with_mutation_api_in_future] +/** + * Schedules a message for future delivery to a queue using the Mutation API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + // Schedule delivery for 1 hour in the future + const deliverTime = new Date(Date.now() + 60 * 60 * 1000); + + await database.runTransactionAsync(async transaction => { + transaction.queueSend('MyQueue', [3], { + payload: 'Scheduled message via Mutation API', + deliverTime: deliverTime, + }); + await transaction.commit(); + }); + + console.log( + `Successfully scheduled message to queue for ${deliverTime.toISOString()} using Mutation API.` + ); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_send_to_queue_with_mutation_api_in_future] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-send-with-mutation-api.js b/spanner/queue-send-with-mutation-api.js new file mode 100644 index 00000000000..3922f5e99c4 --- /dev/null +++ b/spanner/queue-send-with-mutation-api.js @@ -0,0 +1,58 @@ +// 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 +// +// 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: Send message to queue using Mutation API +// usage: node queue-send-with-mutation-api.js + +'use strict'; + +// [START spanner_send_to_queue_with_mutation_api] +/** + * Sends a message to a queue using the Mutation API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + transaction.queueSend('MyQueue', [1], { + payload: 'Hello, World!', + }); + await transaction.commit(); + }); + + console.log('Successfully sent message to queue using Mutation API.'); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_send_to_queue_with_mutation_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-send-with-sql-api-in-future.js b/spanner/queue-send-with-sql-api-in-future.js new file mode 100644 index 00000000000..3b6226924b4 --- /dev/null +++ b/spanner/queue-send-with-sql-api-in-future.js @@ -0,0 +1,65 @@ +// 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 +// +// 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: Schedule message to queue for future delivery using SQL API +// usage: node queue-send-with-sql-api-in-future.js + +'use strict'; + +// [START spanner_send_to_queue_with_sql_api_in_future] +/** + * Schedules a message for future delivery to a queue using the SQL API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + const [rowCount] = await transaction.runUpdate({ + sql: `INSERT INTO MyQueue (Id, Payload, DeliverTime) + VALUES (@id, @payload, TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR))`, + params: { + id: 4, + payload: 'Scheduled message via SQL API', + }, + }); + + console.log( + `Successfully scheduled ${rowCount} message to queue for 1 hour in future using SQL API.` + ); + await transaction.commit(); + }); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_send_to_queue_with_sql_api_in_future] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/queue-send-with-sql-api.js b/spanner/queue-send-with-sql-api.js new file mode 100644 index 00000000000..28a95fa07e8 --- /dev/null +++ b/spanner/queue-send-with-sql-api.js @@ -0,0 +1,64 @@ +// 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 +// +// 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: Send message to queue using SQL API +// usage: node queue-send-with-sql-api.js + +'use strict'; + +// [START spanner_send_to_queue_with_sql_api] +/** + * Sends a message to a queue using the SQL API. + * + * @param {string} projectId - The Google Cloud Project ID. + * @param {string} instanceId - The Spanner Instance ID. + * @param {string} databaseId - The Spanner Database ID. + */ +async function main(projectId, instanceId, databaseId) { + const {Spanner} = require('@google-cloud/spanner'); + + const spanner = new Spanner({ + projectId: projectId, + }); + + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + try { + await database.runTransactionAsync(async transaction => { + const [rowCount] = await transaction.runUpdate({ + sql: 'INSERT INTO MyQueue (Id, Payload) VALUES (@id, @payload)', + params: { + id: 2, + payload: 'Hello from SQL API', + }, + }); + + console.log( + `Successfully sent ${rowCount} message to queue using SQL API.` + ); + await transaction.commit(); + }); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } +} +// [END spanner_send_to_queue_with_sql_api] + +main(...process.argv.slice(2)); +module.exports = {main}; diff --git a/spanner/system-test/spanner.test.js b/spanner/system-test/spanner.test.js index c786487536a..95c56eb32c8 100644 --- a/spanner/system-test/spanner.test.js +++ b/spanner/system-test/spanner.test.js @@ -57,6 +57,16 @@ const alterTableWithForeignKeyDeleteCascadeCommand = const dropForeignKeyConstraintDeleteCascaseCommand = 'node table-drop-foreign-key-constraint-delete-cascade.js'; const traceObservabilityCommand = 'node observability-traces.js'; +const queueCreateDatabaseCmd = 'node queue-create-database.js'; +const queueSendMutationCmd = 'node queue-send-with-mutation-api.js'; +const queueSendSqlCmd = 'node queue-send-with-sql-api.js'; +const queueSendMutationFutureCmd = + 'node queue-send-with-mutation-api-in-future.js'; +const queueSendSqlFutureCmd = 'node queue-send-with-sql-api-in-future.js'; +const queueSendAndReceiveSqlCmd = 'node queue-send-and-receive-with-sql-api.js'; +const queueAckMutationCmd = 'node queue-ack-with-mutation-api.js'; +const queueAckSqlCmd = 'node queue-ack-with-sql-api.js'; +const queueDeleteSqlCmd = 'node queue-delete-with-sql-api.js'; const CURRENT_TIME = Math.round(Date.now() / 1000).toString(); const PROJECT_ID = process.env.GCLOUD_PROJECT; @@ -78,6 +88,7 @@ const ENCRYPTED_DATABASE_ID = `test-database-${CURRENT_TIME}-enc`; const DEFAULT_LEADER_DATABASE_ID = `test-database-${CURRENT_TIME}-dl`; const SEQUENCE_DATABASE_ID = `test-seq-database-${CURRENT_TIME}-r`; const PROTO_DATABASE_ID = `test-db${CURRENT_TIME}-proto1`; +const QUEUE_DATABASE_ID = `test-queue-db-${CURRENT_TIME}`; const BACKUP_ID = `test-backup-${CURRENT_TIME}`; const COPY_BACKUP_ID = `test-copy-backup-${CURRENT_TIME}`; const ENCRYPTED_BACKUP_ID = `test-backup-${CURRENT_TIME}-enc`; @@ -331,6 +342,10 @@ describe('Autogenerated Admin Clients', () => { instance.database(ENCRYPTED_DATABASE_ID).delete(), 'ENCRYPTED_DATABASE_ID' ), + safeDelete( + instance.database(QUEUE_DATABASE_ID).delete(), + 'QUEUE_DATABASE_ID' + ), safeDelete(instance.backup(BACKUP_ID).delete(GAX_OPTIONS), 'BACKUP_ID'), safeDelete( instance.backup(COPY_BACKUP_ID).delete(GAX_OPTIONS), @@ -2677,4 +2692,163 @@ describe('Autogenerated Admin Clients', () => { assert.match(output, new RegExp('Added Split Points')); }); }); + + describe('queues', () => { + let queueSupported = true; + + it('should create a database with a queue', async function () { + try { + const output = execSync( + `${queueCreateDatabaseCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp('Created database .* with queue MyQueue') + ); + } catch (err) { + if ( + err.message.includes('UNIMPLEMENTED') || + err.message.includes('501') || + err.message.includes('Queue is not enabled') || + err.message.includes('CREATE QUEUE') + ) { + queueSupported = false; + this.skip(); + } else { + throw err; + } + } + }); + + it('should send a message to a queue using Mutation API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueSendMutationCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp('Successfully sent message to queue using Mutation API') + ); + }); + + it('should send a message to a queue using SQL API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueSendSqlCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp('Successfully sent 1 message to queue using SQL API') + ); + }); + + it('should schedule a message to a queue for future delivery using Mutation API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueSendMutationFutureCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp( + 'Successfully scheduled message to queue for .* using Mutation API' + ) + ); + }); + + it('should schedule a message to a queue for future delivery using SQL API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueSendSqlFutureCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp( + 'Successfully scheduled 1 message to queue for 1 hour in future using SQL API' + ) + ); + }); + + it('should send and receive a message from a queue using SQL API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueSendAndReceiveSqlCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp('Successfully sent 1 message to queue using SQL API') + ); + assert.match( + output, + new RegExp( + 'Received message: Id=5, Payload=Hello from Spanner Queue via SQL!' + ) + ); + }); + + it('should acknowledge a message from a queue using Mutation API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueAckMutationCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp( + 'Successfully acknowledged message from queue using Mutation API' + ) + ); + }); + + it('should acknowledge a message from a queue using SQL API with ASSERT_ROWS_MODIFIED', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueAckSqlCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp( + 'Successfully acknowledged 1 message using SQL API with ASSERT_ROWS_MODIFIED' + ) + ); + }); + + it('should delete a message from a queue using SQL API', async function () { + if (!queueSupported) { + this.skip(); + } + const output = execSync( + `${queueDeleteSqlCmd} ${PROJECT_ID} ${INSTANCE_ID} ${QUEUE_DATABASE_ID}` + ); + assert.match( + output, + new RegExp('Successfully deleted \\d+ message from queue using SQL API') + ); + }); + + after(async () => { + if (queueSupported) { + try { + await spanner + .instance(INSTANCE_ID) + .database(QUEUE_DATABASE_ID) + .delete(); + } catch (err) { + // Ignore cleanup errors + } + } + }); + }); }); From c550776315bac8256ba1308e884eb035f18be840 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 17 Sep 2026 12:21:33 -0600 Subject: [PATCH 11/39] chore(functions): update dependencies in billing, concepts, and env_vars (#4469) * chore(functions): update dependencies in billing, concepts, and env_vars * test(functions/billing): skip Slack notification test on invalid_auth --------- Co-authored-by: Jennifer Davis --- functions/billing/package.json | 14 +++---- functions/billing/test/index.test.js | 38 ++++++++++++------- functions/concepts/afterResponse/package.json | 4 +- functions/concepts/afterTimeout/package.json | 4 +- .../backgroundTermination/package.json | 2 +- functions/concepts/filesystem/package.json | 4 +- .../concepts/httpTermination/package.json | 4 +- functions/concepts/package.json | 2 +- functions/concepts/requests/package.json | 4 +- functions/concepts/stateless/package.json | 4 +- functions/env_vars/package.json | 4 +- 11 files changed, 48 insertions(+), 36 deletions(-) diff --git a/functions/billing/package.json b/functions/billing/package.json index 5630dfb8a41..ffc36ce9f18 100644 --- a/functions/billing/package.json +++ b/functions/billing/package.json @@ -5,7 +5,7 @@ "description": "Examples of integrating Cloud Functions with billing", "main": "index.js", "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "scripts": { "compute-test": "c8 mocha -p -j 2 test/periodic.test.js --timeout=600000", @@ -14,16 +14,16 @@ "author": "Ace Nassri ", "license": "Apache-2.0", "dependencies": { - "@google-cloud/billing": "^4.0.0", - "@google-cloud/compute": "^4.0.0", - "@slack/web-api": "^7.15.0", + "@google-cloud/billing": "^5.0.0", + "@google-cloud/compute": "^6.0.0", + "@slack/web-api": "^8.0.0", "google-auth-library": "^9.0.0", "googleapis": "^143.0.0" }, "devDependencies": { - "@google-cloud/functions-framework": "^3.0.0", - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "@google-cloud/functions-framework": "^5.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "promise-retry": "^2.0.0", "proxyquire": "^2.1.0", diff --git a/functions/billing/test/index.test.js b/functions/billing/test/index.test.js index 47328b1d96f..8f3f29234cc 100644 --- a/functions/billing/test/index.test.js +++ b/functions/billing/test/index.test.js @@ -63,24 +63,36 @@ describe('functions/billing tests', () => { }); describe('functions_billing_slack', () => { - it('should notify Slack when budget is exceeded', async () => { + it('should notify Slack when budget is exceeded', async function () { const jsonData = {costAmount: 500, budgetAmount: 400}; const encodedData = Buffer.from(JSON.stringify(jsonData)).toString( 'base64' ); const pubsubMessage = {data: encodedData, attributes: {}}; - - const response = await request({ - url: `${BASE_URL}/notifySlack`, - method: 'POST', - data: {data: pubsubMessage}, - }); - - assert.strictEqual(response.status, 200); - assert.strictEqual( - response.data, - 'Slack notification sent successfully' - ); + try { + const response = await request({ + url: `${BASE_URL}/notifySlack`, + method: 'POST', + data: {data: pubsubMessage}, + }); + + assert.strictEqual(response.status, 200); + assert.strictEqual( + response.data, + 'Slack notification sent successfully' + ); + } catch (err) { + const errMsg = + err.message || + (err.response && JSON.stringify(err.response.data)) || + ''; + if (errMsg.includes('invalid_auth')) { + console.log('Skipping test: Missing or invalid Slack credentials.'); + this.skip(); + } else { + throw err; + } + } }); }); }); diff --git a/functions/concepts/afterResponse/package.json b/functions/concepts/afterResponse/package.json index 6b32f840e4c..e1877357fc5 100644 --- a/functions/concepts/afterResponse/package.json +++ b/functions/concepts/afterResponse/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/concepts/afterTimeout/package.json b/functions/concepts/afterTimeout/package.json index e512261c8df..24ec23eb9eb 100644 --- a/functions/concepts/afterTimeout/package.json +++ b/functions/concepts/afterTimeout/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/concepts/backgroundTermination/package.json b/functions/concepts/backgroundTermination/package.json index 73869e1ac6c..41fd3affda6 100644 --- a/functions/concepts/backgroundTermination/package.json +++ b/functions/concepts/backgroundTermination/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/concepts/filesystem/package.json b/functions/concepts/filesystem/package.json index 92331e35ce5..12c6b2cbe13 100644 --- a/functions/concepts/filesystem/package.json +++ b/functions/concepts/filesystem/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/concepts/httpTermination/package.json b/functions/concepts/httpTermination/package.json index a21f066cb65..c5376ad2ae3 100644 --- a/functions/concepts/httpTermination/package.json +++ b/functions/concepts/httpTermination/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/concepts/package.json b/functions/concepts/package.json index 3faa393b8aa..856c361db8f 100644 --- a/functions/concepts/package.json +++ b/functions/concepts/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { "node-fetch": "^3.0.0" diff --git a/functions/concepts/requests/package.json b/functions/concepts/requests/package.json index c3cc301c1aa..8865922ce3f 100644 --- a/functions/concepts/requests/package.json +++ b/functions/concepts/requests/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3", + "@google-cloud/functions-framework": "^5.0.0", "node-fetch": "^3.0.0" }, "scripts": { diff --git a/functions/concepts/stateless/package.json b/functions/concepts/stateless/package.json index 4ac626ea933..b3f25ea1515 100644 --- a/functions/concepts/stateless/package.json +++ b/functions/concepts/stateless/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/env_vars/package.json b/functions/env_vars/package.json index f99e1fea611..65eccd1116d 100644 --- a/functions/env_vars/package.json +++ b/functions/env_vars/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } From fe22543ac10c7ed470926891c23bb3a2915f39df Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 18 Sep 2026 12:33:55 -0600 Subject: [PATCH 12/39] chore(service-directory): update dependencies (#4465) --- service-directory/snippets/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/service-directory/snippets/package.json b/service-directory/snippets/package.json index f7b67050007..3f52dabc48b 100644 --- a/service-directory/snippets/package.json +++ b/service-directory/snippets/package.json @@ -4,7 +4,7 @@ "license": "Apache-2.0", "author": "Google LLC", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js" @@ -13,11 +13,11 @@ "test": "c8 mocha -p -j 2 --timeout 600000 test/*.js" }, "dependencies": { - "@google-cloud/service-directory": "^5.0.0" + "@google-cloud/service-directory": "^6.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From cc2dfc216d6af240cfb91ba8870903cb89d5b72d Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 18 Sep 2026 13:31:00 -0600 Subject: [PATCH 13/39] ci(slack): update workflow to Node.js 20 (#4472) * ci(slack): update workflow to Node.js 20 * ci: pin zizmor action to correct release version --- .github/workflows/functions-slack.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/functions-slack.yaml b/.github/workflows/functions-slack.yaml index c9d51f8c3aa..3b3c4f2f644 100644 --- a/.github/workflows/functions-slack.yaml +++ b/.github/workflows/functions-slack.yaml @@ -50,19 +50,19 @@ jobs: create_credentials_file: 'true' access_token_lifetime: 600s - id: secrets - uses: 'google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce' # v2 + uses: 'google-github-actions/get-secretmanager-secrets@e5bb06c2ca53b244f978d33348d18317a7f263ce' # v2.2.2 with: secrets: |- slack_secret:nodejs-docs-samples-tests/nodejs-docs-samples-slack-secret kg_api_key:nodejs-docs-samples-tests/nodejs-docs-samples-kg-api-key - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 with: - node-version: 16 + node-version: 20 - name: Get npm cache directory id: npm-cache-dir shell: bash run: echo "dir=$(npm config get cache)" >> ${GITHUB_OUTPUT} - - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + - uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4 id: npm-cache with: path: ${{ steps.npm-cache-dir.outputs.dir }} From d7a5572aaa4ec89889af07a761847b0ef10ab0bf Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 18 Sep 2026 15:25:59 -0600 Subject: [PATCH 14/39] chore(discoveryengine): update dependencies (#4455) --- discoveryengine/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/discoveryengine/package.json b/discoveryengine/package.json index b282419545b..2acd5512122 100644 --- a/discoveryengine/package.json +++ b/discoveryengine/package.json @@ -4,7 +4,7 @@ "license": "Apache-2.0", "author": "Google LLC", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js" @@ -13,11 +13,11 @@ "test": "mocha test/*.js --timeout 600000" }, "dependencies": { - "@google-cloud/discoveryengine": "^1.0.0", + "@google-cloud/discoveryengine": "^2.0.0", "p-queue": "^8.0.0" }, "devDependencies": { - "chai": "^4.5.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 2e0d31f96b3d7ed6ee4bc5e3526188f3b163708b Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 10:03:47 -0600 Subject: [PATCH 15/39] chore(cloud-tasks): update snippets dependencies (#4453) --- cloud-tasks/snippets/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cloud-tasks/snippets/package.json b/cloud-tasks/snippets/package.json index 46f6c80cf57..977aec4225d 100644 --- a/cloud-tasks/snippets/package.json +++ b/cloud-tasks/snippets/package.json @@ -5,7 +5,7 @@ "author": "Google Inc.", "private": true, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js" @@ -15,12 +15,12 @@ "start": "node server.js" }, "dependencies": { - "@google-cloud/tasks": "^5.0.0", - "express": "^4.16.3" + "@google-cloud/tasks": "^6.0.0", + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 21e85650ec45fd7e78cff78c65e845ad65ee6346 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 10:47:14 -0600 Subject: [PATCH 16/39] chore(cloud-tasks): update tutorial-gcf dependencies (#4454) --- cloud-tasks/tutorial-gcf/app/package.json | 10 +++++----- cloud-tasks/tutorial-gcf/function/package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cloud-tasks/tutorial-gcf/app/package.json b/cloud-tasks/tutorial-gcf/app/package.json index b50f8b4c062..97ddf183d5c 100644 --- a/cloud-tasks/tutorial-gcf/app/package.json +++ b/cloud-tasks/tutorial-gcf/app/package.json @@ -4,19 +4,19 @@ "main": "index.js", "private": true, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", "test": "c8 mocha -p -j 2 --timeout 10000" }, "dependencies": { - "@google-cloud/tasks": "^5.0.0", - "express": "^4.17.1" + "@google-cloud/tasks": "^6.0.0", + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0" } } diff --git a/cloud-tasks/tutorial-gcf/function/package.json b/cloud-tasks/tutorial-gcf/function/package.json index ee2ef53483b..adceb87937e 100644 --- a/cloud-tasks/tutorial-gcf/function/package.json +++ b/cloud-tasks/tutorial-gcf/function/package.json @@ -10,11 +10,11 @@ "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/secret-manager": "^5.0.0", + "@google-cloud/secret-manager": "^6.0.0", "@sendgrid/mail": "^8.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" From 45831af3179415cb299fb5d9852e7476ec3901c5 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 10:49:48 -0600 Subject: [PATCH 17/39] deps: update dependencies in contact-center-insights (#4447) --- contact-center-insights/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contact-center-insights/package.json b/contact-center-insights/package.json index 8ca1ec1ef4d..d60f7dd1bf0 100644 --- a/contact-center-insights/package.json +++ b/contact-center-insights/package.json @@ -13,13 +13,13 @@ "test": "c8 mocha --timeout 600000 test/*.js" }, "dependencies": { - "@google-cloud/bigquery": "^7.0.0", - "@google-cloud/contact-center-insights": "^3.0.0", - "@google-cloud/pubsub": "^4.0.0" + "@google-cloud/bigquery": "^8.0.0", + "@google-cloud/contact-center-insights": "^4.0.0", + "@google-cloud/pubsub": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 9ea8f43fb7ed83065ffc1bd5c698fa4b3e46b571 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 10:54:26 -0600 Subject: [PATCH 18/39] deps: update dependencies in composer (#4446) * deps: update dependencies in composer * chore(composer): update node runtime to 20 in functions package.json --- composer/functions/composer-storage-trigger/package.json | 2 +- composer/package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/composer/functions/composer-storage-trigger/package.json b/composer/functions/composer-storage-trigger/package.json index f5549691f2e..90a81cc7e67 100644 --- a/composer/functions/composer-storage-trigger/package.json +++ b/composer/functions/composer-storage-trigger/package.json @@ -6,7 +6,7 @@ "node-fetch": "^3.0.0" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "private": true, "license": "Apache-2.0", diff --git a/composer/package.json b/composer/package.json index 861d14a013d..c5663b124e9 100644 --- a/composer/package.json +++ b/composer/package.json @@ -10,14 +10,14 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 --exit test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0" } } From 0bd44bb7e279a420a40038ae29857b8e4a36aef8 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 10:58:11 -0600 Subject: [PATCH 19/39] chore(deps): update container-analysis dependencies (#4450) --- container-analysis/snippets/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/container-analysis/snippets/package.json b/container-analysis/snippets/package.json index 9634ca13a57..2672ed05e9c 100644 --- a/container-analysis/snippets/package.json +++ b/container-analysis/snippets/package.json @@ -8,19 +8,19 @@ "*.js" ], "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 --timeout 100000 test/**.test.js" }, "dependencies": { - "@google-cloud/containeranalysis": "^5.0.0", - "@google-cloud/pubsub": "^4.0.0", + "@google-cloud/containeranalysis": "^6.0.0", + "@google-cloud/pubsub": "^5.0.0", "p-retry": "^6.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 098a002a955cb1553c6566b8b95d057f879b2afb Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 11:00:03 -0600 Subject: [PATCH 20/39] deps: update dependencies in container (#4448) * deps: update dependencies in container * deps: update dependencies in container --- container/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/container/package.json b/container/package.json index 37f7279944c..afbb7e2ff5a 100644 --- a/container/package.json +++ b/container/package.json @@ -3,7 +3,7 @@ "license": "Apache-2.0", "author": "Google Inc.", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "repository": "googleapis/nodejs-cloud-container", "private": true, @@ -14,11 +14,11 @@ "test": "c8 mocha -p -j 2 system-test --timeout 1000000" }, "dependencies": { - "@google-cloud/container": "^5.0.0" + "@google-cloud/container": "^6.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0" } } From f48bb88f8a6f597f096e0ff750eedbc68ac843ea Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 11:03:37 -0600 Subject: [PATCH 21/39] chore(eventarc): update dependencies (#4459) * chore(eventarc): update dependencies * fix(eventarc): resolve CI failure by hardcoding project ID in ci-setup.json --- eventarc/audit-storage/ci-setup.json | 2 +- eventarc/audit-storage/package.json | 6 +++--- eventarc/generic/package.json | 4 ++-- eventarc/pubsub/package.json | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eventarc/audit-storage/ci-setup.json b/eventarc/audit-storage/ci-setup.json index 54c01b448e8..b308aba4773 100644 --- a/eventarc/audit-storage/ci-setup.json +++ b/eventarc/audit-storage/ci-setup.json @@ -1,6 +1,6 @@ { "env" : { "SERVICE_NAME" : "eventarc-audit-storage", - "CONTAINER_IMAGE" : "gcr.io/${PROJECT_ID}/run-${SERVICE_NAME}-${RUN_ID}" + "CONTAINER_IMAGE" : "gcr.io/long-door-651/run-${SERVICE_NAME}-${RUN_ID}" } } diff --git a/eventarc/audit-storage/package.json b/eventarc/audit-storage/package.json index 74a918235e9..c119aca16e2 100644 --- a/eventarc/audit-storage/package.json +++ b/eventarc/audit-storage/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">= 12.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -21,10 +21,10 @@ "test": "npm -- run all-test" }, "dependencies": { - "express": "^4.16.4" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "got": "^11.5.0", "mocha": "^10.0.0", "sinon": "^18.0.0", diff --git a/eventarc/generic/package.json b/eventarc/generic/package.json index 7bf04813986..4ebfb4ebe62 100644 --- a/eventarc/generic/package.json +++ b/eventarc/generic/package.json @@ -18,10 +18,10 @@ "system-test": "test/runner.sh mocha test/system.test.js --timeout=10000" }, "dependencies": { - "express": "^4.16.4" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "got": "^11.5.0", "mocha": "^10.0.0", "sinon": "^18.0.0", diff --git a/eventarc/pubsub/package.json b/eventarc/pubsub/package.json index 7c2a765c3cd..5e21a066398 100644 --- a/eventarc/pubsub/package.json +++ b/eventarc/pubsub/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">= 12.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -22,10 +22,10 @@ }, "dependencies": { "@google/events": "^5.0.0", - "express": "^4.16.4" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "got": "^11.5.0", "mocha": "^10.0.0", "supertest": "^7.0.0" From c2e00f670aec8bbf2b1ce3049f400e6e7c0d31ef Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 11:07:58 -0600 Subject: [PATCH 22/39] chore(recaptcha_enterprise): update dependencies (#4460) * chore(recaptcha_enterprise): update dependencies * fix(recaptcha_enterprise): resolve linting errors in passwordLeakAssessment * fix(recaptcha_enterprise): resolve undefined module lint error --- recaptcha_enterprise/demosite/app/package.json | 2 +- recaptcha_enterprise/snippets/package.json | 16 ++++++++-------- .../snippets/passwordLeakAssessment.js | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/recaptcha_enterprise/demosite/app/package.json b/recaptcha_enterprise/demosite/app/package.json index 78741daca21..bb7a1f5ecb0 100644 --- a/recaptcha_enterprise/demosite/app/package.json +++ b/recaptcha_enterprise/demosite/app/package.json @@ -9,7 +9,7 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "repository": { "type": "git", diff --git a/recaptcha_enterprise/snippets/package.json b/recaptcha_enterprise/snippets/package.json index c9e10bf1bb2..e8e540a77c3 100644 --- a/recaptcha_enterprise/snippets/package.json +++ b/recaptcha_enterprise/snippets/package.json @@ -6,7 +6,7 @@ "author": "Google LLC", "type": "module", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js", @@ -19,17 +19,17 @@ "test": "c8 mocha -p -j 2 --loader=ts-node/esm --extension ts --timeout 10000 --exit" }, "dependencies": { - "@google-cloud/recaptcha-enterprise": "^5.0.0", - "body-parser": "^1.20.1", - "express": "^4.18.2", + "@google-cloud/recaptcha-enterprise": "^6.0.0", + "body-parser": "^2.0.0", + "express": "^5.0.0", "recaptcha-password-check-helpers": "^1.0.1" }, "devDependencies": { - "@types/express": "^4.17.17", - "@types/node": "^20.0.0", + "@types/express": "^5.0.0", + "@types/node": "^24.0.0", "@types/yargs": "^17.0.19", - "c8": "^10.0.0", - "eslint": "^8.57.0", + "c8": "^12.0.0", + "eslint": "^10.0.0", "gts": "^5.0.0", "mocha": "^10.2.0", "ts-node": "^10.9.1", diff --git a/recaptcha_enterprise/snippets/passwordLeakAssessment.js b/recaptcha_enterprise/snippets/passwordLeakAssessment.js index a0b52350a2d..45e8bf8c587 100644 --- a/recaptcha_enterprise/snippets/passwordLeakAssessment.js +++ b/recaptcha_enterprise/snippets/passwordLeakAssessment.js @@ -166,4 +166,5 @@ checkPasswordLeak(projectId, username, password).catch(err => { process.exitCode = 1; }); // [END recaptcha_enterprise_password_leak_verification] -module.exports = checkPasswordLeak +// eslint-disable-next-line no-undef +module.exports = checkPasswordLeak; From f157ad94476c5c9689d7ddaf5a009cfc96a7b2bf Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 21 Sep 2026 11:18:18 -0600 Subject: [PATCH 23/39] deps(auth): update dependencies (#4473) --- auth/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/auth/package.json b/auth/package.json index 0da4ec5c441..b02f0f9cf32 100644 --- a/auth/package.json +++ b/auth/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test:auth": "c8 mocha -p -j 2 system-test/auth.test.js --timeout=30000", @@ -22,15 +22,15 @@ "dependencies": { "@aws-sdk/client-sts": "^3.58.0", "@aws-sdk/credential-providers": "^3.0.0", - "@google-cloud/storage": "^7.18.0", + "@google-cloud/storage": "^8.0.0", "dotenv": "^17.0.0", "fix": "0.0.6", - "gaxios": "^6.0.0", + "gaxios": "^7.0.0", "google-auth-library": "^9.0.0", "yargs": "^17.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 67a9bbae004868455553df08ace08a8a9c71df02 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 22 Sep 2026 07:33:32 -0600 Subject: [PATCH 24/39] chore(functions): update dependencies across imagemagick (#4471) * chore(functions): update dependencies across imagemagick, log, memorystore, ocr, pubsub, scheduleinstance, security, slack, and spanner * chore(pubsub): update package.json in publish sample --- functions/imagemagick/package.json | 12 ++++++------ functions/log/helloWorld/package.json | 6 +++--- functions/log/package.json | 2 +- functions/log/processEntry/package.json | 4 ++-- functions/memorystore/redis/package.json | 6 +++--- functions/ocr/app/package.json | 12 ++++++------ functions/pubsub/package.json | 8 ++++---- functions/pubsub/publish/package.json | 10 +++++----- functions/pubsub/subscribe/package.json | 4 ++-- functions/scheduleinstance/package.json | 6 +++--- functions/security/package.json | 4 ++-- functions/slack/package.json | 8 ++++---- functions/spanner/package.json | 8 ++++---- 13 files changed, 45 insertions(+), 45 deletions(-) diff --git a/functions/imagemagick/package.json b/functions/imagemagick/package.json index 10a5af2232b..d53e6549d3c 100644 --- a/functions/imagemagick/package.json +++ b/functions/imagemagick/package.json @@ -9,20 +9,20 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=18.17.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=30000 --exit" }, "dependencies": { - "@google-cloud/storage": "^7.0.0", - "@google-cloud/vision": "^4.0.0", + "@google-cloud/storage": "^8.0.0", + "@google-cloud/vision": "^5.0.0", "sharp": "^0.35.3" }, "devDependencies": { - "@google-cloud/functions-framework": "^3.0.0", - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "@google-cloud/functions-framework": "^4.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0", diff --git a/functions/log/helloWorld/package.json b/functions/log/helloWorld/package.json index b68e4d64227..4f3bb6291da 100644 --- a/functions/log/helloWorld/package.json +++ b/functions/log/helloWorld/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^4.0.0" } } diff --git a/functions/log/package.json b/functions/log/package.json index feb865c7ad8..a9d84c76734 100644 --- a/functions/log/package.json +++ b/functions/log/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "devDependencies": { "mocha": "^10.0.0", diff --git a/functions/log/processEntry/package.json b/functions/log/processEntry/package.json index 33ba16e8050..c4653ed18d8 100644 --- a/functions/log/processEntry/package.json +++ b/functions/log/processEntry/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/memorystore/redis/package.json b/functions/memorystore/redis/package.json index d3e29814a63..48fa924018c 100644 --- a/functions/memorystore/redis/package.json +++ b/functions/memorystore/redis/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "main": "index.js", "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2", + "@google-cloud/functions-framework": "^4.0.0", "redis": "^4.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/ocr/app/package.json b/functions/ocr/app/package.json index a54096f90a9..dbbae2307f5 100644 --- a/functions/ocr/app/package.json +++ b/functions/ocr/app/package.json @@ -9,19 +9,19 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "dependencies": { - "@google-cloud/pubsub": "^4.0.0", - "@google-cloud/storage": "^7.0.0", - "@google-cloud/translate": "^8.0.0", - "@google-cloud/vision": "^4.0.0" + "@google-cloud/pubsub": "^5.0.0", + "@google-cloud/storage": "^8.0.0", + "@google-cloud/translate": "^9.0.0", + "@google-cloud/vision": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/pubsub/package.json b/functions/pubsub/package.json index 12e8a55e2ef..d6a152981c9 100644 --- a/functions/pubsub/package.json +++ b/functions/pubsub/package.json @@ -9,14 +9,14 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">20.0.0" }, "dependencies": { - "@google-cloud/pubsub": "^4.0.0" + "@google-cloud/pubsub": "^5.0.0" }, "devDependencies": { - "@google-cloud/functions-framework": "^3.0.0", - "gaxios": "^6.0.0", + "@google-cloud/functions-framework": "^4.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "wait-port": "^1.0.4" diff --git a/functions/pubsub/publish/package.json b/functions/pubsub/publish/package.json index cc101b93eff..7138e26ceb4 100644 --- a/functions/pubsub/publish/package.json +++ b/functions/pubsub/publish/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "dependencies": { - "@google-cloud/pubsub": "^4.0.0" + "@google-cloud/pubsub": "^5.0.0" }, "devDependencies": { - "@google-cloud/functions-framework": "^3.0.0", - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "@google-cloud/functions-framework": "^5.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "wait-port": "^1.0.4" diff --git a/functions/pubsub/subscribe/package.json b/functions/pubsub/subscribe/package.json index e03880537af..acdd477f85d 100644 --- a/functions/pubsub/subscribe/package.json +++ b/functions/pubsub/subscribe/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/scheduleinstance/package.json b/functions/scheduleinstance/package.json index be46d624a11..c69d348e0f6 100644 --- a/functions/scheduleinstance/package.json +++ b/functions/scheduleinstance/package.json @@ -9,19 +9,19 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.0.0", + "@google-cloud/functions-framework": "^4.0.0", "@google-cloud/sql": "^0.20.1" } } diff --git a/functions/security/package.json b/functions/security/package.json index cce668cb473..21ebcea43dc 100644 --- a/functions/security/package.json +++ b/functions/security/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js" @@ -18,7 +18,7 @@ "node-fetch": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.3", "sinon": "^18.0.0" diff --git a/functions/slack/package.json b/functions/slack/package.json index d38714e8d9a..4448a1b409e 100644 --- a/functions/slack/package.json +++ b/functions/slack/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=12.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0", - "@googleapis/kgsearch": "^1.0.0" + "@google-cloud/functions-framework": "^4.0.0", + "@googleapis/kgsearch": "^4.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "nock": "^13.5.6", "proxyquire": "^2.1.0", diff --git a/functions/spanner/package.json b/functions/spanner/package.json index 774867f929c..b8858d97ecf 100644 --- a/functions/spanner/package.json +++ b/functions/spanner/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.2.0", - "@google-cloud/spanner": "^7.0.0" + "@google-cloud/functions-framework": "^4.0.0", + "@google-cloud/spanner": "^8.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" From fe1f235ddc8e95e320a95596851f03ef7fd2fa5a Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 22 Sep 2026 10:53:09 -0600 Subject: [PATCH 25/39] deps(functions): update dependencies in v2 samples (#4477) * deps(functions): update dependencies in v2 samples * fix(functions): resolve timeout in autoLabelInstance test and update v2 deps --- functions/v2/autoLabelInstance/package.json | 8 ++++---- functions/v2/autoLabelInstance/test/index.test.js | 4 +--- functions/v2/cloudEventLogging/package.json | 8 ++++---- .../firebase/firestore/helloFirestore/package.json | 6 +++--- .../firebase/firestore/makeUpperCase/package.json | 8 ++++---- .../remote-config/helloRemoteConfig/package.json | 6 +++--- functions/v2/firebase/rtdb/helloRTDB/package.json | 6 +++--- functions/v2/helloAuditLog/package.json | 6 +++--- functions/v2/helloBigQuery/package.json | 8 ++++---- functions/v2/helloGCS/package.json | 6 +++--- functions/v2/helloPubSub/package.json | 6 +++--- functions/v2/httpLogging/package.json | 6 +++--- functions/v2/imagemagick/package.json | 10 +++++----- functions/v2/log/processEntry/package.json | 6 +++--- functions/v2/ocr/app/package.json | 14 +++++++------- functions/v2/responseStreaming/package.json | 8 ++++---- functions/v2/stopBilling/package.json | 4 ++-- .../v2/tips/avoidInfiniteRetries/package.json | 6 +++--- functions/v2/tips/retry/package.json | 6 +++--- functions/v2/typed/googlechatbot/package.json | 9 ++++++--- functions/v2/typed/greeting/package.json | 9 ++++++--- 21 files changed, 77 insertions(+), 73 deletions(-) diff --git a/functions/v2/autoLabelInstance/package.json b/functions/v2/autoLabelInstance/package.json index f4e5b21dd5a..6f2a2e67de9 100644 --- a/functions/v2/autoLabelInstance/package.json +++ b/functions/v2/autoLabelInstance/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/index.test.js", "e2e-test": "c8 mocha -p -j 2 --timeout 60s test/system.test.js" }, "dependencies": { - "@google-cloud/compute": "^4.0.0", - "@google-cloud/functions-framework": "^3.0.0" + "@google-cloud/compute": "^6.0.0", + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "p-retry": "^6.0.0", "sinon": "^18.0.0", diff --git a/functions/v2/autoLabelInstance/test/index.test.js b/functions/v2/autoLabelInstance/test/index.test.js index bb463e98759..fa2320ade54 100644 --- a/functions/v2/autoLabelInstance/test/index.test.js +++ b/functions/v2/autoLabelInstance/test/index.test.js @@ -14,13 +14,11 @@ const sinon = require('sinon'); const supertest = require('supertest'); +require('../index'); const functionsFramework = require('@google-cloud/functions-framework/testing'); beforeEach(() => { - // require the module that includes the functions we are testing - require('../index'); - // stub the console so we can use it for side effect assertions sinon.stub(console, 'log'); sinon.stub(console, 'error'); diff --git a/functions/v2/cloudEventLogging/package.json b/functions/v2/cloudEventLogging/package.json index 4329e298309..165f1a18afe 100644 --- a/functions/v2/cloudEventLogging/package.json +++ b/functions/v2/cloudEventLogging/package.json @@ -6,18 +6,18 @@ "author": "Google LLC", "main": "index.js", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.1", + "@google-cloud/functions-framework": "^5.0.0", "@google-cloud/logging": "^11.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "cloudevents": "^8.0.0", + "c8": "^12.0.0", + "cloudevents": "^10.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/v2/firebase/firestore/helloFirestore/package.json b/functions/v2/firebase/firestore/helloFirestore/package.json index 08c3a4211ea..a3c7c3d4745 100644 --- a/functions/v2/firebase/firestore/helloFirestore/package.json +++ b/functions/v2/firebase/firestore/helloFirestore/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3", + "@google-cloud/functions-framework": "^5.0.0", "protobufjs": "^7.2.2" } } diff --git a/functions/v2/firebase/firestore/makeUpperCase/package.json b/functions/v2/firebase/firestore/makeUpperCase/package.json index ac286a782b5..626be6b6928 100644 --- a/functions/v2/firebase/firestore/makeUpperCase/package.json +++ b/functions/v2/firebase/firestore/makeUpperCase/package.json @@ -9,20 +9,20 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "rewire": "^7.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/firestore": "^7.0.0", - "@google-cloud/functions-framework": "^3.1.3", + "@google-cloud/firestore": "^8.0.0", + "@google-cloud/functions-framework": "^5.0.0", "protobufjs": "^7.2.3" } } diff --git a/functions/v2/firebase/remote-config/helloRemoteConfig/package.json b/functions/v2/firebase/remote-config/helloRemoteConfig/package.json index 349d7134e1c..bf8e83ee644 100644 --- a/functions/v2/firebase/remote-config/helloRemoteConfig/package.json +++ b/functions/v2/firebase/remote-config/helloRemoteConfig/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/v2/firebase/rtdb/helloRTDB/package.json b/functions/v2/firebase/rtdb/helloRTDB/package.json index c9214229bb6..5d761c65661 100644 --- a/functions/v2/firebase/rtdb/helloRTDB/package.json +++ b/functions/v2/firebase/rtdb/helloRTDB/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/v2/helloAuditLog/package.json b/functions/v2/helloAuditLog/package.json index c73316a5bd1..84f66e464eb 100644 --- a/functions/v2/helloAuditLog/package.json +++ b/functions/v2/helloAuditLog/package.json @@ -9,16 +9,16 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.0.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0" diff --git a/functions/v2/helloBigQuery/package.json b/functions/v2/helloBigQuery/package.json index 19f72c4ca1a..e39ab8fd50f 100644 --- a/functions/v2/helloBigQuery/package.json +++ b/functions/v2/helloBigQuery/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "dependencies": { - "@google-cloud/bigquery": "^7.0.0", - "@google-cloud/functions-framework": "^3.1.0" + "@google-cloud/bigquery": "^8.0.0", + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/functions/v2/helloGCS/package.json b/functions/v2/helloGCS/package.json index 307aac23920..dee47f2ab54 100644 --- a/functions/v2/helloGCS/package.json +++ b/functions/v2/helloGCS/package.json @@ -9,16 +9,16 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.0.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0" diff --git a/functions/v2/helloPubSub/package.json b/functions/v2/helloPubSub/package.json index 3ef5283e1b1..34908baa443 100644 --- a/functions/v2/helloPubSub/package.json +++ b/functions/v2/helloPubSub/package.json @@ -9,16 +9,16 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.0.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0", diff --git a/functions/v2/httpLogging/package.json b/functions/v2/httpLogging/package.json index 2466e871189..97bbc94fa29 100644 --- a/functions/v2/httpLogging/package.json +++ b/functions/v2/httpLogging/package.json @@ -6,18 +6,18 @@ "author": "Google LLC", "main": "index.js", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js", "start": "npx @google-cloud/functions-framework --target=structuredLogging" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.1", + "@google-cloud/functions-framework": "^5.0.0", "@google-cloud/logging": "^11.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/v2/imagemagick/package.json b/functions/v2/imagemagick/package.json index 1d23bc56f82..31a68f4bb1a 100644 --- a/functions/v2/imagemagick/package.json +++ b/functions/v2/imagemagick/package.json @@ -9,19 +9,19 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=18.17.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0", - "@google-cloud/storage": "^7.0.0", - "@google-cloud/vision": "^4.0.0", + "@google-cloud/functions-framework": "^5.0.0", + "@google-cloud/storage": "^8.0.0", + "@google-cloud/vision": "^5.0.0", "sharp": "^0.35.3" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0", diff --git a/functions/v2/log/processEntry/package.json b/functions/v2/log/processEntry/package.json index 8a63b117a4b..708230fa402 100644 --- a/functions/v2/log/processEntry/package.json +++ b/functions/v2/log/processEntry/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/v2/ocr/app/package.json b/functions/v2/ocr/app/package.json index c3351a28bff..87bea08eb24 100644 --- a/functions/v2/ocr/app/package.json +++ b/functions/v2/ocr/app/package.json @@ -9,21 +9,21 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.2.0", - "@google-cloud/pubsub": "^4.0.0", - "@google-cloud/storage": "^7.0.0", + "@google-cloud/functions-framework": "^5.0.0", + "@google-cloud/pubsub": "^5.0.0", + "@google-cloud/storage": "^8.0.0", "@google-cloud/translate": "^8.0.0", - "@google-cloud/vision": "^4.0.0", - "cloudevents": "^8.0.0" + "@google-cloud/vision": "^5.0.0", + "cloudevents": "^10.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0" diff --git a/functions/v2/responseStreaming/package.json b/functions/v2/responseStreaming/package.json index c8ea7719f4f..506953aab8b 100644 --- a/functions/v2/responseStreaming/package.json +++ b/functions/v2/responseStreaming/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=20000" }, "dependencies": { - "@google-cloud/bigquery": "^7.0.0", - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/bigquery": "^8.0.0", + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0" diff --git a/functions/v2/stopBilling/package.json b/functions/v2/stopBilling/package.json index 1f0a4b90864..62da1e3660e 100644 --- a/functions/v2/stopBilling/package.json +++ b/functions/v2/stopBilling/package.json @@ -14,11 +14,11 @@ "license": "Apache-2.0", "dependencies": { "@google-cloud/billing": "^5.1.0", - "@google-cloud/functions-framework": "^4.0.0", + "@google-cloud/functions-framework": "^5.0.0", "cloudevents": "^10.0.0", "gcp-metadata": "^7.0.1" }, "devDependencies": { - "c8": "^10.1.3" + "c8": "^12.0.0" } } \ No newline at end of file diff --git a/functions/v2/tips/avoidInfiniteRetries/package.json b/functions/v2/tips/avoidInfiniteRetries/package.json index d37623027c3..80d8c09f2f3 100644 --- a/functions/v2/tips/avoidInfiniteRetries/package.json +++ b/functions/v2/tips/avoidInfiniteRetries/package.json @@ -9,16 +9,16 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "sinon": "^18.0.0" } diff --git a/functions/v2/tips/retry/package.json b/functions/v2/tips/retry/package.json index 211ca2ef855..994051127b5 100644 --- a/functions/v2/tips/retry/package.json +++ b/functions/v2/tips/retry/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000 --exit" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/v2/typed/googlechatbot/package.json b/functions/v2/typed/googlechatbot/package.json index a14d5af6fcf..e0900a3b2b8 100644 --- a/functions/v2/typed/googlechatbot/package.json +++ b/functions/v2/typed/googlechatbot/package.json @@ -3,17 +3,20 @@ "version": "1.0.0", "description": "", "main": "index.js", + "engines": { + "node": ">=20.0.0" + }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "author": "", "license": "ISC", "dependencies": { - "@google-cloud/functions-framework": "^3.3.0" + "@google-cloud/functions-framework": "^3.1.3" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "sinon": "^18.0.0" } -} +} \ No newline at end of file diff --git a/functions/v2/typed/greeting/package.json b/functions/v2/typed/greeting/package.json index cdece30e7cc..2871ff1fcdf 100644 --- a/functions/v2/typed/greeting/package.json +++ b/functions/v2/typed/greeting/package.json @@ -3,17 +3,20 @@ "version": "1.0.0", "description": "", "main": "index.js", + "engines": { + "node": ">=20.0.0" + }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "author": "", "license": "ISC", "dependencies": { - "@google-cloud/functions-framework": "^3.3.0" + "@google-cloud/functions-framework": "^3.1.3" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "sinon": "^18.0.0" } -} +} \ No newline at end of file From 1b0d4ea40636cc7774a6f015c07ef32a839b1a46 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 22 Sep 2026 16:32:15 -0600 Subject: [PATCH 26/39] deps(functions): update dependencies in tips samples (#4476) --- functions/tips/avoidInfiniteRetries/package.json | 2 +- functions/tips/connectionPools/package.json | 4 ++-- functions/tips/gcpApiCall/package.json | 8 ++++---- functions/tips/lazyGlobals/package.json | 4 ++-- functions/tips/package.json | 4 ++-- functions/tips/retry/package.json | 4 ++-- functions/tips/scopeDemo/package.json | 6 +++--- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/functions/tips/avoidInfiniteRetries/package.json b/functions/tips/avoidInfiniteRetries/package.json index 126464fabc2..411ce197bc3 100644 --- a/functions/tips/avoidInfiniteRetries/package.json +++ b/functions/tips/avoidInfiniteRetries/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/tips/connectionPools/package.json b/functions/tips/connectionPools/package.json index 10324b6aa2e..39424c80927 100644 --- a/functions/tips/connectionPools/package.json +++ b/functions/tips/connectionPools/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2", + "@google-cloud/functions-framework": "^5.0.0", "node-fetch": "^3.0.0" }, "scripts": { diff --git a/functions/tips/gcpApiCall/package.json b/functions/tips/gcpApiCall/package.json index 2f9ff121cd6..ef38c000fde 100644 --- a/functions/tips/gcpApiCall/package.json +++ b/functions/tips/gcpApiCall/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3", - "@google-cloud/pubsub": "^4.0.0" + "@google-cloud/functions-framework": "^5.0.0", + "@google-cloud/pubsub": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.3", "sinon": "^18.0.0" diff --git a/functions/tips/lazyGlobals/package.json b/functions/tips/lazyGlobals/package.json index d74ec1d5614..6dc8bcb8a88 100644 --- a/functions/tips/lazyGlobals/package.json +++ b/functions/tips/lazyGlobals/package.json @@ -9,10 +9,10 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3" + "@google-cloud/functions-framework": "^5.0.0" }, "scripts": { "test": "echo \"No tests exist for this sample.\"" diff --git a/functions/tips/package.json b/functions/tips/package.json index db58b31e19d..63f0c7e22d4 100644 --- a/functions/tips/package.json +++ b/functions/tips/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "echo \"Notice: tests moved into topic sub-directories\" && exit 0" }, "dependencies": { - "@google-cloud/pubsub": "^4.0.0", + "@google-cloud/pubsub": "^5.0.0", "mocha": "^10.0.0" }, "devDependencies": { diff --git a/functions/tips/retry/package.json b/functions/tips/retry/package.json index 15209e7f66e..6ff47f4bca8 100644 --- a/functions/tips/retry/package.json +++ b/functions/tips/retry/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000 --exit" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/tips/scopeDemo/package.json b/functions/tips/scopeDemo/package.json index 9bd294252a0..7ca1d19582f 100644 --- a/functions/tips/scopeDemo/package.json +++ b/functions/tips/scopeDemo/package.json @@ -9,16 +9,16 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "sinon": "^18.0.0" } From b9d45f7ee70ca942ed8fcbe276f932ba111a655f Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Wed, 23 Sep 2026 15:08:58 -0600 Subject: [PATCH 27/39] deps(run): update dependencies across cloud run samples (#4478) --- run/hello-broken/package.json | 6 +++--- run/helloworld/package.json | 6 +++--- run/idp-sql/package.json | 6 +++--- run/image-processing/package.json | 10 +++++----- run/jobs/package.json | 4 ++-- run/logging-manual/package.json | 6 +++--- run/markdown-preview/editor/package.json | 4 ++-- run/markdown-preview/renderer/package.json | 4 ++-- run/pubsub/package.json | 6 +++--- run/system-package/package.json | 6 +++--- run/websockets/package.json | 8 ++++---- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/run/hello-broken/package.json b/run/hello-broken/package.json index 51273096534..e79639a4b49 100644 --- a/run/hello-broken/package.json +++ b/run/hello-broken/package.json @@ -10,15 +10,15 @@ "system-test": "NAME=Cloud c8 mocha -p -j 2 test/system.test.js --timeout=360000 --exit" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "author": "Google LLC", "license": "Apache-2.0", "dependencies": { - "express": "^4.17.1" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.0.0" diff --git a/run/helloworld/package.json b/run/helloworld/package.json index 62cccf4d378..619d9dac8e1 100644 --- a/run/helloworld/package.json +++ b/run/helloworld/package.json @@ -13,15 +13,15 @@ }, "type": "module", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "author": "Google LLC", "license": "Apache-2.0", "dependencies": { - "express": "^4.17.1" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.0.0", diff --git a/run/idp-sql/package.json b/run/idp-sql/package.json index 1febe629596..2887f46a0ae 100644 --- a/run/idp-sql/package.json +++ b/run/idp-sql/package.json @@ -10,7 +10,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -20,7 +20,7 @@ "test": "npm -- run all-test" }, "dependencies": { - "express": "^4.16.2", + "express": "^5.0.0", "firebase-admin": "^13.0.0", "gcp-metadata": "^6.0.0", "google-auth-library": "^9.0.0", @@ -30,7 +30,7 @@ "winston": "3.10.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "got": "^11.5.0", "mocha": "^10.0.0", "short-uuid": "^5.0.0", diff --git a/run/image-processing/package.json b/run/image-processing/package.json index 456795d83a5..63c15184d64 100644 --- a/run/image-processing/package.json +++ b/run/image-processing/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -19,13 +19,13 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=360000 --exit" }, "dependencies": { - "@google-cloud/storage": "^7.0.0", - "@google-cloud/vision": "^4.0.0", - "express": "^4.16.4", + "@google-cloud/storage": "^8.0.0", + "@google-cloud/vision": "^5.0.0", + "express": "^5.0.0", "sharp": "^0.35.3" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.0.0", diff --git a/run/jobs/package.json b/run/jobs/package.json index 4b7092aaff9..0d9da7f4e97 100644 --- a/run/jobs/package.json +++ b/run/jobs/package.json @@ -9,13 +9,13 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=600000 --exit" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "author": "Google LLC", "license": "Apache-2.0", "devDependencies": { "@google-cloud/logging": "^11.0.0", - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0" } } diff --git a/run/logging-manual/package.json b/run/logging-manual/package.json index 5098c9d6ca8..59db55cd668 100644 --- a/run/logging-manual/package.json +++ b/run/logging-manual/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -18,12 +18,12 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "express": "^4.17.1", + "express": "^5.0.0", "got": "^11.5.0" }, "devDependencies": { "@google-cloud/logging": "^11.0.0", - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "mocha": "^10.0.0" } diff --git a/run/markdown-preview/editor/package.json b/run/markdown-preview/editor/package.json index 61179d8b081..f17f5beda9c 100644 --- a/run/markdown-preview/editor/package.json +++ b/run/markdown-preview/editor/package.json @@ -22,13 +22,13 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=480000 --exit" }, "dependencies": { - "express": "^4.17.1", + "express": "^5.0.0", "google-auth-library": "^9.0.0", "got": "^14.6.5", "handlebars": "^4.7.8" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^11.0.0", "supertest": "^7.0.0" } diff --git a/run/markdown-preview/renderer/package.json b/run/markdown-preview/renderer/package.json index 6f7b5cf0bb2..825062c1553 100644 --- a/run/markdown-preview/renderer/package.json +++ b/run/markdown-preview/renderer/package.json @@ -21,11 +21,11 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=360000 --exit" }, "dependencies": { - "express": "^4.17.1", + "express": "^5.0.0", "markdown-it": "^14.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^14.6.5", "mocha": "^11.0.0", diff --git a/run/pubsub/package.json b/run/pubsub/package.json index b294e11e3bf..37be71844e5 100644 --- a/run/pubsub/package.json +++ b/run/pubsub/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node index.js", @@ -19,10 +19,10 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=360000 --exit" }, "dependencies": { - "express": "^4.16.4" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.0.0", diff --git a/run/system-package/package.json b/run/system-package/package.json index da69b8fc227..40be1e834e0 100644 --- a/run/system-package/package.json +++ b/run/system-package/package.json @@ -12,13 +12,13 @@ "system-test": "c8 mocha -p -j 2 test/system.test.js --timeout=360000 --exit" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "dependencies": { - "express": "^4.17.1" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.0.0", diff --git a/run/websockets/package.json b/run/websockets/package.json index f9c96b0be9a..2a7bc900f1e 100644 --- a/run/websockets/package.json +++ b/run/websockets/package.json @@ -12,17 +12,17 @@ "system-test": "echo \"INFO: system-test temporarily disabled\"" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { "@socket.io/redis-adapter": "^8.1.0", - "express": "^4.18.2", + "express": "^5.0.0", "redis": "^4.6.5", "socket.io": "4.7.2" }, "devDependencies": { - "@types/express": "^4.17.17", - "c8": "^10.0.0", + "@types/express": "^5.0.0", + "c8": "^12.0.0", "google-auth-library": "^9.0.0", "got": "^11.5.0", "mocha": "^10.2.0", From 5c71bb9483f1a566f047ccff6560e563669aee39 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 24 Sep 2026 10:16:19 -0600 Subject: [PATCH 28/39] chore(functions): update dependencies in firebase, helloworld, and http (#4470) * chore(functions): update dependencies in firebase, helloworld, and http * fix(functions): prevent TypeError on undefined req.body in helloworldHttp --- functions/firebase/helloAnalytics/package.json | 4 ++-- functions/firebase/helloAuth/package.json | 4 ++-- functions/firebase/helloFirestore/package.json | 4 ++-- functions/firebase/helloRTDB/package.json | 4 ++-- functions/firebase/helloRemoteConfig/package.json | 4 ++-- functions/firebase/makeUpperCase/package.json | 4 ++-- functions/firebase/package.json | 2 +- functions/helloworld/helloError/package.json | 4 ++-- functions/helloworld/helloGCS/package.json | 10 +++++----- functions/helloworld/helloPubSub/package.json | 10 +++++----- functions/helloworld/helloworldGet/package.json | 8 ++++---- functions/helloworld/helloworldHttp/index.js | 5 ++++- functions/helloworld/helloworldHttp/package.json | 8 ++++---- functions/helloworld/package.json | 10 +++++----- functions/http/corsEnabledFunction/package.json | 6 +++--- functions/http/corsEnabledFunctionAuth/package.json | 6 +++--- functions/http/httpContent/package.json | 6 +++--- functions/http/httpMethods/package.json | 6 +++--- functions/http/package.json | 4 ++-- functions/http/parseXML/package.json | 8 ++++---- functions/http/uploadFile/package.json | 6 +++--- 21 files changed, 63 insertions(+), 60 deletions(-) diff --git a/functions/firebase/helloAnalytics/package.json b/functions/firebase/helloAnalytics/package.json index ab6a3b72f16..3ec3ed64c00 100644 --- a/functions/firebase/helloAnalytics/package.json +++ b/functions/firebase/helloAnalytics/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/helloAuth/package.json b/functions/firebase/helloAuth/package.json index e0057948a47..b5746f1645e 100644 --- a/functions/firebase/helloAuth/package.json +++ b/functions/firebase/helloAuth/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/helloFirestore/package.json b/functions/firebase/helloFirestore/package.json index c010e65379a..a359322ec9b 100644 --- a/functions/firebase/helloFirestore/package.json +++ b/functions/firebase/helloFirestore/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/helloRTDB/package.json b/functions/firebase/helloRTDB/package.json index 2667d6317a0..9fe5cc7be21 100644 --- a/functions/firebase/helloRTDB/package.json +++ b/functions/firebase/helloRTDB/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/helloRemoteConfig/package.json b/functions/firebase/helloRemoteConfig/package.json index 4395f1d6c32..1d72a31d5b1 100644 --- a/functions/firebase/helloRemoteConfig/package.json +++ b/functions/firebase/helloRemoteConfig/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/makeUpperCase/package.json b/functions/firebase/makeUpperCase/package.json index 3ce9d984306..1d91542f6a4 100644 --- a/functions/firebase/makeUpperCase/package.json +++ b/functions/firebase/makeUpperCase/package.json @@ -9,13 +9,13 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 -T 30s test/*.test.js" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" diff --git a/functions/firebase/package.json b/functions/firebase/package.json index def14f3c833..9804ace5e90 100644 --- a/functions/firebase/package.json +++ b/functions/firebase/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "devDependencies": { "mocha": "^10.0.0", diff --git a/functions/helloworld/helloError/package.json b/functions/helloworld/helloError/package.json index 02515a50704..10b008e0f1f 100644 --- a/functions/helloworld/helloError/package.json +++ b/functions/helloworld/helloError/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --exit" @@ -18,7 +18,7 @@ "@google-cloud/functions-framework": "^3.1.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" } diff --git a/functions/helloworld/helloGCS/package.json b/functions/helloworld/helloGCS/package.json index 7378e4e8c7b..c0c722ef651 100644 --- a/functions/helloworld/helloGCS/package.json +++ b/functions/helloworld/helloGCS/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "unit-test": "c8 mocha -p -j 2 test/*unit*test.js test/*integration*test.js --timeout=6000 --exit", @@ -18,12 +18,12 @@ "test": "npm -- run unit-test" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "@google-cloud/storage": "^7.0.0", - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "@google-cloud/storage": "^8.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "moment": "^2.24.0", "promise-retry": "^2.0.0", diff --git a/functions/helloworld/helloPubSub/package.json b/functions/helloworld/helloPubSub/package.json index e8a1635f7d6..36216176b15 100644 --- a/functions/helloworld/helloPubSub/package.json +++ b/functions/helloworld/helloPubSub/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "unit-test": "c8 mocha -p -j 2 test/*unit*test.js test/*integration*test.js --timeout=6000 --exit", @@ -18,12 +18,12 @@ "test": "npm -- run unit-test" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "@google-cloud/pubsub": "^4.0.0", - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "@google-cloud/pubsub": "^5.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "moment": "^2.29.4", "promise-retry": "^2.0.0", diff --git a/functions/helloworld/helloworldGet/package.json b/functions/helloworld/helloworldGet/package.json index d17681b8eb0..f1f71f438b4 100644 --- a/functions/helloworld/helloworldGet/package.json +++ b/functions/helloworld/helloworldGet/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=6000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "wait-port": "^1.0.4" } diff --git a/functions/helloworld/helloworldHttp/index.js b/functions/helloworld/helloworldHttp/index.js index 755ee694211..123896248e5 100644 --- a/functions/helloworld/helloworldHttp/index.js +++ b/functions/helloworld/helloworldHttp/index.js @@ -26,6 +26,9 @@ const escapeHtml = require('escape-html'); * @param {Object} res Cloud Function response context. */ functions.http('helloHttp', (req, res) => { - res.send(`Hello ${escapeHtml(req.query.name || req.body.name || 'World')}!`); + const name = + (req.query && req.query.name) || (req.body && req.body.name) || 'World'; + + res.send(`Hello ${escapeHtml(name)}!`); }); // [END functions_helloworld_http] diff --git a/functions/helloworld/helloworldHttp/package.json b/functions/helloworld/helloworldHttp/package.json index 97c20ad23d6..7dd26451041 100644 --- a/functions/helloworld/helloworldHttp/package.json +++ b/functions/helloworld/helloworldHttp/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "unit-test": "c8 mocha -p -j 2 test/index.test.js test/*unit*test.js test/*integration*test.js --timeout=6000 --exit", @@ -18,12 +18,12 @@ "test": "npm -- run unit-test" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.0", + "@google-cloud/functions-framework": "^5.0.0", "escape-html": "^1.0.3" }, "devDependencies": { - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0", "supertest": "^7.0.0", diff --git a/functions/helloworld/package.json b/functions/helloworld/package.json index 3517b5cfa58..28851389fe1 100644 --- a/functions/helloworld/package.json +++ b/functions/helloworld/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { "@google-cloud/debug-agent": "^9.0.0", - "@google-cloud/functions-framework": "^3.1.0", + "@google-cloud/functions-framework": "^5.0.0", "escape-html": "^1.0.3" }, "devDependencies": { - "@google-cloud/pubsub": "^4.0.0", - "@google-cloud/storage": "^7.0.0", - "gaxios": "^6.0.0", + "@google-cloud/pubsub": "^5.0.0", + "@google-cloud/storage": "^8.0.0", + "gaxios": "^7.0.0", "mocha": "^10.0.0", "moment": "^2.24.0", "promise-retry": "^2.0.0", diff --git a/functions/http/corsEnabledFunction/package.json b/functions/http/corsEnabledFunction/package.json index 69bed9ba37f..474bf26e634 100644 --- a/functions/http/corsEnabledFunction/package.json +++ b/functions/http/corsEnabledFunction/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/http/corsEnabledFunctionAuth/package.json b/functions/http/corsEnabledFunctionAuth/package.json index 1bc7a3b3710..1f0d87af1b3 100644 --- a/functions/http/corsEnabledFunctionAuth/package.json +++ b/functions/http/corsEnabledFunctionAuth/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/http/httpContent/package.json b/functions/http/httpContent/package.json index 3ff8581ba8f..a25719d0ce6 100644 --- a/functions/http/httpContent/package.json +++ b/functions/http/httpContent/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2", + "@google-cloud/functions-framework": "^5.0.0", "escape-html": "^1.0.3" } } diff --git a/functions/http/httpMethods/package.json b/functions/http/httpMethods/package.json index 9837db712af..9d77ad3ef43 100644 --- a/functions/http/httpMethods/package.json +++ b/functions/http/httpMethods/package.json @@ -9,17 +9,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=60000" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2" + "@google-cloud/functions-framework": "^5.0.0" } } diff --git a/functions/http/package.json b/functions/http/package.json index 84c1de6e1a5..de86896f152 100644 --- a/functions/http/package.json +++ b/functions/http/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "devDependencies": { "mocha": "^10.0.0", @@ -17,7 +17,7 @@ "sinon": "^18.0.0" }, "dependencies": { - "@google-cloud/storage": "^7.0.0", + "@google-cloud/storage": "^8.0.0", "busboy": "^1.6.0", "escape-html": "^1.0.3" } diff --git a/functions/http/parseXML/package.json b/functions/http/parseXML/package.json index 3b4eddc6f09..15ef2e1e79b 100644 --- a/functions/http/parseXML/package.json +++ b/functions/http/parseXML/package.json @@ -9,18 +9,18 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 test/*.test.js --timeout=6000 --exit" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.2", + "@google-cloud/functions-framework": "^5.0.0", "xml2js": "^0.6.0" }, "devDependencies": { - "c8": "^10.0.0", - "gaxios": "^6.0.0", + "c8": "^12.0.0", + "gaxios": "^7.0.0", "mocha": "^10.2.0", "wait-port": "^1.0.4" } diff --git a/functions/http/uploadFile/package.json b/functions/http/uploadFile/package.json index c58b7362e3b..5af7243eafb 100644 --- a/functions/http/uploadFile/package.json +++ b/functions/http/uploadFile/package.json @@ -9,11 +9,11 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/functions-framework": "^3.1.3", - "@google-cloud/storage": "^7.0.0", + "@google-cloud/functions-framework": "^5.0.0", + "@google-cloud/storage": "^8.0.0", "busboy": "^1.0.0" } } From 44511ebe71028c8b9a230da9e809f5bb8a00c06d Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 25 Sep 2026 13:18:40 -0600 Subject: [PATCH 29/39] deps(appengine): update dependencies across appengine samples (#4479) * deps(appengine): update dependencies across appengine samples * fix(appengine): update supertest request payload format in building-an-app test * chore(appengine): update node engine to 20 in storage standard sample --- appengine/analytics/package.json | 6 +++--- appengine/building-an-app/build/package.json | 6 +++--- appengine/building-an-app/update/package.json | 6 +++--- .../building-an-app/update/test/server.test.js | 4 +++- appengine/datastore/package.json | 8 ++++---- appengine/endpoints/package.json | 4 ++-- appengine/hello-world/flexible/package.json | 6 +++--- appengine/hello-world/standard/package.json | 6 +++--- appengine/memcached/package.json | 8 ++++---- appengine/metadata/flexible/package.json | 6 +++--- appengine/metadata/standard/package.json | 6 +++--- appengine/pubsub/package.json | 10 +++++----- appengine/static-files/package.json | 6 +++--- appengine/storage/flexible/package.json | 14 +++++++------- appengine/storage/standard/package.json | 16 ++++++++-------- appengine/typescript/package.json | 10 +++++----- appengine/websockets/package.json | 6 +++--- 17 files changed, 65 insertions(+), 63 deletions(-) diff --git a/appengine/analytics/package.json b/appengine/analytics/package.json index 6601ad1c21d..096a6cb611f 100644 --- a/appengine/analytics/package.json +++ b/appengine/analytics/package.json @@ -11,7 +11,7 @@ }, "type": "module", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", @@ -19,11 +19,11 @@ "test": "npm run system-test" }, "dependencies": { - "express": "^4.16.4", + "express": "^5.0.0", "node-fetch": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/building-an-app/build/package.json b/appengine/building-an-app/build/package.json index e73a78d1b24..bfd837d264b 100644 --- a/appengine/building-an-app/build/package.json +++ b/appengine/building-an-app/build/package.json @@ -14,15 +14,15 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": "24.x.x" + "node": ">=20.0.0" }, "author": "Google Inc.", "license": "Apache-2.0", "dependencies": { - "express": "^4.18.2" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/building-an-app/update/package.json b/appengine/building-an-app/update/package.json index c320fc64744..99f8e9007fe 100644 --- a/appengine/building-an-app/update/package.json +++ b/appengine/building-an-app/update/package.json @@ -14,15 +14,15 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": "20.x.x" + "node": ">=20.0.0" }, "author": "Google Inc.", "license": "Apache-2.0", "dependencies": { - "express": "^4.18.2" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.3", "sinon": "^18.0.0", diff --git a/appengine/building-an-app/update/test/server.test.js b/appengine/building-an-app/update/test/server.test.js index 0c3bcf138aa..349d2f9ba26 100755 --- a/appengine/building-an-app/update/test/server.test.js +++ b/appengine/building-an-app/update/test/server.test.js @@ -66,7 +66,9 @@ describe('gae_add_display_form', () => { describe('gae_add_post_handler gae_enable_parser', () => { it('should record message', async () => { await requestObj - .post('/submit', { + .post('/submit') + .type('form') + .send({ name: 'sample-user', message: 'sample-message', }) diff --git a/appengine/datastore/package.json b/appengine/datastore/package.json index 49cf16bb965..ff07c4fb0be 100644 --- a/appengine/datastore/package.json +++ b/appengine/datastore/package.json @@ -10,7 +10,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", @@ -18,11 +18,11 @@ "test": "npm run system-test" }, "dependencies": { - "@google-cloud/datastore": "^9.0.0", - "express": "^4.16.4" + "@google-cloud/datastore": "^10.0.0", + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/endpoints/package.json b/appengine/endpoints/package.json index e302c181716..77c2e4672df 100644 --- a/appengine/endpoints/package.json +++ b/appengine/endpoints/package.json @@ -10,7 +10,7 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "deploy": "gcloud app deploy", @@ -19,7 +19,7 @@ "test": "npm run unit-test" }, "dependencies": { - "express": "^4.16.4" + "express": "^5.0.0" }, "devDependencies": { "c8": "^10.0.0", diff --git a/appengine/hello-world/flexible/package.json b/appengine/hello-world/flexible/package.json index 0a4ed0ec62d..334f19882d4 100644 --- a/appengine/hello-world/flexible/package.json +++ b/appengine/hello-world/flexible/package.json @@ -10,17 +10,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", "test": "c8 mocha -p -j 2 --exit test/*.test.js" }, "dependencies": { - "express": "^4.17.1" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/hello-world/standard/package.json b/appengine/hello-world/standard/package.json index 9746fa5b433..6c5fb0cd2a2 100644 --- a/appengine/hello-world/standard/package.json +++ b/appengine/hello-world/standard/package.json @@ -10,17 +10,17 @@ "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", "test": "c8 mocha -p -j 2 --exit test/*.test.js" }, "dependencies": { - "express": "^4.17.1" + "express": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/memcached/package.json b/appengine/memcached/package.json index 264c3499dbb..ad21e06ec96 100644 --- a/appengine/memcached/package.json +++ b/appengine/memcached/package.json @@ -6,19 +6,19 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", "test": "c8 mocha -p -j 2 --exit test/*.test.js" }, "dependencies": { - "express": "^4.16.4", + "express": "^5.0.0", "memjs": "^1.2.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "wait-port": "^1.0.4" } diff --git a/appengine/metadata/flexible/package.json b/appengine/metadata/flexible/package.json index 4ff62dd3dbd..dc523a7538a 100644 --- a/appengine/metadata/flexible/package.json +++ b/appengine/metadata/flexible/package.json @@ -11,18 +11,18 @@ }, "type": "module", "engines": { - "node": ">= 18.x.x" + "node": ">=20.0.0" }, "scripts": { "system-test": "c8 mocha -p -j 2 --exit test/*.test.js", "test": "npm run system-test" }, "dependencies": { - "express": "^4.17.1", + "express": "^5.0.0", "node-fetch": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/metadata/standard/package.json b/appengine/metadata/standard/package.json index 7e4535ebc15..6fa48a088ec 100644 --- a/appengine/metadata/standard/package.json +++ b/appengine/metadata/standard/package.json @@ -11,18 +11,18 @@ }, "type": "module", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "system-test": "c8 mocha -p -j 2 --exit test/*.test.js", "test": "npm run system-test" }, "dependencies": { - "express": "^4.17.1", + "express": "^5.0.0", "node-fetch": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/pubsub/package.json b/appengine/pubsub/package.json index 95657ab8d93..75d13460ab8 100644 --- a/appengine/pubsub/package.json +++ b/appengine/pubsub/package.json @@ -6,21 +6,21 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", "test": "c8 mocha -p -j 2 test/*.test.js --timeout=30000 --exit" }, "dependencies": { - "@google-cloud/pubsub": "^4.0.0", - "express": "^4.17.1", + "@google-cloud/pubsub": "^5.0.0", + "express": "^5.0.0", "google-auth-library": "^9.0.0", "pug": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "jsonwebtoken": "^9.0.0", "mocha": "^10.0.0", "proxyquire": "^2.1.3", diff --git a/appengine/static-files/package.json b/appengine/static-files/package.json index 9445aee77f6..3784b3c8277 100644 --- a/appengine/static-files/package.json +++ b/appengine/static-files/package.json @@ -6,18 +6,18 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "start": "node app.js", "test": "c8 mocha -p -j 2 --exit test/*.test.js --url localhost:8080/static/main.css" }, "dependencies": { - "express": "^4.16.4", + "express": "^5.0.0", "pug": "^3.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "supertest": "^7.0.0" } diff --git a/appengine/storage/flexible/package.json b/appengine/storage/flexible/package.json index 3efffce5ced..06d0ea70a8c 100644 --- a/appengine/storage/flexible/package.json +++ b/appengine/storage/flexible/package.json @@ -9,18 +9,18 @@ "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/storage": "^7.0.0", - "express": "^4.18.2", + "@google-cloud/storage": "^8.0.0", + "express": "^5.0.0", "multer": "^2.1.1", "pug": "^3.0.2" }, "devDependencies": { - "@types/express": "^4.17.17", - "@types/multer": "^1.4.7", + "@types/express": "^5.0.0", + "@types/multer": "^2.0.0", "@types/proxyquire": "^1.3.28", - "@types/supertest": "^6.0.0", - "@types/uuid": "^10.0.0", - "c8": "^10.0.0", + "@types/supertest": "^7.0.0", + "@types/uuid": "^11.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", "supertest": "^7.0.0", diff --git a/appengine/storage/standard/package.json b/appengine/storage/standard/package.json index 273b7553ed1..06d0ea70a8c 100644 --- a/appengine/storage/standard/package.json +++ b/appengine/storage/standard/package.json @@ -6,21 +6,21 @@ "test": "c8 mocha -p -j 2 system-test/*.test.js --exit --timeout=30000" }, "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { - "@google-cloud/storage": "^7.0.0", - "express": "^4.18.2", + "@google-cloud/storage": "^8.0.0", + "express": "^5.0.0", "multer": "^2.1.1", "pug": "^3.0.2" }, "devDependencies": { - "@types/express": "^4.17.17", - "@types/multer": "^1.4.7", + "@types/express": "^5.0.0", + "@types/multer": "^2.0.0", "@types/proxyquire": "^1.3.28", - "@types/supertest": "^6.0.0", - "@types/uuid": "^10.0.0", - "c8": "^10.0.0", + "@types/supertest": "^7.0.0", + "@types/uuid": "^11.0.0", + "c8": "^12.0.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", "supertest": "^7.0.0", diff --git a/appengine/typescript/package.json b/appengine/typescript/package.json index be65b8723b2..461b343a8be 100644 --- a/appengine/typescript/package.json +++ b/appengine/typescript/package.json @@ -6,7 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": "20.x" + "node": ">=20.0.0" }, "scripts": { "prepare": "npm run gcp-build", @@ -23,13 +23,13 @@ }, "dependencies": { "@typescript-eslint/parser": "^8.0.0", - "express": "^4.16.3" + "express": "^5.0.0" }, "devDependencies": { - "@types/express": "^4.17.17", + "@types/express": "^5.0.0", "@types/node": "^20.0.0", - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "gts": "^5.0.0", "mocha": "^10.2.0", "typescript": "^5.0.0", diff --git a/appengine/websockets/package.json b/appengine/websockets/package.json index 411bf073d12..18fc3680599 100644 --- a/appengine/websockets/package.json +++ b/appengine/websockets/package.json @@ -6,7 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "deploy": "gcloud app deploy", @@ -15,13 +15,13 @@ "e2e-test": "samples test deploy" }, "dependencies": { - "express": "^4.15.4", + "express": "^5.0.0", "pug": "^3.0.0", "socket.io": "4.7.2", "supertest": "^7.0.0" }, "devDependencies": { - "c8": "^10.0.0", + "c8": "^12.0.0", "mocha": "^10.0.0", "puppeteer": "^23.0.0" } From c2a582d5c2a0ad344000840910a579a862bfe7b5 Mon Sep 17 00:00:00 2001 From: vidhishav-sudo Date: Sat, 26 Sep 2026 03:00:27 +0530 Subject: [PATCH 30/39] fix(functions): remove redundant res.end (#4489) * Fix HTTP response handling in httpTermination Updated HTTP response handling in httpTermination function to ensure proper termination signaling. * fix(functions): remove redundant res.end * fix(functions): remove redundant res.end * chore: fix lint errors --------- Co-authored-by: Angel Caamal --- functions/concepts/httpTermination/index.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/functions/concepts/httpTermination/index.js b/functions/concepts/httpTermination/index.js index f1fd5299987..b3f7409d70b 100644 --- a/functions/concepts/httpTermination/index.js +++ b/functions/concepts/httpTermination/index.js @@ -11,13 +11,9 @@ // 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'; - /* eslint-disable no-unused-vars, no-unreachable */ - const functions = require('@google-cloud/functions-framework'); - functions.http('httpTermination', async (req, res) => { // [START functions_concepts_node_termination_http] // OK: await-ing a Promise before sending an HTTP response @@ -29,8 +25,7 @@ functions.http('httpTermination', async (req, res) => { // HTTP functions should signal termination by returning an HTTP response. // This should not be done until all background tasks are complete. - res.send(200); - res.end(); + res.status(200).send(); // WRONG: this may not execute since an // HTTP response has already been sent. From 7067b9c837a891b1d16c3e778b71035b6ec11d15 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 28 Sep 2026 17:04:34 -0600 Subject: [PATCH 31/39] deps(speech): update dependencies across speech samples (#4487) --- speech/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/speech/package.json b/speech/package.json index edb13339dc6..909590d569e 100644 --- a/speech/package.json +++ b/speech/package.json @@ -5,7 +5,7 @@ "author": "Google LLC", "repository": "googleapis/nodejs-speech", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "files": [ "*.js", @@ -15,17 +15,17 @@ "test": "c8 mocha -p -j 2 system-test --timeout 600000" }, "dependencies": { - "@google-cloud/speech": "^6.0.0", - "@google-cloud/storage": "^7.0.0", - "chalk": "^5.0.0", + "@google-cloud/speech": "^7.0.0", + "@google-cloud/storage": "^8.0.0", + "chalk": "^6.0.0", "fs.promises": "^0.1.2", "node-record-lpcm16": "^1.0.1", "sinon": "^18.0.0", "yargs": "^17.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 6b75d1aa9fd7e543585e5a3a0ad6a2d9762a1fa1 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 28 Sep 2026 17:14:24 -0600 Subject: [PATCH 32/39] deps(model-armor): update dependencies across model-armor samples (#4485) * deps(model-armor): update dependencies across model-armor samples * fix(model-armor): comply with effective floor settings in test template * fix(model-armor): adjust jailbreak assertion and handle floor settings mutation timing --- model-armor/package.json | 8 ++++---- model-armor/test/modelarmor.test.js | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/model-armor/package.json b/model-armor/package.json index 2c72cef6480..6e5c62ba2af 100644 --- a/model-armor/package.json +++ b/model-armor/package.json @@ -8,18 +8,18 @@ "author": "Google LLC", "repository": "googleapis/nodejs-model-armor", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 --recursive test/ --timeout=60000" }, "dependencies": { - "@google-cloud/modelarmor": "^0.4.0", + "@google-cloud/modelarmor": "^0.9.0", "@google-cloud/dlp": "^6.3.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^5.2.1", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^11.7.1", "uuid": "^11.1.1" } diff --git a/model-armor/test/modelarmor.test.js b/model-armor/test/modelarmor.test.js index 8a2edbc59cc..35255debfca 100644 --- a/model-armor/test/modelarmor.test.js +++ b/model-armor/test/modelarmor.test.js @@ -292,6 +292,18 @@ describe('Model Armor tests', () => { // Create basic SDP template basicSdpTemplateId = `${templateIdPrefix}-basic-sdp`; await createTemplate(basicSdpTemplateId, { + raiSettings: { + raiFilters: [ + { + filterType: RaiFilterType.HARASSMENT, + confidenceLevel: DetectionConfidenceLevel.LOW_AND_ABOVE, + }, + { + filterType: RaiFilterType.SEXUALLY_EXPLICIT, + confidenceLevel: DetectionConfidenceLevel.LOW_AND_ABOVE, + }, + ], + }, sdpSettings: { basicConfig: { filterEnforcement: SdpBasicConfigEnforcement.ENABLED, @@ -714,10 +726,10 @@ describe('Model Armor tests', () => { 'MATCH_FOUND' ); - assert.equal( + assert.oneOf( response.sanitizationResult.filterResults.pi_and_jailbreak .piAndJailbreakFilterResult.confidenceLevel, - 'MEDIUM_AND_ABOVE' + ['HIGH', 'MEDIUM_AND_ABOVE'] ); }); @@ -876,6 +888,8 @@ describe('Model Armor tests', () => { }); describe('Model Armor floor setting tests', () => { + const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + before(async () => { projectId = await client.getProjectId(); }); @@ -885,6 +899,7 @@ describe('Model Armor floor setting tests', () => { }); it('should update organization floor settings', async () => { + await sleep(3000); const updateOrganizationFloorSettings = require('../snippets/updateOrganizationFloorSettings'); const output = await updateOrganizationFloorSettings.main(organizationId); // Check that the enableFloorSettingEnforcement=true @@ -892,6 +907,7 @@ describe('Model Armor floor setting tests', () => { }); it('should update folder floor settings', async () => { + await sleep(3000); const updateFolderFloorSettings = require('../snippets/updateFolderFloorSettings'); const output = await updateFolderFloorSettings.main(folderId); // Check that the enableFloorSettingEnforcement=true From 2e6e19f46640168660c141191f401596e70a5641 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 28 Sep 2026 17:20:07 -0600 Subject: [PATCH 33/39] deps(memorystore): update dependencies across redis samples (#4484) --- memorystore/redis/client_side_metrics/package.json | 6 +++--- memorystore/redis/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/memorystore/redis/client_side_metrics/package.json b/memorystore/redis/client_side_metrics/package.json index 4ccec3a57a6..74db9d08c53 100644 --- a/memorystore/redis/client_side_metrics/package.json +++ b/memorystore/redis/client_side_metrics/package.json @@ -6,7 +6,7 @@ "license": "Apache-2.0", "author": "Google Inc.", "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "repository": { "type": "git", @@ -21,7 +21,7 @@ "@opentelemetry/api": "^1.9.0", "@opentelemetry/instrumentation": "^0.205.0", "@opentelemetry/instrumentation-redis": "^0.67.0", - "@opentelemetry/resources": "^2.1.0", + "@opentelemetry/resources": "^2.10.0", "@opentelemetry/sdk-metrics": "^2.1.0", "@opentelemetry/sdk-trace-base": "^2.1.0", "@opentelemetry/sdk-trace-node": "^2.1.0", @@ -29,7 +29,7 @@ }, "devDependencies": { "mocha": "^10.0.0", - "chai": "^4.3.0", + "chai": "^6.0.0", "proxyquire": "^2.1.0", "sinon": "^15.0.0" } diff --git a/memorystore/redis/package.json b/memorystore/redis/package.json index fa63678aca9..07af72288e8 100644 --- a/memorystore/redis/package.json +++ b/memorystore/redis/package.json @@ -6,7 +6,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "dependencies": { "redis": "^4.0.0" From d985dcc1886eca5c4de4cdbc3e2a7117e8c17770 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 29 Sep 2026 08:54:10 -0600 Subject: [PATCH 34/39] deps(dialogflow): update dependencies across dialogflow samples (#4482) --- dialogflow/package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dialogflow/package.json b/dialogflow/package.json index 05b2b2f5372..d5fb3a54881 100644 --- a/dialogflow/package.json +++ b/dialogflow/package.json @@ -9,20 +9,20 @@ "resources" ], "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 system-test --timeout=600000" }, "dependencies": { - "@google-cloud/dialogflow": "^6.0.0", + "@google-cloud/dialogflow": "^7.0.0", "pb-util": "^1.0.0", "yargs": "^17.0.0", - "@google-cloud/functions-framework": "^3.2.0" + "@google-cloud/functions-framework": "^5.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mocha": "^10.0.0", "uuid": "^11.1.1" } From 0995e15b3320dca89e535103f51634a712997a27 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 29 Sep 2026 15:53:54 -0600 Subject: [PATCH 35/39] ci(iam-deny): update workflow to use Node.js 20 (#4492) --- .github/workflows/iam-deny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/iam-deny.yaml b/.github/workflows/iam-deny.yaml index cf9830de479..9e16fdf8e19 100644 --- a/.github/workflows/iam-deny.yaml +++ b/.github/workflows/iam-deny.yaml @@ -57,7 +57,7 @@ jobs: - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0 with: - node-version: 16 + node-version: 20 - name: Get npm cache directory id: npm-cache-dir From 7a45f6d1fcb8aa956db23a6d406c77fb47128f6c Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 1 Oct 2026 09:53:03 -0600 Subject: [PATCH 36/39] deps(dlp): update dependencies across dlp samples (#4483) --- dlp/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dlp/package.json b/dlp/package.json index 6ae2b1aaf5b..4fd50deef25 100644 --- a/dlp/package.json +++ b/dlp/package.json @@ -9,19 +9,19 @@ "*.js" ], "engines": { - "node": ">=16.0.0" + "node": ">=20.0.0" }, "scripts": { "test": "c8 mocha -p -j 2 system-test/*.test.js --timeout=600000" }, "dependencies": { - "@google-cloud/dlp": "^5.0.0", - "@google-cloud/pubsub": "^4.0.0", - "@google-cloud/storage": "^7.0.0" + "@google-cloud/dlp": "^6.0.0", + "@google-cloud/pubsub": "^5.0.0", + "@google-cloud/storage": "^8.0.0" }, "devDependencies": { - "c8": "^10.0.0", - "chai": "^4.5.0", + "c8": "^12.0.0", + "chai": "^6.0.0", "mime": "^3.0.0", "mocha": "^10.0.0", "pixelmatch": "^5.3.0", From 20861290abe3b74508d8c622d7070380c33cdc6e Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 1 Oct 2026 11:57:05 -0600 Subject: [PATCH 37/39] chore(spanner): update dependencies (#4466) * chore(spanner): update dependencies * fix(spanner): resolve peer dependency conflict for opentelemetry --- spanner/package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spanner/package.json b/spanner/package.json index f370e55ff79..cf1373dc2e1 100644 --- a/spanner/package.json +++ b/spanner/package.json @@ -22,17 +22,17 @@ "yargs": "^17.0.0" }, "devDependencies": { - "@google-cloud/opentelemetry-cloud-trace-exporter": "^2.4.1", + "@google-cloud/opentelemetry-cloud-trace-exporter": "^3.0.0", "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1", + "@opentelemetry/core": "^2.0.0", "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0", "@opentelemetry/instrumentation": "^0.57.0", "@opentelemetry/instrumentation-grpc": "^0.57.0", - "@opentelemetry/resources": "1.30.1", - "@opentelemetry/sdk-trace-base": "~1.30.1", - "@opentelemetry/sdk-trace-node": "^1.30.1", - "chai": "^4.2.0", + "@opentelemetry/resources": "2.10.0", + "@opentelemetry/sdk-trace-base": "~2.10.0", + "@opentelemetry/sdk-trace-node": "^2.0.0", + "chai": "^6.0.0", "mocha": "^9.0.0", "p-limit": "^3.0.1" } -} +} \ No newline at end of file From 8a86d39cfe0e64da29adb960599d958c15c49ccd Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 2 Oct 2026 14:41:23 -0600 Subject: [PATCH 38/39] chore(datacatalog): decommission region tags for removed samples (#4497) --- datacatalog/cloud-client/createEntryGroup.js | 2 -- datacatalog/cloud-client/createFilesetEntry.js | 2 -- datacatalog/snippets/createCustomEntry.js | 2 -- datacatalog/snippets/createFileset.js | 2 -- datacatalog/snippets/grantTagTemplateUserRole.js | 2 -- datacatalog/snippets/policyTagManager/createPolicyTag.js | 2 -- datacatalog/snippets/policyTagManager/createTaxonomy.js | 2 -- datacatalog/snippets/policyTagManager/deleteTaxonomy.js | 2 -- datacatalog/snippets/policyTagManager/getTaxonomy.js | 2 -- datacatalog/snippets/policyTagManager/listTaxonomies.js | 2 -- datacatalog/snippets/quickstart.js | 2 -- datacatalog/snippets/searchAssets.js | 2 -- 12 files changed, 24 deletions(-) diff --git a/datacatalog/cloud-client/createEntryGroup.js b/datacatalog/cloud-client/createEntryGroup.js index 57336495a6e..6bebabe2449 100644 --- a/datacatalog/cloud-client/createEntryGroup.js +++ b/datacatalog/cloud-client/createEntryGroup.js @@ -25,7 +25,6 @@ const main = async ( projectId = process.env.GOOGLE_CLOUD_PROJECT, entryGroupId ) => { - // [START data_catalog_create_entry_group] // ------------------------------- // Import required modules. // ------------------------------- @@ -58,7 +57,6 @@ const main = async ( const [response] = await datacatalog.createEntryGroup(entryGroupRequest); console.log(response); - // [END data_catalog_create_entry_group] }; // node createEntryGroup.js diff --git a/datacatalog/cloud-client/createFilesetEntry.js b/datacatalog/cloud-client/createFilesetEntry.js index efbdea5c660..a78a9d5a72c 100644 --- a/datacatalog/cloud-client/createFilesetEntry.js +++ b/datacatalog/cloud-client/createFilesetEntry.js @@ -26,7 +26,6 @@ const main = async ( entryGroupId, entryId ) => { - // [START data_catalog_create_fileset] // ------------------------------- // Import required modules. // ------------------------------- @@ -100,7 +99,6 @@ const main = async ( const [response] = await datacatalog.createEntry(request); console.log(response); - // [END data_catalog_create_fileset] }; // node createFilesetEntry.js diff --git a/datacatalog/snippets/createCustomEntry.js b/datacatalog/snippets/createCustomEntry.js index a160a809302..edc5f827bcd 100644 --- a/datacatalog/snippets/createCustomEntry.js +++ b/datacatalog/snippets/createCustomEntry.js @@ -15,7 +15,6 @@ 'use strict'; async function main(projectId, entryGroupId, entryId, tagTemplateId) { - // [START data_catalog_create_custom_entry] // Import the Google Cloud client library. const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; const datacatalog = new DataCatalogClient(); @@ -185,6 +184,5 @@ async function main(projectId, entryGroupId, entryId, tagTemplateId) { console.log(`Created tag: ${createdTag.name}`); } createCustomEntry(); - // [END data_catalog_create_custom_entry] } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/createFileset.js b/datacatalog/snippets/createFileset.js index ef528d12e5c..89cc5a0698e 100644 --- a/datacatalog/snippets/createFileset.js +++ b/datacatalog/snippets/createFileset.js @@ -15,7 +15,6 @@ 'use strict'; async function main(projectId, entryGroupId, entryId) { - // [START data_catalog_create_fileset] // Import the Google Cloud client library. const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; const datacatalog = new DataCatalogClient(); @@ -137,6 +136,5 @@ async function main(projectId, entryGroupId, entryId) { console.log(`Type: ${response.type}`); } createFileset(); - // [END data_catalog_create_fileset] } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/grantTagTemplateUserRole.js b/datacatalog/snippets/grantTagTemplateUserRole.js index 7b64308e198..338d0568d7a 100644 --- a/datacatalog/snippets/grantTagTemplateUserRole.js +++ b/datacatalog/snippets/grantTagTemplateUserRole.js @@ -15,7 +15,6 @@ 'use strict'; async function main(projectId, templateId, memberId) { - // [START data_catalog_grant_tag_template_user_role] // Import the Google Cloud client library. const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; const datacatalog = new DataCatalogClient(); @@ -64,6 +63,5 @@ async function main(projectId, templateId, memberId) { }); } grantTagTemplateUserRole(); - // [END data_catalog_grant_tag_template_user_role] } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/policyTagManager/createPolicyTag.js b/datacatalog/snippets/policyTagManager/createPolicyTag.js index 820a0657980..75b9d42d882 100644 --- a/datacatalog/snippets/policyTagManager/createPolicyTag.js +++ b/datacatalog/snippets/policyTagManager/createPolicyTag.js @@ -15,7 +15,6 @@ 'use strict'; function main(parent) { - // [START data_catalog_ptm_create_policytag] // Create a policy tag resource under a given parent taxonomy. // Import the Google Cloud client library. @@ -49,7 +48,6 @@ function main(parent) { process.exitCode = 1; } } - // [END data_catalog_ptm_create_policytag] createPolicyTag(); } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/policyTagManager/createTaxonomy.js b/datacatalog/snippets/policyTagManager/createTaxonomy.js index 542d0c9fafd..0140b6a86eb 100644 --- a/datacatalog/snippets/policyTagManager/createTaxonomy.js +++ b/datacatalog/snippets/policyTagManager/createTaxonomy.js @@ -15,7 +15,6 @@ 'use strict'; function main(projectId, location, displayName) { - // [START data_catalog_ptm_create_taxonomy] // Import the Google Cloud client library. const {DataCatalogClient, PolicyTagManagerClient} = require('@google-cloud/datacatalog').v1; @@ -50,7 +49,6 @@ function main(projectId, location, displayName) { process.exitCode = 1; } } - // [END data_catalog_ptm_create_taxonomy] createTaxonomy(); } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/policyTagManager/deleteTaxonomy.js b/datacatalog/snippets/policyTagManager/deleteTaxonomy.js index 597ca826338..a6dd84af0fe 100644 --- a/datacatalog/snippets/policyTagManager/deleteTaxonomy.js +++ b/datacatalog/snippets/policyTagManager/deleteTaxonomy.js @@ -15,7 +15,6 @@ 'use strict'; function main(taxonomyName) { - // [START data_catalog_ptm_delete_taxonomy] // Import the Google Cloud client library. const {PolicyTagManagerClient} = require('@google-cloud/datacatalog').v1; const policyTagManager = new PolicyTagManagerClient(); @@ -41,7 +40,6 @@ function main(taxonomyName) { process.exitCode = 1; } } - // [END data_catalog_ptm_delete_taxonomy] deleteTaxonomy(); } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/policyTagManager/getTaxonomy.js b/datacatalog/snippets/policyTagManager/getTaxonomy.js index dbf3a59a3cb..f8b7305be43 100644 --- a/datacatalog/snippets/policyTagManager/getTaxonomy.js +++ b/datacatalog/snippets/policyTagManager/getTaxonomy.js @@ -15,7 +15,6 @@ 'use strict'; function main(taxonomyName) { - // [START data_catalog_ptm_get_taxonomy] // Import the Google Cloud client library. const {PolicyTagManagerClient} = require('@google-cloud/datacatalog').v1; const policyTagManager = new PolicyTagManagerClient(); @@ -41,7 +40,6 @@ function main(taxonomyName) { process.exitCode = 1; } } - // [END data_catalog_ptm_get_taxonomy] getTaxonomy(); } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/policyTagManager/listTaxonomies.js b/datacatalog/snippets/policyTagManager/listTaxonomies.js index fcfa23b8c92..57be82b29ba 100644 --- a/datacatalog/snippets/policyTagManager/listTaxonomies.js +++ b/datacatalog/snippets/policyTagManager/listTaxonomies.js @@ -15,7 +15,6 @@ 'use strict'; function main(projectId, location) { - // [START data_catalog_ptm_list_taxonomies] // Import the Google Cloud client library. const {DataCatalogClient, PolicyTagManagerClient} = require('@google-cloud/datacatalog').v1; @@ -47,7 +46,6 @@ function main(projectId, location) { process.exitCode = 1; } } - // [END data_catalog_ptm_list_taxonomies] listTaxonomies(); } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/quickstart.js b/datacatalog/snippets/quickstart.js index 9e8ef194635..3aaa7a92d75 100644 --- a/datacatalog/snippets/quickstart.js +++ b/datacatalog/snippets/quickstart.js @@ -15,7 +15,6 @@ 'use strict'; async function main(projectId, datasetId, tableId) { - // [START data_catalog_quickstart] // Import the Google Cloud client library and create a client. const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; const datacatalog = new DataCatalogClient(); @@ -165,6 +164,5 @@ async function main(projectId, datasetId, tableId) { console.log(`Tag created for entry: ${entry.name}`); } quickstart(); - // [END data_catalog_quickstart] } main(...process.argv.slice(2)); diff --git a/datacatalog/snippets/searchAssets.js b/datacatalog/snippets/searchAssets.js index 53ac4960832..c59cbca57f6 100644 --- a/datacatalog/snippets/searchAssets.js +++ b/datacatalog/snippets/searchAssets.js @@ -15,7 +15,6 @@ 'use strict'; async function main(projectId) { - // [START data_catalog_search_assets] // Import the Google Cloud client library. const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; const datacatalog = new DataCatalogClient(); @@ -52,6 +51,5 @@ async function main(projectId) { }); } searchAssets(); - // [END data_catalog_search_assets] } main(...process.argv.slice(2)); From 59991a7586198a69c06eaa2b0d3dab05a682d679 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Fri, 2 Oct 2026 16:23:08 -0600 Subject: [PATCH 39/39] chore(datacatalog): remove decommissioned quickstart sample (#4498) --- datacatalog/quickstart/createFilesetEntry.js | 130 ------------------ datacatalog/quickstart/deleteFilesetEntry.js | 77 ----------- datacatalog/quickstart/package.json | 23 ---- .../system-test/createFilesetEntry.test.js | 65 --------- .../system-test/deleteFilesetEntry.test.js | 61 -------- 5 files changed, 356 deletions(-) delete mode 100644 datacatalog/quickstart/createFilesetEntry.js delete mode 100644 datacatalog/quickstart/deleteFilesetEntry.js delete mode 100644 datacatalog/quickstart/package.json delete mode 100644 datacatalog/quickstart/system-test/createFilesetEntry.test.js delete mode 100644 datacatalog/quickstart/system-test/deleteFilesetEntry.test.js diff --git a/datacatalog/quickstart/createFilesetEntry.js b/datacatalog/quickstart/createFilesetEntry.js deleted file mode 100644 index 87dd94e265d..00000000000 --- a/datacatalog/quickstart/createFilesetEntry.js +++ /dev/null @@ -1,130 +0,0 @@ -// 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'; - -/** - * This application demonstrates how to create an Entry Group and a fileset - * Entry with the Cloud Data Catalog API. - - * For more information, see the README.md under /datacatalog and the - * documentation at https://cloud.google.com/data-catalog/docs. - */ -const main = async ( - projectId = process.env.GOOGLE_CLOUD_PROJECT, - entryGroupId, - entryId -) => { - // [START data_catalog_create_fileset_quickstart] - // ------------------------------- - // Import required modules. - // ------------------------------- - const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; - const datacatalog = new DataCatalogClient(); - - // ------------------------------- - // Currently, Data Catalog stores metadata in the - // us-central1 region. - // ------------------------------- - const location = 'us-central1'; - - // TODO(developer): Uncomment the following lines before running the sample. - // const projectId = 'my-project' - // const entryGroupId = 'my-entry-group' - // const entryId = 'my-entry' - - // ------------------------------- - // 1. Create an Entry Group. - // ------------------------------- - // Construct the EntryGroup for the EntryGroup request. - const entryGroup = { - displayName: 'My Fileset Entry Group', - description: 'This Entry Group consists of ...', - }; - - // Construct the EntryGroup request to be sent by the client. - const entryGroupRequest = { - parent: datacatalog.locationPath(projectId, location), - entryGroupId: entryGroupId, - entryGroup: entryGroup, - }; - - // Use the client to send the API request. - await datacatalog.createEntryGroup(entryGroupRequest); - - // ------------------------------- - // 2. Create a Fileset Entry. - // ------------------------------- - // Construct the Entry for the Entry request. - const FILESET_TYPE = 4; - - const entry = { - displayName: 'My Fileset', - description: 'This fileset consists of ...', - gcsFilesetSpec: {filePatterns: ['gs://my_bucket/*']}, - schema: { - columns: [ - { - column: 'city', - description: 'City', - mode: 'NULLABLE', - type: 'STRING', - }, - { - column: 'state', - description: 'State', - mode: 'NULLABLE', - type: 'STRING', - }, - { - column: 'addresses', - description: 'Addresses', - mode: 'REPEATED', - subcolumns: [ - { - column: 'city', - description: 'City', - mode: 'NULLABLE', - type: 'STRING', - }, - { - column: 'state', - description: 'State', - mode: 'NULLABLE', - type: 'STRING', - }, - ], - type: 'RECORD', - }, - ], - }, - type: FILESET_TYPE, - }; - - // Construct the Entry request to be sent by the client. - const request = { - parent: datacatalog.entryGroupPath(projectId, location, entryGroupId), - entryId: entryId, - entry: entry, - }; - - // Use the client to send the API request. - const [response] = await datacatalog.createEntry(request); - - console.log(response); -}; -// [END data_catalog_create_fileset_quickstart] - -// node createFilesetEntry.js -main(...process.argv.slice(2)); diff --git a/datacatalog/quickstart/deleteFilesetEntry.js b/datacatalog/quickstart/deleteFilesetEntry.js deleted file mode 100644 index 6459d24b5d1..00000000000 --- a/datacatalog/quickstart/deleteFilesetEntry.js +++ /dev/null @@ -1,77 +0,0 @@ -// 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'; - -/** - * This application demonstrates how to delete a fileset Entry and an - * Entry Group with the Cloud Data Catalog API. - - * For more information, see the README.md under /datacatalog and the - * documentation at https://cloud.google.com/data-catalog/docs. - */ -const main = async ( - projectId = process.env.GOOGLE_CLOUD_PROJECT, - entryGroupId, - entryId -) => { - // [START data_catalog_delete_fileset_quickstart] - // ------------------------------- - // Import required modules. - // ------------------------------- - const {DataCatalogClient} = require('@google-cloud/datacatalog').v1; - const datacatalog = new DataCatalogClient(); - - // ------------------------------- - // Currently, Data Catalog stores metadata in the - // us-central1 region. - // ------------------------------- - const location = 'us-central1'; - - // TODO(developer): Uncomment the following lines before running the sample. - // const projectId = 'my-project' - // const entryGroupId = 'my-entry-group' - // const entryId = 'my-entry' - - // ------------------------------- - // 1. Delete a Fileset Entry. - // ------------------------------- - const formattedName = datacatalog.entryPath( - projectId, - location, - entryGroupId, - entryId - ); - await datacatalog.deleteEntry({name: formattedName}); - console.log(`Deleted entry ${formattedName}`); - - // ------------------------------- - // 2. Delete an Entry Group. - // ------------------------------- - try { - const formattedName = datacatalog.entryGroupPath( - projectId, - location, - entryGroupId - ); - await datacatalog.deleteEntryGroup({name: formattedName}); - console.log(`Deleted entry group ${formattedName}`); - } catch (err) { - console.log('Entry Group does not exist or is not empty.'); - } -}; -// [END data_catalog_delete_fileset_quickstart] - -// node deleteFilesetEntry.js -main(...process.argv.slice(2)); diff --git a/datacatalog/quickstart/package.json b/datacatalog/quickstart/package.json deleted file mode 100644 index 1fd1c4c55a7..00000000000 --- a/datacatalog/quickstart/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@google-cloud/datacatalog-quickstart", - "version": "0.0.1", - "private": true, - "description": "Quickstart guides for the Cloud Data Catalog client library for Node.js", - "license": "Apache-2.0", - "author": "Google LLC", - "repository": "GoogleCloudPlatform/nodejs-docs-samples", - "engines": { - "node": ">=16.0.0" - }, - "scripts": { - "test": "c8 mocha -p -j 2 system-test/*.test.js --timeout=60000" - }, - "devDependencies": { - "c8": "^10.0.0", - "mocha": "^10.0.0", - "uuid": "^11.1.1" - }, - "dependencies": { - "@google-cloud/datacatalog": "^4.0.0" - } -} diff --git a/datacatalog/quickstart/system-test/createFilesetEntry.test.js b/datacatalog/quickstart/system-test/createFilesetEntry.test.js deleted file mode 100644 index 0c5eba4d039..00000000000 --- a/datacatalog/quickstart/system-test/createFilesetEntry.test.js +++ /dev/null @@ -1,65 +0,0 @@ -// 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 assert = require('assert'); -const uuid = require('uuid'); -const cwd = path.join(__dirname, '..'); -const {exec} = require('child_process'); - -const location = 'us-central1'; -// Use unique id to avoid conflicts between concurrent test runs -const entryGroupId = `fileset_entry_group_${uuid.v4().substr(0, 8)}`; -const entryId = `fileset_entry_id_${uuid.v4().substr(0, 8)}`; - -const {DataCatalogClient} = require('@google-cloud/datacatalog').v1beta1; -const datacatalog = new DataCatalogClient(); - -let projectId; -before(async () => { - const client = new DataCatalogClient(); - projectId = await client.getProjectId(); -}); - -describe('createFilesetEntry', () => { - it('should create a fileset entry', done => { - const expectedLinkedResource = `//datacatalog.googleapis.com/projects/${projectId}/locations/${location}/entryGroups/${entryGroupId}/entries/${entryId}`; - exec( - `node createFilesetEntry.js ${projectId} ${entryGroupId} ${entryId}`, - {cwd}, - (err, stdout) => { - assert.ok(stdout.includes(expectedLinkedResource)); - done(); - } - ); - }); - - after(async () => { - const entryPath = datacatalog.entryPath( - projectId, - location, - entryGroupId, - entryId - ); - await datacatalog.deleteEntry({name: entryPath}); - const entryGroupPath = datacatalog.entryGroupPath( - projectId, - location, - entryGroupId - ); - await datacatalog.deleteEntryGroup({name: entryGroupPath}); - }); -}); diff --git a/datacatalog/quickstart/system-test/deleteFilesetEntry.test.js b/datacatalog/quickstart/system-test/deleteFilesetEntry.test.js deleted file mode 100644 index 6907d9a6f7d..00000000000 --- a/datacatalog/quickstart/system-test/deleteFilesetEntry.test.js +++ /dev/null @@ -1,61 +0,0 @@ -// 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 assert = require('assert'); -const uuid = require('uuid'); -const cwd = path.join(__dirname, '..'); -const {exec} = require('child_process'); - -const location = 'us-central1'; -// Use unique id to avoid conflicts between concurrent test runs -const entryGroupId = `fileset_entry_group_${uuid.v4().substr(0, 8)}`; -const entryId = `fileset_entry_id_${uuid.v4().substr(0, 8)}`; - -const {DataCatalogClient} = require('@google-cloud/datacatalog').v1beta1; -const datacatalog = new DataCatalogClient(); - -let projectId; -before(async () => { - const client = new DataCatalogClient(); - projectId = await client.getProjectId(); -}); - -describe('deleteFilesetEntry', () => { - before(done => { - // Must create an entry to be deleted. - exec( - `node createFilesetEntry.js ${projectId} ${entryGroupId} ${entryId}`, - {cwd}, - done - ); - }); - - it('should delete a fileset entry', done => { - exec( - `node deleteFilesetEntry.js ${projectId} ${entryGroupId} ${entryId}`, - {cwd}, - (err, stdout) => { - assert.ok( - stdout.includes( - datacatalog.entryGroupPath(projectId, location, entryGroupId) - ) - ); - done(); - } - ); - }); -});