Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
"express": "^4.21.2",
"minimist": "^1.2.8",
"on-finished": "^2.3.0",
"read-package-up": "^11.0.0",
"semver": "^7.7.1"
"read-package-up": "^11.0.0"
},
"scripts": {
"test": "mocha build/test --recursive",
Expand Down Expand Up @@ -58,7 +57,6 @@
"@types/mocha": "^10.0.0",
"@types/node": "^22.13.14",
"@types/on-finished": "2.3.5",
"@types/semver": "^7.7.0",
"@types/sinon": "^17.0.4",
"@types/supertest": "6.0.3",
"gts": "6.0.2",
Expand Down
9 changes: 0 additions & 9 deletions src/async_local_storage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import * as semver from 'semver';
import {Request, Response} from './functions';
import {NextFunction} from 'express';
import {requiredNodeJsVersionForLogExecutionID} from './options';
import type {AsyncLocalStorage} from 'node:async_hooks';

export interface ExecutionContext {
Expand All @@ -16,13 +14,6 @@ export async function asyncLocalStorageMiddleware(
res: Response,
next: NextFunction,
) {
if (
semver.lt(process.versions.node, requiredNodeJsVersionForLogExecutionID)
) {
// Skip for unsupported Node.js version.
next();
return;
}
if (!asyncLocalStorage) {
const asyncHooks = await import('node:async_hooks');
asyncLocalStorage = new asyncHooks.AsyncLocalStorage();
Expand Down
8 changes: 6 additions & 2 deletions src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/

import * as path from 'path';
import * as semver from 'semver';
import {pathToFileURL} from 'url';
import {HandlerFunction} from './functions';
import {SignatureType} from './types';
Expand All @@ -31,6 +30,11 @@ import {getRegisteredFunction} from './function_registry';
// Exported for testing.
export const MIN_NODE_VERSION_ESMODULES = '13.2.0';

export const esModuleSupported = (() => {
const [major, minor] = process.versions.node.split('.', 2).map(Number);
return major > 13 || (major === 13 && minor >= 2);
})();

/**
* Determines whether the given module is an ES module.
*
Expand Down Expand Up @@ -104,7 +108,7 @@ export async function getUserFunction(
let functionModule;
const esModule = await isEsModule(functionModulePath);
if (esModule) {
if (semver.lt(process.version, MIN_NODE_VERSION_ESMODULES)) {
if (esModuleSupported === false) {
console.error(
`Cannot load ES Module on Node.js ${process.version}. ` +
`Please upgrade to Node.js v${MIN_NODE_VERSION_ESMODULES} and up.`,
Expand Down
14 changes: 6 additions & 8 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

import * as minimist from 'minimist';
import * as semver from 'semver';
import {resolve} from 'path';
import {SignatureType, isValidSignatureType} from './types';

Expand Down Expand Up @@ -141,24 +140,23 @@ const IgnoredRoutesOption = new ConfigurableOption<string | null>(
);

export const requiredNodeJsVersionForLogExecutionID = '13.0.0';

export const logExecutionIdSupported =
Number(process.versions.node.split('.', 1)[0]) >= 13;

const ExecutionIdOption = new ConfigurableOption(
'log-execution-id',
'LOG_EXECUTION_ID',
false,
x => {
const nodeVersion = process.versions.node;
const isVersionSatisfied = semver.gte(
nodeVersion,
requiredNodeJsVersionForLogExecutionID,
);
const isTrue =
(typeof x === 'boolean' && x) ||
(typeof x === 'string' && x.toLowerCase() === 'true');
if (isTrue && !isVersionSatisfied) {
if (isTrue && !logExecutionIdSupported) {
console.warn(
`Execution id is only supported with Node.js versions
${requiredNodeJsVersionForLogExecutionID} and above. Your
current version is ${nodeVersion}. Please upgrade.`,
current version is ${process.versions.node}. Please upgrade.`,
);
console.warn('Proceeding with execution id support disabled...');
return false;
Expand Down
7 changes: 5 additions & 2 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {timeoutMiddleware} from './middleware/timeout';
import {wrapUserFunction} from './function_wrappers';
import {asyncLocalStorageMiddleware} from './async_local_storage';
import {executionContextMiddleware} from './execution_context';
import {FrameworkOptions} from './options';
import {FrameworkOptions, logExecutionIdSupported} from './options';

/**
* Creates and configures an Express application and returns an HTTP server
Expand Down Expand Up @@ -106,8 +106,11 @@ export function getServer(

// Get execution context.
app.use(executionContextMiddleware);

// Store execution context to async local storge.
app.use(asyncLocalStorageMiddleware);
if (logExecutionIdSupported) {
app.use(asyncLocalStorageMiddleware);
}

if (
options.signatureType === 'event' ||
Expand Down
4 changes: 2 additions & 2 deletions test/async_local_storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import {
import {Request, Response} from '../src/functions';
import {NextFunction} from 'express';
import * as assert from 'assert';
import * as semver from 'semver';
import {logExecutionIdSupported} from '../src/options';

const runOrSkip = semver.lt(process.versions.node, '13.0.0') ? it.skip : it;
const runOrSkip = logExecutionIdSupported ? it.skip : it;

describe('asyncLocalStorageMiddleware', () => {
runOrSkip('async local storage', async () => {
Expand Down
3 changes: 1 addition & 2 deletions test/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import * as assert from 'assert';
import * as express from 'express';
import * as semver from 'semver';
import * as functions from '../src/functions';
import * as loader from '../src/loader';
import * as FunctionRegistry from '../src/function_registry';
Expand Down Expand Up @@ -80,7 +79,7 @@ describe('loading function', () => {
);
return loadedFunction?.userFunction as functions.HttpFunction;
};
if (semver.lt(process.version, loader.MIN_NODE_VERSION_ESMODULES)) {
if (loader.esModuleSupported === false) {
it(`should fail to load function in an ES module ${test.name}`, async () => {
void assert.rejects(loadFn);
});
Expand Down
7 changes: 2 additions & 5 deletions test/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
// limitations under the License.

import * as assert from 'assert';
import * as semver from 'semver';
import {resolve} from 'path';
import {
parseOptions,
FrameworkOptions,
requiredNodeJsVersionForLogExecutionID,
logExecutionIdSupported,
} from '../src/options';

describe('parseOptions', () => {
Expand Down Expand Up @@ -202,9 +201,7 @@ describe('parseOptions', () => {
executionIdTestData.forEach(testCase => {
it(testCase.name, () => {
const options = parseOptions(testCase.cliOpts, testCase.envVars);
if (
semver.lt(process.versions.node, requiredNodeJsVersionForLogExecutionID)
) {
if (logExecutionIdSupported === false) {
assert.strictEqual(options.enableExecutionId, false);
} else {
assert.strictEqual(options.enableExecutionId, true);
Expand Down