From 346f92849aaba3c57f2ac359265ae5cd679bd237 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 27 Mar 2025 15:48:43 +1100 Subject: [PATCH 1/5] chore(ci): migrate datastore/functions to new ci --- .github/config/nodejs-dev.jsonc | 1 + datastore/functions/index.js | 14 +-- datastore/functions/package.json | 1 + datastore/functions/test/index.test.js | 114 ++++++++++++------------- 4 files changed, 66 insertions(+), 64 deletions(-) diff --git a/.github/config/nodejs-dev.jsonc b/.github/config/nodejs-dev.jsonc index d5023eb78b..147714b6ab 100644 --- a/.github/config/nodejs-dev.jsonc +++ b/.github/config/nodejs-dev.jsonc @@ -113,6 +113,7 @@ "datacatalog/quickstart", "datacatalog/snippets", "datalabeling", + "datastore/functions", "dialogflow", "discoveryengine", "document-warehouse", diff --git a/datastore/functions/index.js b/datastore/functions/index.js index 35f30da559..9016334857 100644 --- a/datastore/functions/index.js +++ b/datastore/functions/index.js @@ -14,7 +14,7 @@ 'use strict'; -const {Datastore} = require('@google-cloud/datastore'); +import { Datastore } from '@google-cloud/datastore'; // Instantiates a client const datastore = new Datastore(); @@ -58,7 +58,7 @@ const getKeyFromRequestData = requestData => { * @param {object} req.body.value Value to save to Cloud Datastore, e.g. {"description":"Buy milk"} * @param {object} res Cloud Function response context. */ -exports.set = async (req, res) => { +export async function set(req, res) { // The value contains a JSON document representing the entity we want to save if (!req.body.value) { const err = makeErrorObj('Value'); @@ -80,7 +80,7 @@ exports.set = async (req, res) => { console.error(new Error(err.message)); // Add to Stackdriver Error Reporting res.status(500).send(err.message); } -}; +} /** * Retrieves a record. @@ -94,7 +94,7 @@ exports.set = async (req, res) => { * @param {string} req.body.key Key at which to retrieve the data, e.g. "sampletask1". * @param {object} res Cloud Function response context. */ -exports.get = async (req, res) => { +export async function get(req, res) { try { const key = await getKeyFromRequestData(req.body); const [entity] = await datastore.get(key); @@ -110,7 +110,7 @@ exports.get = async (req, res) => { console.error(new Error(err.message)); // Add to Stackdriver Error Reporting res.status(500).send(err.message); } -}; +} /** * Deletes a record. @@ -124,7 +124,7 @@ exports.get = async (req, res) => { * @param {string} req.body.key Key at which to delete data, e.g. "sampletask1". * @param {object} res Cloud Function response context. */ -exports.del = async (req, res) => { +export async function del(req, res) { // Deletes the entity // The delete operation will not fail for a non-existent entity, it just // doesn't delete anything @@ -136,4 +136,4 @@ exports.del = async (req, res) => { console.error(new Error(err.message)); // Add to Stackdriver Error Reporting res.status(500).send(err.message); } -}; +} diff --git a/datastore/functions/package.json b/datastore/functions/package.json index 38aca02bee..09ad958057 100644 --- a/datastore/functions/package.json +++ b/datastore/functions/package.json @@ -7,6 +7,7 @@ "type": "git", "url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git" }, + "type": "module", "engines": { "node": ">=16.0.0" }, diff --git a/datastore/functions/test/index.test.js b/datastore/functions/test/index.test.js index b683d8ffbb..01c5d53ad4 100644 --- a/datastore/functions/test/index.test.js +++ b/datastore/functions/test/index.test.js @@ -14,22 +14,22 @@ 'use strict'; -const assert = require('assert'); -const execPromise = require('child-process-promise').exec; -const path = require('path'); -const uuid = require('uuid'); -const sinon = require('sinon'); -const fetch = require('node-fetch'); -const waitPort = require('wait-port'); -const {Datastore} = require('@google-cloud/datastore'); +import { ok, strictEqual, deepStrictEqual } from 'assert'; +import { exec as execPromise } from 'child-process-promise'; +import { join } from 'path'; +import { v4 } from 'uuid'; +import { stub } from 'sinon'; +import fetch from 'node-fetch'; +import waitPort from 'wait-port'; +import { Datastore } from '@google-cloud/datastore'; const datastore = new Datastore(); -const program = require('../'); +import { set, get, del } from '../'; const FF_TIMEOUT = 3000; -const cwd = path.join(__dirname, '..'); +const cwd = join(__dirname, '..'); const NAME = 'sampletask1'; -const KIND = `Task-${uuid.v4()}`; +const KIND = `Task-${v4()}`; const VALUE = { description: 'Buy milk', }; @@ -72,14 +72,14 @@ describe('functions/datastore', () => { body: {}, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.set(req, res); + await set(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Value'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Value'))); }); it('set: Fails without a key', async () => { @@ -89,12 +89,12 @@ describe('functions/datastore', () => { }, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.set(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Key'))); + await set(req, res); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Key'))); }); it('set: Fails without a kind', async () => { @@ -105,14 +105,14 @@ describe('functions/datastore', () => { }, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.set(req, res); + await set(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Kind'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Kind'))); }); it('set: Saves an entity', async () => { @@ -125,9 +125,9 @@ describe('functions/datastore', () => { }), headers: {'Content-Type': 'application/json'}, }); - assert.strictEqual(response.status, 200); + strictEqual(response.status, 200); const body = await response.text(); - assert.ok(body.includes(`Entity ${KIND}/${NAME} saved`)); + ok(body.includes(`Entity ${KIND}/${NAME} saved`)); }); }); @@ -159,9 +159,9 @@ describe('functions/datastore', () => { validateStatus: () => true, }); - assert.strictEqual(response.status, 500); + strictEqual(response.status, 500); const body = await response.text(); - assert.ok( + ok( new RegExp( /(Missing or insufficient permissions.)|(No entity found for key)/ ).test(body) @@ -177,9 +177,9 @@ describe('functions/datastore', () => { }), headers: {'Content-Type': 'application/json'}, }); - assert.strictEqual(response.status, 200); + strictEqual(response.status, 200); const body = await response.json(); - assert.deepStrictEqual(body, { + deepStrictEqual(body, { description: 'Buy milk', }); }); @@ -189,14 +189,14 @@ describe('functions/datastore', () => { body: {}, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.get(req, res); + await get(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Key'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Key'))); }); it('get: Fails without a kind', async () => { @@ -206,14 +206,14 @@ describe('functions/datastore', () => { }, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.get(req, res); + await get(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Kind'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Kind'))); }); }); @@ -239,14 +239,14 @@ describe('functions/datastore', () => { body: {}, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.del(req, res); + await del(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Key'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Key'))); }); it('del: Fails without a kind', async () => { @@ -256,14 +256,14 @@ describe('functions/datastore', () => { }, }; const res = { - status: sinon.stub().returnsThis(), - send: sinon.stub(), + status: stub().returnsThis(), + send: stub(), }; - await program.del(req, res); + await del(req, res); - assert.ok(res.status.calledWith(500)); - assert.ok(res.send.calledWith(errorMsg('Kind'))); + ok(res.status.calledWith(500)); + ok(res.send.calledWith(errorMsg('Kind'))); }); it("del: Doesn't fail when entity does not exist", async () => { @@ -275,9 +275,9 @@ describe('functions/datastore', () => { }), headers: {'Content-Type': 'application/json'}, }); - assert.strictEqual(response.status, 200); + strictEqual(response.status, 200); const body = await response.text(); - assert.strictEqual(body, `Entity ${KIND}/nonexistent deleted.`); + strictEqual(body, `Entity ${KIND}/nonexistent deleted.`); }); it('del: Deletes an entity', async () => { @@ -289,13 +289,13 @@ describe('functions/datastore', () => { }), headers: {'Content-Type': 'application/json'}, }); - assert.strictEqual(response.status, 200); + strictEqual(response.status, 200); const body = await response.text(); - assert.strictEqual(body, `Entity ${KIND}/${NAME} deleted.`); + strictEqual(body, `Entity ${KIND}/${NAME} deleted.`); const key = datastore.key([KIND, NAME]); const [entity] = await datastore.get(key); - assert.ok(!entity); + ok(!entity); }); }); }); From 598a83f4cf400f3ac31719cbcfb9b5bce1e8e681 Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 27 Mar 2025 15:51:53 +1100 Subject: [PATCH 2/5] fix --- .github/config/nodejs-prod.jsonc | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/config/nodejs-prod.jsonc b/.github/config/nodejs-prod.jsonc index 36697a34d7..0cb4511647 100644 --- a/.github/config/nodejs-prod.jsonc +++ b/.github/config/nodejs-prod.jsonc @@ -84,7 +84,6 @@ "cloud-sql/sqlserver/tedious", // (untested) TypeError: The "config.server" property is required and must be of type string. "compute", // GoogleError: The resource 'projects/long-door-651/zones/us-central1-a/disks/disk-from-pool-name' was not found "dataproc", // GoogleError: Error submitting create cluster request: Multiple validation errors - "datastore/functions", // [ERR_REQUIRE_ESM]: require() of ES Module "dialogflow-cx", // NOT_FOUND: com.google.apps.framework.request.NotFoundException: Agent 'undefined' does not exist "dlp", // [ERR_REQUIRE_ESM]: require() of ES Module "document-ai", // [ERR_REQUIRE_ESM]: require() of ES Module From 8e13e97d84ebdf3fbd319a5f442c6b980bc505ef Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Thu, 27 Mar 2025 19:05:25 +1100 Subject: [PATCH 3/5] gts --- datastore/functions/index.js | 2 +- datastore/functions/test/index.test.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/datastore/functions/index.js b/datastore/functions/index.js index 9016334857..f9a1c288fa 100644 --- a/datastore/functions/index.js +++ b/datastore/functions/index.js @@ -14,7 +14,7 @@ 'use strict'; -import { Datastore } from '@google-cloud/datastore'; +import {Datastore} from '@google-cloud/datastore'; // Instantiates a client const datastore = new Datastore(); diff --git a/datastore/functions/test/index.test.js b/datastore/functions/test/index.test.js index 01c5d53ad4..27f31504e9 100644 --- a/datastore/functions/test/index.test.js +++ b/datastore/functions/test/index.test.js @@ -14,17 +14,17 @@ 'use strict'; -import { ok, strictEqual, deepStrictEqual } from 'assert'; -import { exec as execPromise } from 'child-process-promise'; -import { join } from 'path'; -import { v4 } from 'uuid'; -import { stub } from 'sinon'; +import {ok, strictEqual, deepStrictEqual} from 'assert'; +import {exec as execPromise} from 'child-process-promise'; +import {join} from 'path'; +import {v4} from 'uuid'; +import {stub} from 'sinon'; import fetch from 'node-fetch'; import waitPort from 'wait-port'; -import { Datastore } from '@google-cloud/datastore'; +import {Datastore} from '@google-cloud/datastore'; const datastore = new Datastore(); -import { set, get, del } from '../'; +import {set, get, del} from '../'; const FF_TIMEOUT = 3000; const cwd = join(__dirname, '..'); From dd6234aee48d0e68497ff8f39cd5a142f6cd22bf Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Fri, 28 Mar 2025 09:51:41 +1100 Subject: [PATCH 4/5] update deps --- datastore/functions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datastore/functions/package.json b/datastore/functions/package.json index 09ad958057..62c612fbb1 100644 --- a/datastore/functions/package.json +++ b/datastore/functions/package.json @@ -20,7 +20,7 @@ "devDependencies": { "@google-cloud/functions-framework": "^3.0.0", "c8": "^10.0.0", - "child-process-promise": "^2.2.1", + "child-process-promise": "^2.1.3", "mocha": "^10.0.0", "node-fetch": "^3.0.0", "proxyquire": "^2.1.0", From 5fabf8896e69c7807a41fab5db416a0d5f8f453c Mon Sep 17 00:00:00 2001 From: Katie McLaughlin Date: Fri, 28 Mar 2025 09:58:07 +1100 Subject: [PATCH 5/5] workaround? --- datastore/functions/test/index.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datastore/functions/test/index.test.js b/datastore/functions/test/index.test.js index 27f31504e9..4bc2cd4922 100644 --- a/datastore/functions/test/index.test.js +++ b/datastore/functions/test/index.test.js @@ -20,6 +20,8 @@ import {join} from 'path'; import {v4} from 'uuid'; import {stub} from 'sinon'; import fetch from 'node-fetch'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; import waitPort from 'wait-port'; import {Datastore} from '@google-cloud/datastore'; @@ -27,6 +29,8 @@ const datastore = new Datastore(); import {set, get, del} from '../'; const FF_TIMEOUT = 3000; +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); const cwd = join(__dirname, '..'); const NAME = 'sampletask1'; const KIND = `Task-${v4()}`;