chore: require Node >=v18.20, and default to v22

Anything older than Node v22 is end-of-life, and doesn't get any more
support outside of commercial support.

See https://endoflife.date/nodejs

The current code is still compatible with Node v18.20 and up though,
which switched from import assertions (`assert` keyword) to import
attributes (`with` keyword).

See https://nodejs.org/en/blog/release/v18.20.0

We can't go higher than v22 yet due to certain dependencies depending
on obsolete behavior and `node` command line flags. For instance, the
current version of `argon2-browser` (which is 4 years old) breaks on
Node's native `fetch` behavior, which used to be experimental, but is
now mainstream, and can no longer be disabled in Node v23 and up.
This commit is contained in:
Bart van Andel 2026-02-05 13:19:14 +01:00
parent 0cf7bcaddc
commit 97ae7e3a15
17 changed files with 37 additions and 19 deletions

View File

@ -3,7 +3,7 @@
{
"name": "CyberChef",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bookworm",
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-22",
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {

View File

@ -20,7 +20,7 @@ jobs:
- name: Set node version
uses: actions/setup-node@v6
with:
node-version: 18
node-version: 22
registry-url: "https://registry.npmjs.org"
- name: Install

View File

@ -17,7 +17,7 @@ jobs:
- name: Set node version
uses: actions/setup-node@v6
with:
node-version: 18
node-version: 22
registry-url: "https://registry.npmjs.org"
- name: Install

View File

@ -25,7 +25,7 @@ jobs:
- name: Set node version
uses: actions/setup-node@v6
with:
node-version: 18
node-version: 22
registry-url: "https://registry.npmjs.org"
- name: Install

5
.npmrc Normal file
View File

@ -0,0 +1,5 @@
# We can't currently enable strict engine enforcement, because
# `@astronautlabs/amf@0.0.6` enforces an old Node version.
# They've already fixed this, but the fix hasn't been released yet.
# See: https://github.com/astronautlabs/amf/issues/1
# engine-strict=true

10
.nvmrc
View File

@ -1 +1,9 @@
18
# Currently, we're requiring at least Node v18.20, which introduced import
# attributes (`with` keyword) and removed import asserts (`assert` keyword).
#
# We can't support Node v23+, until `argon2-browser` receives an update that
# supports Node's native `fetch`, i.e., which doesn't require the now obsolete
# `--no-experimental-fetch` flag.
#
# So, let's default to v22.
22

View File

@ -4,7 +4,7 @@
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
# This is because npm "chromedriver" package is not compatiable with all platforms
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
FROM --platform=$BUILDPLATFORM node:18-alpine AS builder
FROM --platform=$BUILDPLATFORM node:22-alpine AS builder
WORKDIR /app

2
mise.toml Normal file
View File

@ -0,0 +1,2 @@
[tools]
node = "22"

6
package-lock.json generated
View File

@ -159,6 +159,9 @@
"webpack-dev-server": "5.0.4",
"webpack-node-externals": "^3.0.0",
"worker-loader": "^3.0.8"
},
"engines": {
"node": ">=18.20 <23"
}
},
"node_modules/@ampproject/remapping": {
@ -170,9 +173,6 @@
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@asamuzakjp/css-color": {

View File

@ -36,7 +36,7 @@
"browserslist": [
"Chrome >= 50",
"Firefox >= 38",
"node >= 16"
"node >= 18.20"
],
"devDependencies": {
"@babel/core": "^7.24.7",
@ -205,5 +205,8 @@
"minor": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newMinorVersion.mjs",
"getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
"setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
},
"engines": {
"node": ">=18.20 <23"
}
}

View File

@ -7,7 +7,7 @@
*/
import Chef from "./Chef.mjs";
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
import OperationConfig from "./config/OperationConfig.json" with {type: "json"};
import OpModules from "./config/modules/OpModules.mjs";
import loglevelMessagePrefix from "loglevel-message-prefix";

View File

@ -4,7 +4,7 @@
* @license Apache-2.0
*/
import OperationConfig from "./config/OperationConfig.json" assert {type: "json"};
import OperationConfig from "./config/OperationConfig.json" with {type: "json"};
import OperationError from "./errors/OperationError.mjs";
import Operation from "./Operation.mjs";
import DishError from "./errors/DishError.mjs";

View File

@ -1,4 +1,4 @@
import OperationConfig from "../config/OperationConfig.json" assert {type: "json"};
import OperationConfig from "../config/OperationConfig.json" with {type: "json"};
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
import Recipe from "../Recipe.mjs";
import Dish from "../Dish.mjs";

View File

@ -10,7 +10,7 @@
import NodeDish from "./NodeDish.mjs";
import NodeRecipe from "./NodeRecipe.mjs";
import OperationConfig from "../core/config/OperationConfig.json" assert {type: "json"};
import OperationConfig from "../core/config/OperationConfig.json" with {type: "json"};
import { sanitise, removeSubheadingsFromArray, sentenceToCamelCase } from "./apiUtils.mjs";
import ExcludedOperationError from "../core/errors/ExcludedOperationError.mjs";

View File

@ -17,8 +17,8 @@ import * as CanvasComponents from "../core/lib/CanvasComponents.mjs";
// CyberChef
import App from "./App.mjs";
import Categories from "../core/config/Categories.json" assert {type: "json"};
import OperationConfig from "../core/config/OperationConfig.json" assert {type: "json"};
import Categories from "../core/config/Categories.json" with {type: "json"};
import OperationConfig from "../core/config/OperationConfig.json" with {type: "json"};
/**

View File

@ -1,5 +1,5 @@
import sm from "sitemap";
import OperationConfig from "../../core/config/OperationConfig.json" assert { type: "json" };
import OperationConfig from "../../core/config/OperationConfig.json" with { type: "json" };
/**
* Generates an XML sitemap for all CyberChef operations and a number of recipes.

View File

@ -1,6 +1,6 @@
import TestRegister from "../../lib/TestRegister.mjs";
import Categories from "../../../src/core/config/Categories.json" assert {type: "json"};
import OperationConfig from "../../../src/core/config/OperationConfig.json" assert {type: "json"};
import Categories from "../../../src/core/config/Categories.json" with {type: "json"};
import OperationConfig from "../../../src/core/config/OperationConfig.json" with {type: "json"};
import it from "../assertionHandler.mjs";
import assert from "assert";