Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: default (runtime) Node.js version #2794

Draft
wants to merge 9 commits into
base: v2
Choose a base branch
from
2 changes: 1 addition & 1 deletion src/kit/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { defineNitroPreset } from "./preset";
export { defineNitroPreset, getDefaultNodeVersion } from "./preset";
export { defineNitroModule } from "./module";

export { writeFile, isDirectory } from "./fs";
Expand Down
38 changes: 38 additions & 0 deletions src/kit/preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,41 @@ export function defineNitroPreset<
}
return { ...preset, _meta: meta } as P & { _meta: M };
}

const DEFAULT_NODE_VERSION = 20 as const;

/**
* Builder to get the default Node.js version for a provider.
*
* Ideally, all presets will support Nitro's preferred `DEFAULT_NODE_VERSION`,
* which will simply be converted to a preset-specific identifier.
* If not, it will return the highest supported version below `DEFAULT_NODE_VERSION`.
*
* @param supportedNodeVersions - A set of Node.js version numbers supported by the provider.
* @param getNodeVerisonString - A preset-specific function to convert a Node.js version number to the runtime string. Defaults to String constructor.
* @returns The Node.js version identifier for preset.
*/
export function getDefaultNodeVersion(
supportedNodeVersions: Set<number>,
getNodeVerisonString: (version: number) => string = String
): string {
// Get Nitro's current default Node.js version
let version = DEFAULT_NODE_VERSION;

// Check it is supported by the provider
if (supportedNodeVersions.has(version)) {
// If so, return the mapped version
return getNodeVerisonString(version);
}

// Else, return the latest supported version
while (version > 10) {
version--;
if (supportedNodeVersions.has(version)) {
// Found the next-highest supported version
return getNodeVerisonString(version);
}
}

throw new Error("No supported Node.js version found");
}
32 changes: 14 additions & 18 deletions src/presets/azure/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { createWriteStream } from "node:fs";
import fsp from "node:fs/promises";
import archiver from "archiver";
import { writeFile } from "nitropack/kit";
import { getDefaultNodeVersion, writeFile } from "nitropack/kit";
import type { Nitro } from "nitropack/types";
import { join, resolve } from "pathe";
import { readPackageJSON } from "pkg-types";

export async function writeFunctionsRoutes(nitro: Nitro) {
const host = {
Expand Down Expand Up @@ -49,22 +49,18 @@ export async function writeSWARoutes(nitro: Nitro) {
version: "2.0",
};

// https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v4#supported-versions
const supportedNodeVersions = new Set(["16", "18", "20"]);
let nodeVersion = "18";
try {
const currentNodeVersion = JSON.parse(
await fsp.readFile(join(nitro.options.rootDir, "package.json"), "utf8")
).engines.node;
if (supportedNodeVersions.has(currentNodeVersion)) {
nodeVersion = currentNodeVersion;
}
} catch {
const currentNodeVersion = process.versions.node.slice(0, 2);
if (supportedNodeVersions.has(currentNodeVersion)) {
nodeVersion = currentNodeVersion;
}
}
/** @link https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=typescript%2Cwindows%2Cazure-cli&pivots=nodejs-model-v4#supported-versions */
const supportedNodeVersions = new Set([16, 18, 20]);

// Read package.json to get the current node version
const packageJSONPath = join(nitro.options.rootDir, "package.json");
const packageJSON = await readPackageJSON(packageJSONPath);
const currentNodeVersion = Number.parseInt(packageJSON.engines?.node);
/* If current node version is supported, use it,
otherwise use the default node version */
const nodeVersion = supportedNodeVersions.has(currentNodeVersion)
? currentNodeVersion
: getDefaultNodeVersion(supportedNodeVersions);

// Merge custom config into the generated config
const config = {
Expand Down
10 changes: 8 additions & 2 deletions src/presets/firebase/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { existsSync } from "node:fs";
import { writeFile } from "nitropack/kit";
import { writeFile, getDefaultNodeVersion } from "nitropack/kit";
import type { Nitro } from "nitropack/types";
import { join, relative } from "pathe";
import { readPackageJSON, writePackageJSON } from "pkg-types";
import type { FirebaseFunctionsOptions } from "./types";

/**
* Supported Node.js versions for Firebase Functions.
* @link https://cloud.google.com/functions/docs/runtime-support#node.js
*/
const supportedNodeVersions = new Set([18, 20]);

export async function writeFirebaseConfig(nitro: Nitro) {
const firebaseConfigPath = join(nitro.options.rootDir, "firebase.json");
if (existsSync(firebaseConfigPath)) {
Expand Down Expand Up @@ -51,7 +57,7 @@ export async function updatePackageJSON(nitro: Nitro) {
// https://cloud.google.com/functions/docs/concepts/nodejs-runtime
node:
(nitro.options.firebase as FirebaseFunctionsOptions)?.nodeVersion ||
"20",
getDefaultNodeVersion(supportedNodeVersions),
},
});
}