diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 686953002..036f93631 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -32,6 +32,7 @@ jobs: node-version: - 18.x - 20.x + - 22.x steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 @@ -52,6 +53,7 @@ jobs: node-version: - 18.x - 20.x + - 22.x steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2446e5f49..26846cc7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,3 @@ - Add an authPolicy callback to CallableOptions for reusable auth middleware as well as helper auth policies (#1650) +- Handle ESM functions codebases containing top-level awaits, which would break in node 22.12+ (#1651) - Multiple breaking changes to the not-yet-announced streaming feature for Callable Functions (#1652) diff --git a/scripts/bin-test/sources/esm-top-level-await/exports.js b/scripts/bin-test/sources/esm-top-level-await/exports.js new file mode 100644 index 000000000..50ece433e --- /dev/null +++ b/scripts/bin-test/sources/esm-top-level-await/exports.js @@ -0,0 +1,3 @@ +export const fn = () => { + return null; +} \ No newline at end of file diff --git a/scripts/bin-test/sources/esm-top-level-await/index.js b/scripts/bin-test/sources/esm-top-level-await/index.js new file mode 100644 index 000000000..05d2e5eca --- /dev/null +++ b/scripts/bin-test/sources/esm-top-level-await/index.js @@ -0,0 +1,8 @@ +import * as functionsv2 from "firebase-functions/v2"; + +const { fn } = await import('./exports.js'); + +export const v2http = functionsv2.https.onRequest((req, resp) => { + fn() + resp.status(200).send("PASS"); +}); diff --git a/scripts/bin-test/sources/esm-top-level-await/package.json b/scripts/bin-test/sources/esm-top-level-await/package.json new file mode 100644 index 000000000..9cb65cb9f --- /dev/null +++ b/scripts/bin-test/sources/esm-top-level-await/package.json @@ -0,0 +1,4 @@ +{ + "name": "esm", + "type": "module" +} diff --git a/src/runtime/loader.ts b/src/runtime/loader.ts index 953444e35..5c7af9553 100644 --- a/src/runtime/loader.ts +++ b/src/runtime/loader.ts @@ -48,8 +48,8 @@ async function loadModule(functionsDir: string) { try { return require(path.resolve(absolutePath)); } catch (e) { - if (e.code === "ERR_REQUIRE_ESM") { - // This is an ESM package! + if (e.code === "ERR_REQUIRE_ESM" || e.code === "ERR_REQUIRE_ASYNC_MODULE") { + // This is an ESM package, or one containing top-level awaits! const modulePath = require.resolve(absolutePath); // Resolve module path to file:// URL. Required for windows support. const moduleURL = url.pathToFileURL(modulePath).href;