Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions .changeset/every-node-from-26-vercel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-vercel': patch
---

fix: accept every Node.js version from 26 (`nodejs27.x`, `nodejs28.x`, ...), not only even ones
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const config = {

You can set the following options:

- `runtime`: Even Node versions (for example `'nodejs22.x'`, `'nodejs24.x'`, `'nodejs26.x'`), `bun1.x` or `bun1.4.x`. By default, the adapter will select the runtime used for the build, which corresponds to the Node version your project is configured to use on the Vercel dashboard unless you [build the app with Bun](https://bun.com/docs/guides/ecosystem/vite)
- `runtime`: Node versions (for example `'nodejs22.x'`, `'nodejs24.x'`, `'nodejs26.x'`), `bun1.x` or `bun1.4.x`. By default, the adapter will select the runtime used for the build, which corresponds to the Node version your project is configured to use on the Vercel dashboard unless you [build the app with Bun](https://bun.com/docs/guides/ecosystem/vite)
- `regions`: an array of [edge network regions](https://vercel.com/docs/concepts/edge-network/regions) (defaulting to `["iad1"]`). Note that multiple regions for serverless functions are only supported on Enterprise plans
- `split`: if `true`, causes a route to be deployed as an individual function. If `split` is set to `true` at the adapter level, all routes will be deployed as individual functions
- `memory`: the amount of memory available to the function. Defaults to `1024` Mb, and can be decreased to `128` Mb or [increased](https://vercel.com/docs/concepts/limits/overview#serverless-function-memory) in 64Mb increments up to `3008` Mb on Pro or Enterprise accounts
Expand Down
7 changes: 4 additions & 3 deletions packages/adapter-vercel/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function get_default_runtime() {

if (!valid_node_version_regex.test(version_key)) {
throw new Error(
`Unsupported Node.js version: ${process.version}. Please use an even Node version to build your project, or explicitly specify a runtime in your adapter configuration.`
`Unsupported Node.js version: ${process.version}. Please use an up-to-date Node version to build your project, or explicitly specify a runtime in your adapter configuration.`
);
}

Expand All @@ -123,7 +123,8 @@ function get_default_runtime() {
}

const valid_non_node_runtimes = /** @type {const} */ (['bun1.x', 'bun1.4.x']);
const valid_node_version_regex = /^nodejs[2-9][02468]\.x$/;
// Node 20, 22, 24, and every major from 26
const valid_node_version_regex = /^nodejs(2[0246-9]|[3-9]\d)\.x$/;

/**
* @param {string} key
Expand All @@ -137,7 +138,7 @@ function assert_is_valid_runtime(key) {
!valid_node_version_regex.test(key)
) {
throw new Error(
`Unsupported runtime: ${key}. Supported runtimes are: ${valid_non_node_runtimes.join(', ')}, and even Node versions. See the Node.js Version section in your Vercel project settings for info on the currently supported versions.`
`Unsupported runtime: ${key}. Supported runtimes are: ${valid_non_node_runtimes.join(', ')}, and up-to-date Node versions. See the Node.js Version section in your Vercel project settings for info on the currently supported versions.`
);
}
}
Expand Down
43 changes: 26 additions & 17 deletions packages/adapter-vercel/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,24 @@ describe('resolve_runtime', () => {
assert.equal(result, 'bun1.x');
});

test.each(['node18.x', 'nodejs028.x', 'nodejs18.x', 'nodejs33.x', 'nodejs100.x', 'nodejs2,.x'])(
'throws an error when resolving to an invalid runtime (%s)',
(runtime) => {
assert.throws(() => resolve_runtime(runtime), /Unsupported runtime/);
}
);
test.each([
'node18.x',
'nodejs028.x',
'nodejs18.x',
'nodejs23.x',
'nodejs25.x',
'nodejs100.x',
'nodejs2,.x'
])('throws an error when resolving to an invalid runtime (%s)', (runtime) => {
assert.throws(() => resolve_runtime(runtime), /Unsupported runtime/);
});

test('accepts a minor-pinned bun runtime', () => {
const result = resolve_runtime('bun1.4.x');
assert.equal(result, 'bun1.4.x');
});

test.each(['nodejs22.x', 'nodejs24.x', 'nodejs26.x', 'nodejs96.x', 'nodejs98.x'])(
test.each(['nodejs22.x', 'nodejs24.x', 'nodejs26.x', 'nodejs27.x', 'nodejs33.x', 'nodejs99.x'])(
'accepts %s',
(runtime) => {
assert.equal(resolve_runtime(runtime), runtime);
Expand Down Expand Up @@ -197,20 +202,24 @@ describe('resolve_runtime with node detected', () => {
['22.0.0', 'nodejs22.x'],
['24.1.0', 'nodejs24.x'],
['26.0.0', 'nodejs26.x'],
['96.1.0', 'nodejs96.x'],
['98.0.0', 'nodejs98.x']
['27.0.0', 'nodejs27.x'],
['29.1.0', 'nodejs29.x'],
['99.0.0', 'nodejs99.x']
])('detects Node %s', (version, runtime) => {
with_node(version, () => {
assert.equal(resolve_runtime(undefined, undefined), runtime);
});
});

test.each(['18.0.0', '27.0.0'])('throws for an unsupported Node major (%s)', (version) => {
with_node(version, () => {
assert.throws(
() => resolve_runtime(undefined, undefined),
/Unsupported Node\.js version.*Please use an even Node version to build your project/
);
});
});
test.each(['18.0.0', '23.0.0', '25.0.0'])(
'throws for an unsupported Node major (%s)',
(version) => {
with_node(version, () => {
assert.throws(
() => resolve_runtime(undefined, undefined),
/Unsupported Node\.js version.*Please use an up-to-date Node version to build your project/
);
});
}
);
});
Loading