From d89402c6ac913050b329a4b5180f93cd2d51c46c Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Tue, 3 Mar 2026 23:38:18 +0000 Subject: [PATCH 01/12] fix(healthcare): set responseType to JSON instead of Buffer --- healthcare/fhir/patchFhirStore.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/healthcare/fhir/patchFhirStore.js b/healthcare/fhir/patchFhirStore.js index c432731f8c..4b99a2267d 100644 --- a/healthcare/fhir/patchFhirStore.js +++ b/healthcare/fhir/patchFhirStore.js @@ -28,6 +28,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const patchFhirStore = async () => { @@ -50,10 +51,16 @@ const main = ( }, }; - await healthcare.projects.locations.datasets.fhirStores.patch(request); - console.log( - `Patched FHIR store ${fhirStoreId} with Cloud Pub/Sub topic ${pubsubTopic}` - ); + try { + const response = + await healthcare.projects.locations.datasets.fhirStores.patch(request); + console.log( + `Patched FHIR store ${fhirStoreId} with Cloud Pub/Sub topic ${pubsubTopic}` + ); + console.log(JSON.stringify(response.data, null, 2)); + } catch (error) { + console.error('Error patching FHIR store:', error.message || error); + } }; patchFhirStore(); From c14a1867a8d4ebeee4ccaff18f09b06db1b1168a Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Wed, 4 Mar 2026 19:12:04 +0000 Subject: [PATCH 02/12] fix(healthcare): set responseType to JSON instead of Buffer --- healthcare/fhir/getFhirStoreIamPolicy.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/healthcare/fhir/getFhirStoreIamPolicy.js b/healthcare/fhir/getFhirStoreIamPolicy.js index e31be8c2fc..27058590bc 100644 --- a/healthcare/fhir/getFhirStoreIamPolicy.js +++ b/healthcare/fhir/getFhirStoreIamPolicy.js @@ -27,6 +27,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const getFhirStoreIamPolicy = async () => { @@ -38,14 +39,21 @@ const main = ( const resource_ = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`; const request = {resource_}; - const fhirStore = - await healthcare.projects.locations.datasets.fhirStores.getIamPolicy( - request + try { + const fhirStore = + await healthcare.projects.locations.datasets.fhirStores.getIamPolicy( + request + ); + console.log( + 'Got FHIR store IAM policy:', + JSON.stringify(fhirStore.data, null, 2) ); - console.log( - 'Got FHIR store IAM policy:', - JSON.stringify(fhirStore.data, null, 2) - ); + } catch (error) { + console.error( + 'Error getting FHIR store IAM policy:', + error.message || error + ); + } }; getFhirStoreIamPolicy(); From eb7bc5c51ce2b1a8847b62eb39322fb839a77fff Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 5 Mar 2026 17:27:42 +0000 Subject: [PATCH 03/12] fix(healthcare): set responseType to JSON instead of Buffer --- healthcare/fhir/deleteFhirResource.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/healthcare/fhir/deleteFhirResource.js b/healthcare/fhir/deleteFhirResource.js index 49a432aab2..52016b5df8 100644 --- a/healthcare/fhir/deleteFhirResource.js +++ b/healthcare/fhir/deleteFhirResource.js @@ -29,6 +29,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const deleteFhirResource = async () => { @@ -46,10 +47,14 @@ const main = ( // fails, the server returns a 200 OK HTTP status code. To check that the // resource was successfully deleted, search for or get the resource and // see if it exists. - await healthcare.projects.locations.datasets.fhirStores.fhir.delete( - request - ); - console.log('Deleted FHIR resource'); + try { + await healthcare.projects.locations.datasets.fhirStores.fhir.delete( + request + ); + console.log(`Deleted FHIR resource: ${resourceId}`); + } catch (error) { + console.error('Error deleting FHIR resource:', error.message || error); + } }; deleteFhirResource(); From aedc47e110167f1d820b8d347c269d57665ed010 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 5 Mar 2026 17:38:57 +0000 Subject: [PATCH 04/12] fix(healthcare): set responseType to JSON instead of Buffer --- healthcare/fhir/deleteFhirResourcePurge.js | 13 +++++++++---- healthcare/fhir/system-test/fhir_resources.test.js | 4 +++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/healthcare/fhir/deleteFhirResourcePurge.js b/healthcare/fhir/deleteFhirResourcePurge.js index 16601b4f8b..1ee070e6ca 100644 --- a/healthcare/fhir/deleteFhirResourcePurge.js +++ b/healthcare/fhir/deleteFhirResourcePurge.js @@ -29,6 +29,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'blob', }); const deleteFhirResourcePurge = async () => { @@ -42,10 +43,14 @@ const main = ( const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}/fhir/${resourceType}/${resourceId}`; const request = {name}; - await healthcare.projects.locations.datasets.fhirStores.fhir.ResourcePurge( - request - ); - console.log('Deleted all historical versions of resource'); + try { + await healthcare.projects.locations.datasets.fhirStores.fhir.ResourcePurge( + request + ); + console.log(`Purged all historical versions of resource: ${resourceId}`); + } catch (error) { + console.error('Error purging FHIR resource:', error.message || error); + } }; deleteFhirResourcePurge(); diff --git a/healthcare/fhir/system-test/fhir_resources.test.js b/healthcare/fhir/system-test/fhir_resources.test.js index 61c09595fa..b7f2762bbd 100644 --- a/healthcare/fhir/system-test/fhir_resources.test.js +++ b/healthcare/fhir/system-test/fhir_resources.test.js @@ -163,7 +163,9 @@ it('should purge all historical versions of a FHIR resource', () => { {cwd} ); assert.strictEqual( - new RegExp('Deleted all historical versions of resource').test(output), + new RegExp( + `Purged all historical versions of resource: ${resourceId}` + ).test(output), true ); }); From c876688a5cac97227157954529aaf3b9494a37d7 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 5 Mar 2026 17:44:22 +0000 Subject: [PATCH 05/12] fix(healthcare): Fix test for delete resource --- healthcare/fhir/system-test/fhir_resources.test.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/healthcare/fhir/system-test/fhir_resources.test.js b/healthcare/fhir/system-test/fhir_resources.test.js index 61c09595fa..17769ff97b 100644 --- a/healthcare/fhir/system-test/fhir_resources.test.js +++ b/healthcare/fhir/system-test/fhir_resources.test.js @@ -181,7 +181,10 @@ it('should delete a FHIR resource', () => { `node deleteFhirResource.js ${projectId} ${cloudRegion} ${datasetId} ${fhirStoreId} ${resourceType} ${resourceId}`, {cwd} ); - assert.strictEqual(new RegExp('Deleted FHIR resource').test(output), true); + assert.strictEqual( + new RegExp(`Deleted FHIR resource: ${resourceId}`).test(output), + true + ); // Clean up execSync( From ae749ad2a1adc8c093ef6769af7d1d4ae1f8e09c Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 5 Mar 2026 17:49:48 +0000 Subject: [PATCH 06/12] fix(healthcare): Fix response type --- healthcare/fhir/deleteFhirResourcePurge.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/healthcare/fhir/deleteFhirResourcePurge.js b/healthcare/fhir/deleteFhirResourcePurge.js index 1ee070e6ca..cf1023aacb 100644 --- a/healthcare/fhir/deleteFhirResourcePurge.js +++ b/healthcare/fhir/deleteFhirResourcePurge.js @@ -29,7 +29,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), - responseType: 'blob', + responseType: 'json', }); const deleteFhirResourcePurge = async () => { From 90c5a4e42e75b63df694aada8bb1ffabaa32f1d9 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 9 Mar 2026 23:29:22 +0000 Subject: [PATCH 07/12] fix(healthcare): set responseType to JSON instead of Buffer --- healthcare/fhir/exportFhirResources.js | 35 +++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/healthcare/fhir/exportFhirResources.js b/healthcare/fhir/exportFhirResources.js index 1d538096f6..83f0d70ce7 100644 --- a/healthcare/fhir/exportFhirResources.js +++ b/healthcare/fhir/exportFhirResources.js @@ -28,6 +28,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const sleep = ms => { return new Promise(resolve => setTimeout(resolve, ms)); @@ -51,23 +52,29 @@ const main = ( }, }; - const operation = - await healthcare.projects.locations.datasets.fhirStores.export(request); - const operationName = operation.data.name; + try { + const operation = + await healthcare.projects.locations.datasets.fhirStores.export(request); + const operationName = operation.data.name; - // Wait ten seconds for the LRO to finish - await sleep(10000); + // Wait ten seconds for the LRO to finish + await sleep(10000); - // Check the LRO's status - const operationStatus = - await healthcare.projects.locations.datasets.operations.get({ - name: operationName, - }); + // Check the LRO's status + const operationStatus = + await healthcare.projects.locations.datasets.operations.get({ + name: operationName, + }); - if (typeof operationStatus.data.metadata.counter !== 'undefined') { - console.log('Exported FHIR resources successfully'); - } else { - console.log('Export failed'); + if (operationStatus.data.done && !operationStatus.data.error) { + console.log('Exported FHIR resources successfully'); + } else if (operationStatus.data.error) { + console.log('Export failed with error:', operationStatus.data.error); + } else { + console.log('Export operation is still in progress.'); + } + } catch (error) { + console.error('Error exporting FHIR resources:', error.message || error); } }; From 22c430b9b39df6c7c08ba79eb7070d154dabb388 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Mon, 9 Mar 2026 23:46:00 +0000 Subject: [PATCH 08/12] fix(healthcare): replace fixed sleep with polling for LRO and improve error logging --- healthcare/fhir/exportFhirResources.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/healthcare/fhir/exportFhirResources.js b/healthcare/fhir/exportFhirResources.js index 83f0d70ce7..ded96655da 100644 --- a/healthcare/fhir/exportFhirResources.js +++ b/healthcare/fhir/exportFhirResources.js @@ -57,21 +57,25 @@ const main = ( await healthcare.projects.locations.datasets.fhirStores.export(request); const operationName = operation.data.name; - // Wait ten seconds for the LRO to finish - await sleep(10000); + let done = false; + let operationStatus; - // Check the LRO's status - const operationStatus = - await healthcare.projects.locations.datasets.operations.get({ - name: operationName, - }); + while (!done) { + console.log('Waiting for operation to complete...'); + await sleep(5000); - if (operationStatus.data.done && !operationStatus.data.error) { - console.log('Exported FHIR resources successfully'); - } else if (operationStatus.data.error) { + operationStatus = + await healthcare.projects.locations.datasets.operations.get({ + name: operationName, + }); + + done = operationStatus.data.done; + } + + if (operationStatus.data.error) { console.log('Export failed with error:', operationStatus.data.error); } else { - console.log('Export operation is still in progress.'); + console.log('Exported FHIR resources successfully'); } } catch (error) { console.error('Error exporting FHIR resources:', error.message || error); From 7f13b7903bf4ed100b06da1e1568306483b062ee Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 30 Apr 2026 17:16:41 +0000 Subject: [PATCH 09/12] refactor(fhir): improve API response handling and fix test failures Configured fhirStore requests with responseType: 'json' for automatic parsing, resolving Node 20 ESM/Blob issues. Additionally, fixed the members array syntax in IAM policy payloads. --- healthcare/fhir/createFhirResource.js | 1 + healthcare/fhir/getFhirResourceHistory.js | 1 + healthcare/fhir/listFhirResourceHistory.js | 1 + healthcare/fhir/searchFhirResourcesPost.js | 23 +++++++++++++++++----- healthcare/fhir/setFhirStoreIamPolicy.js | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/healthcare/fhir/createFhirResource.js b/healthcare/fhir/createFhirResource.js index 1457b1079f..92a796f672 100644 --- a/healthcare/fhir/createFhirResource.js +++ b/healthcare/fhir/createFhirResource.js @@ -30,6 +30,7 @@ function main( scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), headers: {'Content-Type': 'application/fhir+json'}, + responseType: 'json', }); async function createFhirResource() { diff --git a/healthcare/fhir/getFhirResourceHistory.js b/healthcare/fhir/getFhirResourceHistory.js index 8dd56d6997..8a16badaf3 100644 --- a/healthcare/fhir/getFhirResourceHistory.js +++ b/healthcare/fhir/getFhirResourceHistory.js @@ -30,6 +30,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const getFhirResourceHistory = async () => { diff --git a/healthcare/fhir/listFhirResourceHistory.js b/healthcare/fhir/listFhirResourceHistory.js index acee5552e0..a4a207b740 100644 --- a/healthcare/fhir/listFhirResourceHistory.js +++ b/healthcare/fhir/listFhirResourceHistory.js @@ -29,6 +29,7 @@ const main = ( auth: new google.auth.GoogleAuth({ scopes: ['https://www.googleapis.com/auth/cloud-platform'], }), + responseType: 'json', }); const listFhirResourceHistory = async () => { diff --git a/healthcare/fhir/searchFhirResourcesPost.js b/healthcare/fhir/searchFhirResourcesPost.js index e7756d457f..d0fdc774b9 100644 --- a/healthcare/fhir/searchFhirResourcesPost.js +++ b/healthcare/fhir/searchFhirResourcesPost.js @@ -44,11 +44,24 @@ const main = ( // Patient with the last name "Smith", set resourceType to "Patient" and // specify the following params: // params = {'family:exact' : 'Smith'}; - const client = await auth.getClient(); - const response = await client.request({url, method: 'POST', params}); - const resources = response.data.entry; - console.log(`Resources found: ${resources.length}`); - console.log(JSON.stringify(resources, null, 2)); + + try { + const client = await auth.getClient(); + const response = await client.request({ + url, + method: 'POST', + params, + responseType: 'json', + }); + const resources = response.data.entry; + console.log(`Resources found: ${resources.length}`); + console.log(JSON.stringify(resources, null, 2)); + } catch (error) { + console.error( + `Error searching ${resourceType} resources:`, + error.response ? error.response.data : error.message + ); + } }; searchFhirResourcesPost(); diff --git a/healthcare/fhir/setFhirStoreIamPolicy.js b/healthcare/fhir/setFhirStoreIamPolicy.js index 3290f05db4..f750968f53 100644 --- a/healthcare/fhir/setFhirStoreIamPolicy.js +++ b/healthcare/fhir/setFhirStoreIamPolicy.js @@ -46,7 +46,7 @@ const main = ( policy: { bindings: [ { - members: member, + members: [member], role: role, }, ], From b1d70826a5c6f80ba8bea5f529b17f91d4a62214 Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 30 Apr 2026 17:31:57 +0000 Subject: [PATCH 10/12] fix(fhir): add missing Content-Type header to POST request --- healthcare/fhir/searchFhirResourcesPost.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/healthcare/fhir/searchFhirResourcesPost.js b/healthcare/fhir/searchFhirResourcesPost.js index d0fdc774b9..f379e6dfa0 100644 --- a/healthcare/fhir/searchFhirResourcesPost.js +++ b/healthcare/fhir/searchFhirResourcesPost.js @@ -28,8 +28,6 @@ const main = ( const searchFhirResourcesPost = async () => { const auth = new GoogleAuth({ scopes: 'https://www.googleapis.com/auth/cloud-platform', - // Set application/fhir+json header because this is a POST request. - headers: {'Content-Type': 'application/fhir+json'}, }); // TODO(developer): uncomment these lines before running the sample // const cloudRegion = 'us-central1'; @@ -50,6 +48,9 @@ const main = ( const response = await client.request({ url, method: 'POST', + headers: { + 'Content-Type': 'application/fhir+json', + }, params, responseType: 'json', }); From 7dca04792acc845f339c4f6c7b44e9fe33bc404b Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 30 Apr 2026 18:08:38 +0000 Subject: [PATCH 11/12] fix(healthcare): remove mocha parallel execution to prevent npm install race conditions in CI --- healthcare/fhir/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/healthcare/fhir/package.json b/healthcare/fhir/package.json index abb74033ed..683d4bec14 100644 --- a/healthcare/fhir/package.json +++ b/healthcare/fhir/package.json @@ -9,7 +9,7 @@ "node": ">=12.0.0" }, "scripts": { - "test": "c8 mocha -p -j 2 system-test/*.test.js --timeout=60000" + "test": "c8 mocha system-test/*.test.js --timeout=60000" }, "devDependencies": { "@google-cloud/pubsub": "^4.0.0", From 2d60e96c9c24aff84894478767fe5b5e5922189a Mon Sep 17 00:00:00 2001 From: Angel Caamal Date: Thu, 30 Apr 2026 18:15:24 +0000 Subject: [PATCH 12/12] fix(healthcare): apply code review feedback --- healthcare/fhir/searchFhirResourcesPost.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/healthcare/fhir/searchFhirResourcesPost.js b/healthcare/fhir/searchFhirResourcesPost.js index f379e6dfa0..2d6caa22bf 100644 --- a/healthcare/fhir/searchFhirResourcesPost.js +++ b/healthcare/fhir/searchFhirResourcesPost.js @@ -54,8 +54,8 @@ const main = ( params, responseType: 'json', }); - const resources = response.data.entry; - console.log(`Resources found: ${resources.length}`); + const resources = response.data.entry || []; + console.log('Resources found: ' + resources.length); console.log(JSON.stringify(resources, null, 2)); } catch (error) { console.error(