Skip to content

Commit 94fd766

Browse files
Fix Node.js 22 strip-only loader regression in mocha setup (#1740)
* fix(tests): update import syntax for Node.js 22 compatibility Updates import syntax in test files to be compatible with the new experimental TypeScript loader enabled by default in Node.js v22.18.0+. Starting in v22.18.0, Node.js enables a "strip-only" mode for TypeScript files by default. This new loader is stricter and does not support certain TypeScript-specific syntax, such as `import = require()` declarations, which were previously handled by a separate transpiler. This change caused `TypeError` and `SyntaxError` exceptions during test runs. This commit replaces the incompatible syntax with standard ES module imports to resolve the test failures. * fix(tests): normalize mocha setup imports for node compatibility * lint: run formatter * fix(tests): normalize bin mocha setup imports * fix(tests): normalize js-yaml import for bin tests * fix(tests): swap bin manifest parser to yaml * fix linter issue. * Update mocha/setup.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 5e2c5f8 commit 94fd766

File tree

7 files changed

+49
-19
lines changed

7 files changed

+49
-19
lines changed

mocha/setup.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import * as chai from "chai";
2-
import * as chaiAsPromised from "chai-as-promised";
3-
import * as nock from "nock";
2+
import * as chaiAsPromisedModule from "chai-as-promised";
3+
import * as nockModule from "nock";
4+
5+
// Normalize CommonJS exports so ts-node (Node.js 20) and Node.js 22's strip-only loader
6+
// both receive callable modules without relying on esModuleInterop.
7+
type ChaiPlugin = Parameters<typeof chai.use>[0];
8+
type NockModule = typeof nockModule;
9+
10+
const chaiAsPromisedExport = chaiAsPromisedModule as ChaiPlugin & { default?: ChaiPlugin };
11+
const chaiAsPromised = chaiAsPromisedExport.default ?? chaiAsPromisedExport;
12+
const nockExport = nockModule as NockModule & { default?: NockModule };
13+
const nock = nockExport.default ?? nockExport;
414

515
chai.use(chaiAsPromised);
616

package-lock.json

Lines changed: 14 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,6 @@
301301
"eslint-plugin-prettier": "^4.0.0",
302302
"firebase-admin": "^13.0.0",
303303
"genkit": "^1.0.0-rc.4",
304-
"js-yaml": "^3.13.1",
305304
"jsdom": "^16.2.1",
306305
"jsonwebtoken": "^9.0.0",
307306
"jwk-to-pem": "^2.0.5",
@@ -317,6 +316,7 @@
317316
"sinon": "^9.2.4",
318317
"ts-node": "^10.4.0",
319318
"typescript": "^4.3.5",
319+
"yaml": "^2.8.1",
320320
"yargs": "^15.3.1"
321321
},
322322
"peerDependencies": {

scripts/bin-test/mocha-setup.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
import * as chai from "chai";
2-
import * as chaiAsPromised from "chai-as-promised";
2+
import * as chaiAsPromisedModule from "chai-as-promised";
3+
4+
// Match the runtime shim in mocha/setup.ts so bin tests work on Node.js 20 ts-node
5+
// and Node.js 22's strip-only TypeScript loader without enabling esModuleInterop.
6+
type ChaiPlugin = Parameters<typeof chai.use>[0];
7+
8+
const chaiAsPromisedExport = chaiAsPromisedModule as ChaiPlugin & { default?: ChaiPlugin };
9+
const chaiAsPromised = chaiAsPromisedExport.default ?? chaiAsPromisedExport;
310

411
chai.use(chaiAsPromised);

scripts/bin-test/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as fs from "fs/promises";
55
import * as os from "os";
66

77
import { expect } from "chai";
8-
import * as yaml from "js-yaml";
8+
import { parse as parseYaml } from "yaml";
99
import fetch from "node-fetch";
1010
import * as portfinder from "portfinder";
1111

@@ -177,7 +177,7 @@ async function runHttpDiscovery(modulePath: string): Promise<DiscoveryResult> {
177177
const body = await res.text();
178178

179179
if (res.status === 200) {
180-
const manifest = yaml.load(body) as Record<string, unknown>;
180+
const manifest = parseYaml(body) as Record<string, unknown>;
181181
return { success: true, manifest };
182182
} else {
183183
return { success: false, error: body };

spec/common/config.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@
2323
import { expect } from "chai";
2424
import * as fs from "fs";
2525
import * as process from "process";
26-
import Sinon = require("sinon");
26+
import * as sinon from "sinon";
2727

2828
import { firebaseConfig, resetCache } from "../../src/common/config";
2929

3030
describe("firebaseConfig()", () => {
31-
let readFileSync: Sinon.SinonStub;
32-
let cwdStub: Sinon.SinonStub;
31+
let readFileSync: sinon.SinonStub;
32+
let cwdStub: sinon.SinonStub;
3333

3434
before(() => {
35-
readFileSync = Sinon.stub(fs, "readFileSync");
35+
readFileSync = sinon.stub(fs, "readFileSync");
3636
readFileSync.throws("Unexpected call");
37-
cwdStub = Sinon.stub(process, "cwd");
37+
cwdStub = sinon.stub(process, "cwd");
3838
cwdStub.returns("/srv");
3939
});
4040

4141
after(() => {
42-
Sinon.verifyAndRestore();
42+
sinon.verifyAndRestore();
4343
});
4444

4545
afterEach(() => {

spec/v1/config.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@
2323
import { expect } from "chai";
2424
import * as fs from "fs";
2525
import * as process from "process";
26-
import Sinon = require("sinon");
26+
import * as sinon from "sinon";
2727

2828
import { config, resetCache } from "../../src/v1/config";
2929

3030
describe("config()", () => {
31-
let readFileSync: Sinon.SinonStub;
32-
let cwdStub: Sinon.SinonStub;
31+
let readFileSync: sinon.SinonStub;
32+
let cwdStub: sinon.SinonStub;
3333

3434
before(() => {
35-
readFileSync = Sinon.stub(fs, "readFileSync");
35+
readFileSync = sinon.stub(fs, "readFileSync");
3636
readFileSync.throws("Unexpected call");
37-
cwdStub = Sinon.stub(process, "cwd");
37+
cwdStub = sinon.stub(process, "cwd");
3838
cwdStub.returns("/srv");
3939
});
4040

4141
after(() => {
42-
Sinon.verifyAndRestore();
42+
sinon.verifyAndRestore();
4343
});
4444

4545
afterEach(() => {

0 commit comments

Comments
 (0)