From 2598314510b2e75a7717de8292d809b1d47ca9ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 18 Sep 2026 15:45:38 +0200 Subject: [PATCH 1/5] chore!: require Node.js 26.9 (AI-assisted) (#12463) --- .github/workflows/argos.yml | 2 +- .github/workflows/build-blog-only.yml | 2 +- .github/workflows/build-hash-router.yml | 2 +- .github/workflows/build-perf.yml | 4 ++-- .github/workflows/continuous-releases.yml | 2 +- .github/workflows/lighthouse-report.yml | 2 +- .github/workflows/lint-autofix.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/publish.yml | 2 +- .github/workflows/security-supply-chain.yml | 4 ++-- .github/workflows/showcase-test.yml | 2 +- .github/workflows/tests-e2e.yml | 18 +++++++++--------- .github/workflows/tests-swizzle.yml | 2 +- .github/workflows/tests-windows.yml | 2 +- .github/workflows/tests.yml | 4 ++-- .nvmrc | 2 +- admin/scripts/generateExamples.js | 4 ++-- package.json | 2 +- packages/create-docusaurus/package.json | 2 +- .../templates/classic-typescript/package.json | 2 +- .../templates/classic/package.json | 2 +- .../templates/shared/docs/intro.mdx | 2 +- packages/docusaurus-babel/package.json | 2 +- packages/docusaurus-bundler/package.json | 2 +- .../docusaurus-cssnano-preset/package.json | 2 +- packages/docusaurus-faster/package.json | 2 +- packages/docusaurus-logger/package.json | 2 +- packages/docusaurus-mdx-loader/package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- .../package.json | 2 +- packages/docusaurus-plugin-debug/package.json | 2 +- .../docusaurus-plugin-google-gtag/package.json | 2 +- .../package.json | 2 +- .../docusaurus-plugin-ideal-image/package.json | 2 +- packages/docusaurus-plugin-pwa/package.json | 2 +- .../docusaurus-plugin-rsdoctor/package.json | 2 +- .../docusaurus-plugin-sitemap/package.json | 2 +- packages/docusaurus-plugin-svgr/package.json | 2 +- .../package.json | 2 +- .../docusaurus-preset-classic/package.json | 2 +- .../package.json | 2 +- packages/docusaurus-theme-classic/package.json | 2 +- packages/docusaurus-theme-common/package.json | 2 +- .../package.json | 2 +- packages/docusaurus-theme-mermaid/package.json | 2 +- .../package.json | 2 +- .../docusaurus-theme-translations/package.json | 2 +- packages/docusaurus-utils-common/package.json | 2 +- .../docusaurus-utils-validation/package.json | 2 +- packages/docusaurus-utils/package.json | 2 +- packages/docusaurus/package.json | 2 +- packages/eslint-plugin/package.json | 2 +- packages/lqip-loader/package.json | 2 +- website/docs/deployment/github-pages.mdx | 12 ++++++------ website/docs/installation.mdx | 2 +- website/netlify.toml | 2 +- 59 files changed, 76 insertions(+), 76 deletions(-) diff --git a/.github/workflows/argos.yml b/.github/workflows/argos.yml index fcd68f66cb25..932f5d75dbe8 100644 --- a/.github/workflows/argos.yml +++ b/.github/workflows/argos.yml @@ -44,7 +44,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Install dependencies diff --git a/.github/workflows/build-blog-only.yml b/.github/workflows/build-blog-only.yml index a5c6838df459..d2b5a520bda0 100644 --- a/.github/workflows/build-blog-only.yml +++ b/.github/workflows/build-blog-only.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/build-hash-router.yml b/.github/workflows/build-hash-router.yml index 9b9ad93cc482..3c72e374de6a 100644 --- a/.github/workflows/build-hash-router.yml +++ b/.github/workflows/build-hash-router.yml @@ -31,7 +31,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/build-perf.yml b/.github/workflows/build-perf.yml index 95e709a7a9dc..710ed516f122 100644 --- a/.github/workflows/build-perf.yml +++ b/.github/workflows/build-perf.yml @@ -47,7 +47,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Track build size changes uses: preactjs/compressed-size-action@f322c295dde06a1cb7ccaef105732dd8a726d1d9 # v2.10.0 @@ -82,7 +82,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/continuous-releases.yml b/.github/workflows/continuous-releases.yml index e8632203888c..d097881f320a 100644 --- a/.github/workflows/continuous-releases.yml +++ b/.github/workflows/continuous-releases.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' # ⚠️ Do not use any cache on purpose # It increases the chance of a compromised release being publish # See https://github.com/actions/setup-node/issues/1445#issuecomment-4040130833 diff --git a/.github/workflows/lighthouse-report.yml b/.github/workflows/lighthouse-report.yml index be3610facbb9..5de09cfeb6ef 100644 --- a/.github/workflows/lighthouse-report.yml +++ b/.github/workflows/lighthouse-report.yml @@ -29,7 +29,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Install dependencies diff --git a/.github/workflows/lint-autofix.yml b/.github/workflows/lint-autofix.yml index 42e2d8873332..af96783372a1 100644 --- a/.github/workflows/lint-autofix.yml +++ b/.github/workflows/lint-autofix.yml @@ -30,7 +30,7 @@ jobs: - name: Set up Node LTS uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bfad7cb7984f..7334eba8c95c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -26,7 +26,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 235e870910d8..47aa57b8402c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -50,7 +50,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' # ⚠️ Do not use any cache on purpose # It increases the chance of a compromised release being publish # See https://github.com/actions/setup-node/issues/1445#issuecomment-4040130833 diff --git a/.github/workflows/security-supply-chain.yml b/.github/workflows/security-supply-chain.yml index 51725c9fe8a7..29eca4759e2b 100644 --- a/.github/workflows/security-supply-chain.yml +++ b/.github/workflows/security-supply-chain.yml @@ -34,7 +34,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' # No cache on purpose! We want SFW to fetch packages # See https://socket.dev/blog/introducing-socket-firewall @@ -69,7 +69,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' # No cache on purpose! We want SFW to fetch packages # See https://socket.dev/blog/introducing-socket-firewall diff --git a/.github/workflows/showcase-test.yml b/.github/workflows/showcase-test.yml index cf62b92511ef..77f41dcff1fe 100644 --- a/.github/workflows/showcase-test.yml +++ b/.github/workflows/showcase-test.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/tests-e2e.yml b/.github/workflows/tests-e2e.yml index 362daebf8522..01b164e234c5 100644 --- a/.github/workflows/tests-e2e.yml +++ b/.github/workflows/tests-e2e.yml @@ -44,10 +44,10 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install pnpm uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - - name: Use Node.js LTS + - name: Use Node.js 26.9 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile @@ -91,7 +91,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: ['24.14', '26'] + node: ['26.9', 'latest'] steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -140,10 +140,10 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install pnpm uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - - name: Use Node.js LTS + - name: Use Node.js 26.9 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile @@ -221,10 +221,10 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install pnpm uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - - name: Use Node.js LTS + - name: Use Node.js 26.9 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile @@ -263,10 +263,10 @@ jobs: uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Install pnpm uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10 - - name: Use Node.js LTS + - name: Use Node.js 26.9 uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/tests-swizzle.yml b/.github/workflows/tests-swizzle.yml index 78c4549f0c41..fae1d2d1c0ca 100644 --- a/.github/workflows/tests-swizzle.yml +++ b/.github/workflows/tests-swizzle.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Node LTS uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: lts/* + node-version: '26.9' cache: pnpm - name: Installation run: pnpm install --frozen-lockfile || pnpm install --frozen-lockfile || pnpm install --frozen-lockfile diff --git a/.github/workflows/tests-windows.yml b/.github/workflows/tests-windows.yml index 36ae3c0bbdad..fa12adbb9044 100644 --- a/.github/workflows/tests-windows.yml +++ b/.github/workflows/tests-windows.yml @@ -28,7 +28,7 @@ jobs: runs-on: windows-8-core strategy: matrix: - node: ['24.14', '26'] + node: ['26.9', 'latest'] steps: - name: Support longpaths run: git config --system core.longpaths true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5434d745a41d..9d5ef40bf3ab 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node: ['24.14', '26'] + node: ['26.9', 'latest'] steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 @@ -52,7 +52,7 @@ jobs: env: # Our website should build even with limited memory # See https://github.com/facebook/docusaurus/pull/10590 - NODE_OPTIONS: "--max-old-space-size=${{ matrix.node == '24.14' && 350 || 300 }}" + NODE_OPTIONS: '--max-old-space-size=300' DOCUSAURUS_PERF_LOGGER: 'true' - name: Docusaurus site CSS order run: pnpm --filter website test:css-order diff --git a/.nvmrc b/.nvmrc index 6f4247a6255c..134a0606c0b6 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -26 +26.9 diff --git a/admin/scripts/generateExamples.js b/admin/scripts/generateExamples.js index b1b34e938f98..360e9c3903c9 100644 --- a/admin/scripts/generateExamples.js +++ b/admin/scripts/generateExamples.js @@ -80,9 +80,9 @@ async function generateTemplateExample(template) { hardReloadOnChange: true, view: 'browser', template: 'docusaurus', - node: '24', + node: '26', container: { - node: '24', + node: '26', }, }; await fs.writeFile( diff --git a/package.json b/package.json index 28490347612c..3de075c89594 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ }, "packageManager": "pnpm@12.3.4", "engines": { - "node": ">=24.14", + "node": ">=26.9", "pnpm": ">=12.3.4" } } diff --git a/packages/create-docusaurus/package.json b/packages/create-docusaurus/package.json index 0adcaf8ae1ae..27145077fe0b 100755 --- a/packages/create-docusaurus/package.json +++ b/packages/create-docusaurus/package.json @@ -35,6 +35,6 @@ "@types/supports-color": "^10.0.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/create-docusaurus/templates/classic-typescript/package.json b/packages/create-docusaurus/templates/classic-typescript/package.json index acc99ff2abba..31a5fcb89d51 100644 --- a/packages/create-docusaurus/templates/classic-typescript/package.json +++ b/packages/create-docusaurus/templates/classic-typescript/package.json @@ -44,6 +44,6 @@ ] }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/create-docusaurus/templates/classic/package.json b/packages/create-docusaurus/templates/classic/package.json index 1bd4c57c09ef..9968fc582b11 100644 --- a/packages/create-docusaurus/templates/classic/package.json +++ b/packages/create-docusaurus/templates/classic/package.json @@ -40,6 +40,6 @@ ] }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/create-docusaurus/templates/shared/docs/intro.mdx b/packages/create-docusaurus/templates/shared/docs/intro.mdx index edf545700896..4f9eceff94c2 100644 --- a/packages/create-docusaurus/templates/shared/docs/intro.mdx +++ b/packages/create-docusaurus/templates/shared/docs/intro.mdx @@ -14,7 +14,7 @@ Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new ### What you'll need -- [Node.js](https://nodejs.org/en/download/) version 24.14 or above: +- [Node.js](https://nodejs.org/en/download/) version 26.9 or above: - When installing Node.js, you are recommended to check all checkboxes related to dependencies. ## Generate a new site diff --git a/packages/docusaurus-babel/package.json b/packages/docusaurus-babel/package.json index 233f7342a5f5..339c596b6af0 100644 --- a/packages/docusaurus-babel/package.json +++ b/packages/docusaurus-babel/package.json @@ -50,6 +50,6 @@ "@types/babel__traverse": "^7.28.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-bundler/package.json b/packages/docusaurus-bundler/package.json index 96b2133d7dd5..bba6cc1bb79c 100644 --- a/packages/docusaurus-bundler/package.json +++ b/packages/docusaurus-bundler/package.json @@ -55,6 +55,6 @@ "@total-typescript/shoehorn": "^0.1.2" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-cssnano-preset/package.json b/packages/docusaurus-cssnano-preset/package.json index 77ff9ea8a70e..95c4069edeb5 100644 --- a/packages/docusaurus-cssnano-preset/package.json +++ b/packages/docusaurus-cssnano-preset/package.json @@ -26,6 +26,6 @@ "to-vfile": "^8.0.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-faster/package.json b/packages/docusaurus-faster/package.json index d32c29ce979f..db74f9bd18f4 100644 --- a/packages/docusaurus-faster/package.json +++ b/packages/docusaurus-faster/package.json @@ -31,7 +31,7 @@ "webpack": "^5.111.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" }, "peerDependencies": { "@docusaurus/types": "*" diff --git a/packages/docusaurus-logger/package.json b/packages/docusaurus-logger/package.json index 1a57eb935135..dc61a2999018 100644 --- a/packages/docusaurus-logger/package.json +++ b/packages/docusaurus-logger/package.json @@ -24,6 +24,6 @@ "tslib": "^2.8.1" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-mdx-loader/package.json b/packages/docusaurus-mdx-loader/package.json index e4ca0ae65f64..612af72ecd52 100644 --- a/packages/docusaurus-mdx-loader/package.json +++ b/packages/docusaurus-mdx-loader/package.json @@ -64,6 +64,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-client-redirects/package.json b/packages/docusaurus-plugin-client-redirects/package.json index 94cc4c5c49d8..81e39e494ea9 100644 --- a/packages/docusaurus-plugin-client-redirects/package.json +++ b/packages/docusaurus-plugin-client-redirects/package.json @@ -36,6 +36,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-content-blog/package.json b/packages/docusaurus-plugin-content-blog/package.json index 13379c9f399c..1f7e71c177a9 100644 --- a/packages/docusaurus-plugin-content-blog/package.json +++ b/packages/docusaurus-plugin-content-blog/package.json @@ -57,7 +57,7 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" }, "devDependencies": { "@total-typescript/shoehorn": "^0.1.2", diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json index e4c584c7ab9a..7619e43145bc 100644 --- a/packages/docusaurus-plugin-content-docs/package.json +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -65,6 +65,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-content-pages/package.json b/packages/docusaurus-plugin-content-pages/package.json index e1a08615e0ad..3ce6f9069e9c 100644 --- a/packages/docusaurus-plugin-content-pages/package.json +++ b/packages/docusaurus-plugin-content-pages/package.json @@ -32,6 +32,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-css-cascade-layers/package.json b/packages/docusaurus-plugin-css-cascade-layers/package.json index 9e43b3b3ddc6..5e2f7754ac46 100644 --- a/packages/docusaurus-plugin-css-cascade-layers/package.json +++ b/packages/docusaurus-plugin-css-cascade-layers/package.json @@ -25,6 +25,6 @@ "tslib": "^2.8.1" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-debug/package.json b/packages/docusaurus-plugin-debug/package.json index c26d4e121b2f..e8d8aa3af54b 100644 --- a/packages/docusaurus-plugin-debug/package.json +++ b/packages/docusaurus-plugin-debug/package.json @@ -33,6 +33,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-google-gtag/package.json b/packages/docusaurus-plugin-google-gtag/package.json index a30cb4173396..0908802619b9 100644 --- a/packages/docusaurus-plugin-google-gtag/package.json +++ b/packages/docusaurus-plugin-google-gtag/package.json @@ -30,6 +30,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-google-tag-manager/package.json b/packages/docusaurus-plugin-google-tag-manager/package.json index 038de3546c85..f79528b6def2 100644 --- a/packages/docusaurus-plugin-google-tag-manager/package.json +++ b/packages/docusaurus-plugin-google-tag-manager/package.json @@ -28,6 +28,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-ideal-image/package.json b/packages/docusaurus-plugin-ideal-image/package.json index 33da8f98d88e..ca2b45e4dd3f 100644 --- a/packages/docusaurus-plugin-ideal-image/package.json +++ b/packages/docusaurus-plugin-ideal-image/package.json @@ -45,6 +45,6 @@ } }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-pwa/package.json b/packages/docusaurus-plugin-pwa/package.json index 0f8c1dd0e42d..7578e3684a45 100644 --- a/packages/docusaurus-plugin-pwa/package.json +++ b/packages/docusaurus-plugin-pwa/package.json @@ -49,6 +49,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-rsdoctor/package.json b/packages/docusaurus-plugin-rsdoctor/package.json index 8bd252027952..f4c9802db2ec 100644 --- a/packages/docusaurus-plugin-rsdoctor/package.json +++ b/packages/docusaurus-plugin-rsdoctor/package.json @@ -30,6 +30,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-sitemap/package.json b/packages/docusaurus-plugin-sitemap/package.json index dd41ab5ac3a9..702040fdf6ba 100644 --- a/packages/docusaurus-plugin-sitemap/package.json +++ b/packages/docusaurus-plugin-sitemap/package.json @@ -36,6 +36,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-svgr/package.json b/packages/docusaurus-plugin-svgr/package.json index 39dd156a80c7..53e720b4d6d6 100644 --- a/packages/docusaurus-plugin-svgr/package.json +++ b/packages/docusaurus-plugin-svgr/package.json @@ -32,6 +32,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-plugin-vercel-analytics/package.json b/packages/docusaurus-plugin-vercel-analytics/package.json index 9c9c5b1e7f63..de94f84b9b07 100644 --- a/packages/docusaurus-plugin-vercel-analytics/package.json +++ b/packages/docusaurus-plugin-vercel-analytics/package.json @@ -32,6 +32,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-preset-classic/package.json b/packages/docusaurus-preset-classic/package.json index 7a80194b2062..20689794e262 100644 --- a/packages/docusaurus-preset-classic/package.json +++ b/packages/docusaurus-preset-classic/package.json @@ -38,6 +38,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-remark-plugin-npm2yarn/package.json b/packages/docusaurus-remark-plugin-npm2yarn/package.json index a1809bf8df06..7e4776db7735 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/package.json +++ b/packages/docusaurus-remark-plugin-npm2yarn/package.json @@ -31,6 +31,6 @@ "to-vfile": "^8.0.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 844b9982a803..27d072f80bef 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -58,6 +58,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-common/package.json b/packages/docusaurus-theme-common/package.json index efdc7e104ded..5d4309b2b248 100644 --- a/packages/docusaurus-theme-common/package.json +++ b/packages/docusaurus-theme-common/package.json @@ -55,6 +55,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-live-codeblock/package.json b/packages/docusaurus-theme-live-codeblock/package.json index 37d557aac700..216255f1b5cd 100644 --- a/packages/docusaurus-theme-live-codeblock/package.json +++ b/packages/docusaurus-theme-live-codeblock/package.json @@ -56,6 +56,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-mermaid/package.json b/packages/docusaurus-theme-mermaid/package.json index da746f5be6a3..c77f3e5a13a8 100644 --- a/packages/docusaurus-theme-mermaid/package.json +++ b/packages/docusaurus-theme-mermaid/package.json @@ -46,6 +46,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-search-algolia/package.json b/packages/docusaurus-theme-search-algolia/package.json index 77190806e4d2..3fa2eb9efab0 100644 --- a/packages/docusaurus-theme-search-algolia/package.json +++ b/packages/docusaurus-theme-search-algolia/package.json @@ -61,6 +61,6 @@ "react-dom": "^19.3.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-theme-translations/package.json b/packages/docusaurus-theme-translations/package.json index fcac9418c998..025e4ae92182 100644 --- a/packages/docusaurus-theme-translations/package.json +++ b/packages/docusaurus-theme-translations/package.json @@ -31,6 +31,6 @@ "lodash": "^4.18.1" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-utils-common/package.json b/packages/docusaurus-utils-common/package.json index dfe9da86a8fc..5c6647967824 100644 --- a/packages/docusaurus-utils-common/package.json +++ b/packages/docusaurus-utils-common/package.json @@ -23,6 +23,6 @@ "tslib": "^2.8.1" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index 7170210fff58..6e4198d4173f 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -31,6 +31,6 @@ "@types/js-yaml": "^4.0.9" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/docusaurus-utils/package.json b/packages/docusaurus-utils/package.json index fee9a007e918..870077a00eed 100644 --- a/packages/docusaurus-utils/package.json +++ b/packages/docusaurus-utils/package.json @@ -40,7 +40,7 @@ "webpack": "^5.111.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" }, "devDependencies": { "@types/dedent": "^0.7.2", diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 4537979c1217..4314b51b082d 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -102,6 +102,6 @@ } }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index ac53a25b9f00..d41f85ce6d88 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -33,6 +33,6 @@ "eslint": ">=8.57.0" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" } } diff --git a/packages/lqip-loader/package.json b/packages/lqip-loader/package.json index 84506afd4f92..6203cdfb5518 100644 --- a/packages/lqip-loader/package.json +++ b/packages/lqip-loader/package.json @@ -24,7 +24,7 @@ "tslib": "^2.8.1" }, "engines": { - "node": ">=24.14" + "node": ">=26.9" }, "devDependencies": { "@types/file-loader": "^5.0.4", diff --git a/website/docs/deployment/github-pages.mdx b/website/docs/deployment/github-pages.mdx index 357199ed628a..07bbdaa81c77 100644 --- a/website/docs/deployment/github-pages.mdx +++ b/website/docs/deployment/github-pages.mdx @@ -189,7 +189,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: npm - name: Install dependencies @@ -243,7 +243,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: npm - name: Install dependencies @@ -275,7 +275,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: yarn - name: Install dependencies @@ -329,7 +329,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: yarn - name: Install dependencies @@ -396,7 +396,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile @@ -411,7 +411,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 24 + node-version: '26.9' cache: yarn - uses: webfactory/ssh-agent@v0.5.0 with: diff --git a/website/docs/installation.mdx b/website/docs/installation.mdx index 0846919e480c..b4a025a59ad0 100644 --- a/website/docs/installation.mdx +++ b/website/docs/installation.mdx @@ -21,7 +21,7 @@ Use **[docusaurus.new](https://docusaurus.new)** to test Docusaurus immediately ## Requirements {/* #requirements */} -- [Node.js](https://nodejs.org/en/download/) version 24.14 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) to manage multiple Node.js versions on a single machine. +- [Node.js](https://nodejs.org/en/download/) version 26.9 or above (which can be checked by running `node -v`). You can use [nvm](https://github.com/nvm-sh/nvm) to manage multiple Node.js versions on a single machine. - When installing Node.js, it is recommended to check all checkboxes related to dependencies. ## Scaffold project website {/* #scaffold-project-website */} diff --git a/website/netlify.toml b/website/netlify.toml index d55c2649c735..06622ef6b841 100644 --- a/website/netlify.toml +++ b/website/netlify.toml @@ -9,7 +9,7 @@ command = "pnpm --dir .. build:packages && pnpm build" publish = "website/build" [build.environment] -NODE_VERSION = "24" +NODE_VERSION = "26.9" NODE_OPTIONS = "--max_old_space_size=8192" From 6a914a553a75bfea269cb42442c7f667af9e6c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 18 Sep 2026 16:02:39 +0200 Subject: [PATCH 2/5] chore: use Node 26 major version selectors (AI-assisted) (#12464) --- .nvmrc | 2 +- website/docs/deployment/github-pages.mdx | 12 ++++++------ website/netlify.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.nvmrc b/.nvmrc index 134a0606c0b6..6f4247a6255c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -26.9 +26 diff --git a/website/docs/deployment/github-pages.mdx b/website/docs/deployment/github-pages.mdx index 07bbdaa81c77..3bcef4014ebd 100644 --- a/website/docs/deployment/github-pages.mdx +++ b/website/docs/deployment/github-pages.mdx @@ -189,7 +189,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: npm - name: Install dependencies @@ -243,7 +243,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: npm - name: Install dependencies @@ -275,7 +275,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: yarn - name: Install dependencies @@ -329,7 +329,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: yarn - name: Install dependencies @@ -396,7 +396,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: yarn - name: Install dependencies run: yarn install --frozen-lockfile @@ -411,7 +411,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: '26.9' + node-version: 26 cache: yarn - uses: webfactory/ssh-agent@v0.5.0 with: diff --git a/website/netlify.toml b/website/netlify.toml index 06622ef6b841..ca5ae6676678 100644 --- a/website/netlify.toml +++ b/website/netlify.toml @@ -9,7 +9,7 @@ command = "pnpm --dir .. build:packages && pnpm build" publish = "website/build" [build.environment] -NODE_VERSION = "26.9" +NODE_VERSION = "26" NODE_OPTIONS = "--max_old_space_size=8192" From 2a8654b92d6f827cfe49594281d60240c23666f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 18 Sep 2026 17:43:13 +0200 Subject: [PATCH 3/5] chore(deps): upgrade gray-matter to 3 and js-yaml to 5 (AI-assisted) (#12462) --- .../__snapshots__/index.test.ts.snap | 6 +- .../src/__tests__/blogUtils.test.ts | 113 +++++++++++++++++- .../src/__tests__/index.test.ts | 6 +- .../src/blogUtils.ts | 71 +++++++---- .../package.json | 3 +- .../src/sidebars/index.ts | 2 +- .../docusaurus-utils-validation/package.json | 5 +- .../src/tagsFile.ts | 2 +- .../src/validationUtils.ts | 2 +- packages/docusaurus-utils/package.json | 5 +- .../dataFiles/dataFiles/comments.yml | 1 + .../dataFiles/dataFiles/invalid.yml | 2 +- .../dataFiles/dataFiles/schema.yml | 5 + .../src/__tests__/dataFileUtils.test.ts | 20 +++- .../src/__tests__/markdownUtils.test.ts | 55 ++++++++- .../docusaurus-utils/src/dataFileUtils.ts | 2 +- pnpm-lock.yaml | 47 ++++---- 17 files changed, 272 insertions(+), 75 deletions(-) create mode 100644 packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/comments.yml create mode 100644 packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/schema.yml diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap index e8ef1f4fdd12..8bef67538e96 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/index.test.ts.snap @@ -135,7 +135,7 @@ exports[`blog plugin > process blog posts load content 2`] = ` "author": "Sébastien Lorber", "author_title": "Docusaurus maintainer", "author_url": "https://sebastienlorber.com", - "date": 2020-08-15T00:00:00.000Z, + "date": "2020-08-15", "slug": "/simple/slug/another", "tags": [ "tag1", @@ -173,7 +173,7 @@ exports[`blog plugin > process blog posts load content 2`] = ` "description": "with tag", "editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags.md", "frontMatter": { - "date": 2020-08-15T00:00:00.000Z, + "date": "2020-08-15", "slug": "/another/tags", "tags": [ "tag1", @@ -222,7 +222,7 @@ exports[`blog plugin > process blog posts load content 2`] = ` "description": "with tag", "editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags2.md", "frontMatter": { - "date": 2020-08-15T00:00:00.000Z, + "date": "2020-08-15", "slug": "/another/tags2", "tags": [ "tag1", diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts index a454826fa7d1..58deb0252f94 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/blogUtils.test.ts @@ -5,16 +5,20 @@ * LICENSE file in the root directory of this source tree. */ -import {describe, expect, it, vi} from 'vitest'; +import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'; +import fs from 'fs-extra'; import {fromPartial} from '@total-typescript/shoehorn'; import { truncate, parseBlogFileName, + parseFrontMatterDate, + getBlogPostDate, paginateBlogPosts, applyProcessBlogPosts, reportUntruncatedBlogPosts, } from '../blogUtils'; import type {BlogPost} from '@docusaurus/plugin-content-blog'; +import type {VcsConfig} from '@docusaurus/types'; describe('truncate', () => { it('truncates texts', () => { @@ -214,6 +218,113 @@ describe('paginateBlogPosts', () => { }); }); +describe.each(['UTC', 'America/New_York', 'Asia/Tokyo'])( + 'parseFrontMatterDate in %s', + (timeZone) => { + beforeEach(() => vi.stubEnv('TZ', timeZone)); + afterEach(() => vi.unstubAllEnvs()); + it.each([ + ['2026-09-18', '2026-09-18T00:00:00.000Z'], + ['2026-09-18T12:00:00', '2026-09-18T12:00:00.000Z'], + ['2026-09-18T12:00:00Z', '2026-09-18T12:00:00.000Z'], + ['2026-09-18T12:00:00+02:00', '2026-09-18T10:00:00.000Z'], + ['2026-09-18T12:00:00-0430', '2026-09-18T16:30:00.000Z'], + ['2026-09-18 12:00:00 +02', '2026-09-18T10:00:00.000Z'], + ['2026-09-18 2:00:00 -5', '2026-09-18T07:00:00.000Z'], + ['2026-09-18\t12:00:00+02:00', '2026-09-18T10:00:00.000Z'], + ['2026-09-18 12:00:00 +02:00 ', '2026-09-18T10:00:00.000Z'], + [' 2026-09-18 ', '2026-09-18T00:00:00.000Z'], + ['2026/09/18', '2026-09-18T00:00:00.000Z'], + ['2001-12-14t21:59:43.10-05:00', '2001-12-15T02:59:43.100Z'], + ['2001-12-15 2:59:43.10', '2001-12-15T02:59:43.100Z'], + ['2026-09-18T12:00:00+05:45', '2026-09-18T06:15:00.000Z'], + ])('preserves the publication date for %s', (date, expected) => { + expect(parseFrontMatterDate(date).toISOString()).toBe(expected); + }); + + it('preserves Date objects returned by custom front matter parsers', () => { + const date = new Date('2026-09-18T12:00:00Z'); + expect(parseFrontMatterDate(date)).toBe(date); + }); + }, +); + +describe('getBlogPostDate', () => { + function setup() { + const getFileCreationInfo = vi.fn(); + const params = { + filePath: '/blog/post.md', + vcs: fromPartial({getFileCreationInfo}), + }; + return {params, getFileCreationInfo}; + } + + it.each(['2026-09-18', new Date('2026-09-18')])( + 'prefers front matter over the filename and VCS: %s', + async (frontMatterDate) => { + const {params, getFileCreationInfo} = setup(); + await expect( + getBlogPostDate({ + ...params, + frontMatterDate, + filenameDate: new Date('2020-01-01'), + }), + ).resolves.toEqual(new Date('2026-09-18')); + expect(getFileCreationInfo).not.toHaveBeenCalled(); + }, + ); + + it('prefers the filename over VCS', async () => { + const {params, getFileCreationInfo} = setup(); + const filenameDate = new Date('2020-01-01'); + await expect(getBlogPostDate({...params, filenameDate})).resolves.toBe( + filenameDate, + ); + expect(getFileCreationInfo).not.toHaveBeenCalled(); + }); + + it.each([0, Date.UTC(2020, 0, 1)])( + 'uses the VCS creation timestamp: %s', + async (timestamp) => { + const {params, getFileCreationInfo} = setup(); + getFileCreationInfo.mockResolvedValue({timestamp, author: 'Author'}); + await expect(getBlogPostDate(params)).resolves.toEqual( + new Date(timestamp), + ); + expect(getFileCreationInfo).toHaveBeenCalledExactlyOnceWith( + params.filePath, + ); + }, + ); + + it('falls back to filesystem birthtime when VCS has no creation info', async () => { + const {params, getFileCreationInfo} = setup(); + getFileCreationInfo.mockResolvedValue(null); + const birthtime = new Date('2020-01-01'); + using stat = vi + .spyOn(fs, 'stat') + .mockResolvedValue(fromPartial({birthtime})); + await expect(getBlogPostDate(params)).resolves.toBe(birthtime); + expect(stat).toHaveBeenCalledExactlyOnceWith(params.filePath); + }); + + it('propagates VCS errors', async () => { + const {params, getFileCreationInfo} = setup(); + const error = new Error('VCS unavailable'); + getFileCreationInfo.mockRejectedValue(error); + await expect(getBlogPostDate(params)).rejects.toBe(error); + }); + + it('propagates filesystem errors', async () => { + const {params, getFileCreationInfo} = setup(); + getFileCreationInfo.mockResolvedValue(null); + const error = new Error('File not found'); + using stat = vi.spyOn(fs, 'stat').mockRejectedValue(error); + await expect(getBlogPostDate(params)).rejects.toBe(error); + expect(stat).toHaveBeenCalledExactlyOnceWith(params.filePath); + }); +}); + describe('parseBlogFileName', () => { it('parses file', () => { expect(parseBlogFileName('some-post.md')).toEqual({ diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index 94ce220ef79f..7beae36e119d 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -207,7 +207,7 @@ describe('blog plugin', () => { authors: [], date: new Date('2019-01-01'), frontMatter: { - date: new Date('2019-01-01'), + date: '2019-01-01', tags: ['date'], }, prevItem: undefined, @@ -363,7 +363,7 @@ describe('blog plugin', () => { author: 'Sébastien Lorber', author_title: 'Docusaurus maintainer', author_url: 'https://sebastienlorber.com', - date: new Date('2020-08-15'), + date: '2020-08-15', slug: '/simple/slug', title: 'Simple Slug', }, @@ -385,7 +385,7 @@ describe('blog plugin', () => { authors: [], date: new Date('2019-01-02'), frontMatter: { - date: new Date('2019-01-02'), + date: '2019-01-02', }, prevItem: undefined, tags: [], diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index a30480b84025..6f7b95ef652d 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -32,7 +32,7 @@ import {getBlogPostAuthors} from './authors'; import {reportAuthorsProblems} from './authorsProblems'; import {calculateReadingTime} from './readingTime'; import type {TagsFile} from '@docusaurus/utils'; -import type {LoadContext, ParseFrontMatter} from '@docusaurus/types'; +import type {LoadContext, ParseFrontMatter, VcsConfig} from '@docusaurus/types'; import type { AuthorsMap, PluginOptions, @@ -184,6 +184,48 @@ export function parseBlogFileName( return {date: undefined, text, slug}; } +export function parseFrontMatterDate(date: string | Date): Date { + if (typeof date === 'string') { + const dateString = date.trim(); + // Detect a timezone suffix in the time portion, not the date's day/year. + // YAML timestamps allow tabs and short offsets; also accept ISO +/-HHMM. + // https://yaml.org/type/timestamp.html + // This detects a timezone, not date validity (already checked by Joi). + const hasTimeZone = /[t \t]\d.*(?:z|[+-]\d{1,2}(?::?\d{2})?)$/i.test( + dateString, + ); + // Treat dates without an explicit timezone as UTC. + return new Date(hasTimeZone ? dateString : `${dateString}Z`); + } + // Custom front matter parsers can still return Date objects. + return date; +} + +export async function getBlogPostDate({ + frontMatterDate, + filenameDate, + filePath, + vcs, +}: { + frontMatterDate?: string | Date; + filenameDate?: Date; + filePath: string; + vcs: VcsConfig; +}): Promise { + // Prefer front matter, then the filename, then the file creation date. + if (frontMatterDate) { + return parseFrontMatterDate(frontMatterDate); + } else if (filenameDate) { + return filenameDate; + } + + const result = await vcs.getFileCreationInfo(filePath); + if (result == null) { + return (await fs.stat(filePath)).birthtime; + } + return new Date(result.timestamp); +} + async function parseBlogPostMarkdownFile({ filePath, parseFrontMatter, @@ -273,27 +315,12 @@ async function processBlogSourceFile( const parsedBlogFileName = parseBlogFileName(blogSourceRelative); - async function getDate(): Promise { - // Prefer user-defined date. - if (frontMatter.date) { - if (typeof frontMatter.date === 'string') { - // Always treat dates as UTC by adding the `Z` - return new Date(`${frontMatter.date}Z`); - } - // YAML only converts YYYY-MM-DD to dates and leaves others as strings. - return frontMatter.date; - } else if (parsedBlogFileName.date) { - return parsedBlogFileName.date; - } - - const result = await vcs.getFileCreationInfo(blogSourceAbsolute); - if (result == null) { - return (await fs.stat(blogSourceAbsolute)).birthtime; - } - return new Date(result.timestamp); - } - - const date = await getDate(); + const date = await getBlogPostDate({ + frontMatterDate: frontMatter.date, + filenameDate: parsedBlogFileName.date, + filePath: blogSourceAbsolute, + vcs, + }); const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text; const description = frontMatter.description ?? excerpt ?? ''; diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json index 7619e43145bc..b93c7e1542e5 100644 --- a/packages/docusaurus-plugin-content-docs/package.json +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -47,7 +47,7 @@ "@types/react-router-config": "^5.0.11", "combine-promises": "^1.2.0", "fs-extra": "^11.4.0", - "js-yaml": "^4.3.2", + "js-yaml": "^5.4.1", "lodash": "^4.18.1", "schema-dts": "^1.1.5", "tslib": "^2.8.1", @@ -55,7 +55,6 @@ "webpack": "^5.111.0" }, "devDependencies": { - "@types/js-yaml": "^4.0.9", "@types/picomatch": "^2.3.4", "commander": "^5.1.0", "picomatch": "^2.3.2" diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts index 6af73d22ad0d..a39d78d4efe9 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/index.ts @@ -10,7 +10,7 @@ import path from 'path'; import _ from 'lodash'; import logger from '@docusaurus/logger'; import {loadFreshModule, Globby} from '@docusaurus/utils'; -import Yaml from 'js-yaml'; +import * as Yaml from 'js-yaml'; import combinePromises from 'combine-promises'; import {validateSidebars, validateCategoryMetadataFile} from './validation'; import {normalizeSidebars} from './normalization'; diff --git a/packages/docusaurus-utils-validation/package.json b/packages/docusaurus-utils-validation/package.json index 6e4198d4173f..857dcf9458a0 100644 --- a/packages/docusaurus-utils-validation/package.json +++ b/packages/docusaurus-utils-validation/package.json @@ -23,13 +23,10 @@ "@docusaurus/utils-common": "workspace:*", "fs-extra": "^11.4.0", "joi": "^18.2.8", - "js-yaml": "^4.3.2", + "js-yaml": "^5.4.1", "lodash": "^4.18.1", "tslib": "^2.8.1" }, - "devDependencies": { - "@types/js-yaml": "^4.0.9" - }, "engines": { "node": ">=26.9" } diff --git a/packages/docusaurus-utils-validation/src/tagsFile.ts b/packages/docusaurus-utils-validation/src/tagsFile.ts index 55f9550102ed..acb22a9a3f7b 100644 --- a/packages/docusaurus-utils-validation/src/tagsFile.ts +++ b/packages/docusaurus-utils-validation/src/tagsFile.ts @@ -9,7 +9,7 @@ import fs from 'fs-extra'; import path from 'node:path'; import _ from 'lodash'; import Joi from 'joi'; -import YAML from 'js-yaml'; +import * as YAML from 'js-yaml'; import {getContentPathList, getDataFilePath} from '@docusaurus/utils'; import type { ContentPaths, diff --git a/packages/docusaurus-utils-validation/src/validationUtils.ts b/packages/docusaurus-utils-validation/src/validationUtils.ts index 6b3a891571fd..dde57fe49112 100644 --- a/packages/docusaurus-utils-validation/src/validationUtils.ts +++ b/packages/docusaurus-utils-validation/src/validationUtils.ts @@ -6,7 +6,7 @@ */ import logger from '@docusaurus/logger'; -import Yaml from 'js-yaml'; +import * as Yaml from 'js-yaml'; import {PluginIdSchema} from './validationSchemas'; import type {ValidationOptions} from 'joi'; import type Joi from './Joi'; diff --git a/packages/docusaurus-utils/package.json b/packages/docusaurus-utils/package.json index 870077a00eed..83b1a5942372 100644 --- a/packages/docusaurus-utils/package.json +++ b/packages/docusaurus-utils/package.json @@ -18,7 +18,7 @@ }, "license": "MIT", "dependencies": { - "@11ty/gray-matter": "^2.1.0", + "@11ty/gray-matter": "^3.0.0", "@docusaurus/logger": "workspace:*", "@docusaurus/types": "workspace:*", "@docusaurus/utils-common": "workspace:*", @@ -27,7 +27,7 @@ "fs-extra": "^11.4.0", "github-slugger": "^2.0.0", "jiti": "^2.7.0", - "js-yaml": "^4.3.2", + "js-yaml": "^5.4.1", "lodash": "^4.18.1", "micromatch": "^4.0.8", "p-queue": "^6.6.2", @@ -44,7 +44,6 @@ }, "devDependencies": { "@types/dedent": "^0.7.2", - "@types/js-yaml": "^4.0.9", "@types/micromatch": "^4.0.10", "@types/react-dom": "^19.3.0", "dedent": "^1.7.2" diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/comments.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/comments.yml new file mode 100644 index 000000000000..d5e27cc13d2f --- /dev/null +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/comments.yml @@ -0,0 +1 @@ +# No YAML document diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/invalid.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/invalid.yml index 54bd7745b096..e928da266e91 100644 --- a/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/invalid.yml +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/invalid.yml @@ -1 +1 @@ -}{{{{12434665¨£%£%%£%£}}}} +value: [one,,two] diff --git a/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/schema.yml b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/schema.yml new file mode 100644 index 000000000000..c2b47669f0b1 --- /dev/null +++ b/packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/schema.yml @@ -0,0 +1,5 @@ +date: 2000-07-23 +defaults: &defaults + title: Default title +page: + <<: *defaults diff --git a/packages/docusaurus-utils/src/__tests__/dataFileUtils.test.ts b/packages/docusaurus-utils/src/__tests__/dataFileUtils.test.ts index f0750cd24899..b1149140e086 100644 --- a/packages/docusaurus-utils/src/__tests__/dataFileUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/dataFileUtils.test.ts @@ -160,13 +160,27 @@ describe('getDataFileData', () => { ).rejects.toThrowErrorMatchingInlineSnapshot( ` [Error: The file at "packages/docusaurus-utils/src/__tests__/__fixtures__/dataFiles/dataFiles/invalid.yml" looks invalid (not Yaml nor JSON).] - Cause: [YAMLException: end of the stream or a document separator is expected (1:1) + Cause: [YAMLException: expected the node content, but found ',' (1:13) - 1 | }{{{{12434665¨£%£%%£%£}}}} - -----^] + 1 | value: [one,,two] + -----------------^] `, ); }); + + it('uses YAML 1.2 core types for data files', async () => { + await expect(testFile('schema.yml')).resolves.toEqual({ + date: '2000-07-23', + defaults: {title: 'Default title'}, + page: {'<<': {title: 'Default title'}}, + }); + }); + + it('rejects data files without a YAML document', async () => { + await expect(testFile('comments.yml')).rejects.toThrow( + 'looks invalid (not Yaml nor JSON)', + ); + }); }); describe('findFolderContainingFile', () => { diff --git a/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts b/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts index 148237a09e47..2bd2b011d937 100644 --- a/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts +++ b/packages/docusaurus-utils/src/__tests__/markdownUtils.test.ts @@ -807,13 +807,13 @@ describe('parseFileContentFrontMatter', () => { content: 'Some text', frontMatter: { title: 'Frontmatter title', - author: {age: 42, birth: new Date('2000-07-23')}, + author: {age: 42, birth: '2000-07-23'}, }, }; const result = test(input) as typeof expectedResult; expect(result).toEqual(expectedResult); - expect(result.frontMatter.author.birth).toBeInstanceOf(Date); + expect(result.frontMatter.author.birth).toBe('2000-07-23'); // A regression test, ensure we don't return gray-matter cached objects result.frontMatter.title = 'modified'; @@ -821,6 +821,57 @@ describe('parseFileContentFrontMatter', () => { result.frontMatter.author.age = 53; expect(test(input)).toEqual(expectedResult); }); + + it('uses YAML 1.2 core scalar types and keeps merge keys literal', () => { + expect( + test(dedent` + --- + defaults: &defaults + title: Default title + page: + <<: *defaults + date: 2026-09-18T12:00:00Z + enabled: true + answer: yes + binary: 0b10 + octal: 0o10 + --- + Content + `), + ).toEqual({ + content: 'Content', + frontMatter: { + defaults: {title: 'Default title'}, + page: {'<<': {title: 'Default title'}}, + date: '2026-09-18T12:00:00Z', + enabled: true, + answer: 'yes', + binary: '0b10', + octal: 8, + }, + }); + }); + + it.each(['!!timestamp 2000-07-23', '!!binary SGVsbG8=', '!!set {foo: null}'])( + 'rejects legacy YAML tags: %s', + (value) => { + expect(() => test(`---\nvalue: ${value}\n---`)).toThrow(); + }, + ); + + it('rejects complex mapping keys', () => { + expect(() => test('---\n? [foo, bar]\n: value\n---')).toThrow(); + }); + + it.each(['', '\n', '# Only a comment'])( + 'accepts empty front matter: %j', + (value) => { + expect(test(`---\n${value}\n---\nContent`)).toEqual({ + content: 'Content', + frontMatter: {}, + }); + }, + ); }); describe('parseMarkdownFile', () => { diff --git a/packages/docusaurus-utils/src/dataFileUtils.ts b/packages/docusaurus-utils/src/dataFileUtils.ts index b0ef397fcec4..3cfaf95ad591 100644 --- a/packages/docusaurus-utils/src/dataFileUtils.ts +++ b/packages/docusaurus-utils/src/dataFileUtils.ts @@ -8,7 +8,7 @@ import fs from 'fs-extra'; import path from 'path'; import logger from '@docusaurus/logger'; -import Yaml from 'js-yaml'; +import * as Yaml from 'js-yaml'; import {findAsyncSequential} from './index'; import type {ContentPaths} from './markdownLinks'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 91072cd82a66..d3fc2746182e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1121,8 +1121,8 @@ importers: specifier: ^11.4.0 version: 11.4.0 js-yaml: - specifier: ^4.3.2 - version: 4.3.2 + specifier: ^5.4.1 + version: 5.4.1 lodash: specifier: ^4.18.1 version: 4.18.1 @@ -1145,9 +1145,6 @@ importers: specifier: ^5.111.0 version: 5.111.0(@swc/core@1.16.2)(@swc/html@1.16.2)(clean-css@5.3.3)(cssnano@7.1.9(postcss@8.5.28))(csso@5.0.5)(html-minifier-terser@7.2.0)(lightningcss@1.33.0)(postcss@8.5.28)(sharp@0.35.4(@types/node@25.9.5))(svgo@4.1.0)(uglify-js@3.19.3) devDependencies: - '@types/js-yaml': - specifier: ^4.0.9 - version: 4.0.9 '@types/picomatch': specifier: ^2.3.4 version: 2.3.4 @@ -2004,8 +2001,8 @@ importers: packages/docusaurus-utils: dependencies: '@11ty/gray-matter': - specifier: ^2.1.0 - version: 2.1.0 + specifier: ^3.0.0 + version: 3.0.0 '@docusaurus/logger': specifier: workspace:* version: link:../docusaurus-logger @@ -2031,8 +2028,8 @@ importers: specifier: ^2.7.0 version: 2.7.0 js-yaml: - specifier: ^4.3.2 - version: 4.3.2 + specifier: ^5.4.1 + version: 5.4.1 lodash: specifier: ^4.18.1 version: 4.18.1 @@ -2067,9 +2064,6 @@ importers: '@types/dedent': specifier: ^0.7.2 version: 0.7.2 - '@types/js-yaml': - specifier: ^4.0.9 - version: 4.0.9 '@types/micromatch': specifier: ^4.0.10 version: 4.0.10 @@ -2107,18 +2101,14 @@ importers: specifier: ^18.2.8 version: 18.2.8 js-yaml: - specifier: ^4.3.2 - version: 4.3.2 + specifier: ^5.4.1 + version: 5.4.1 lodash: specifier: ^4.18.1 version: 4.18.1 tslib: specifier: ^2.8.1 version: 2.8.1 - devDependencies: - '@types/js-yaml': - specifier: ^4.0.9 - version: 4.0.9 packages/eslint-plugin: dependencies: @@ -2311,8 +2301,8 @@ importers: packages: - '@11ty/gray-matter@2.1.0': - resolution: {integrity: sha512-fNdBOb3MgDz/1UCIoeY4wDuGbp+/3s5y6UrsyfMabECbh/CVycj7Er33JXqSxRwxrRKXcGE1Jipuq/1mODInsQ==} + '@11ty/gray-matter@3.0.0': + resolution: {integrity: sha512-mi6KB36DZCpCfCb9XP3NtDDNXe1N0jKtuFj9mTCZNy5H7vTabODyMgFmmOiGIGJKt+i8mJqEb/REtK+JTEzlpQ==} engines: {node: '>=11'} '@adobe/css-tools@4.5.0': @@ -6071,9 +6061,6 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -9473,6 +9460,10 @@ packages: resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true + js-yaml@5.4.1: + resolution: {integrity: sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==} + hasBin: true + jsdoc-type-pratt-parser@9.2.1: resolution: {integrity: sha512-V4Ww4EHnTcTLSOMoB0FsF72JhQvcAsriCm/LWnxJeGWoxIjEL2l9na11abQok5SYShq8m0Gl02el/xAbTCulvQ==} engines: {node: ^22.22.2 || >=24.15.0} @@ -13260,9 +13251,9 @@ packages: snapshots: - '@11ty/gray-matter@2.1.0': + '@11ty/gray-matter@3.0.0': dependencies: - js-yaml: 4.3.2 + js-yaml: 5.4.1 section-matter: 1.0.0 '@adobe/css-tools@4.5.0': {} @@ -17409,8 +17400,6 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/js-yaml@4.0.9': {} - '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} @@ -21386,6 +21375,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@5.4.1: + dependencies: + argparse: 2.0.1 + jsdoc-type-pratt-parser@9.2.1: dependencies: '@types/estree': 1.0.9 From 7f6caf08a004f6ac6be13047fe10f83d94f4f836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Fri, 18 Sep 2026 17:52:31 +0200 Subject: [PATCH 4/5] break(cli): upgrade Commander to v15 (AI-assisted) (#12466) * chore: upgrade Commander to v15 (AI-assisted) * test: simplify CLI compatibility cases (AI-assisted) --- packages/create-docusaurus/package.json | 2 +- .../package.json | 2 +- .../src/__tests__/index.test.ts | 8 +- packages/docusaurus-types/package.json | 2 +- packages/docusaurus-types/src/plugin.d.ts | 4 +- packages/docusaurus/package.json | 2 +- .../__fixtures__/site/docusaurus.config.js | 45 ++++- .../src/commands/__tests__/cli.test.ts | 191 +++++++++++++++--- packages/docusaurus/src/commands/cli.ts | 19 +- packages/docusaurus/src/commands/external.ts | 4 +- pnpm-lock.yaml | 22 +- .../plugin-methods/extend-infrastructure.mdx | 8 +- 12 files changed, 243 insertions(+), 66 deletions(-) diff --git a/packages/create-docusaurus/package.json b/packages/create-docusaurus/package.json index 27145077fe0b..56296ab9c4a8 100755 --- a/packages/create-docusaurus/package.json +++ b/packages/create-docusaurus/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "@docusaurus/logger": "workspace:*", - "commander": "^5.1.0", + "commander": "^15.0.0", "cross-spawn": "^7.0.6", "prompts": "^2.4.2", "semver": "^7.8.5", diff --git a/packages/docusaurus-plugin-content-docs/package.json b/packages/docusaurus-plugin-content-docs/package.json index b93c7e1542e5..2f822ecf1317 100644 --- a/packages/docusaurus-plugin-content-docs/package.json +++ b/packages/docusaurus-plugin-content-docs/package.json @@ -56,7 +56,7 @@ }, "devDependencies": { "@types/picomatch": "^2.3.4", - "commander": "^5.1.0", + "commander": "^15.0.0", "picomatch": "^2.3.2" }, "peerDependencies": { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index 5dd9927c22ba..73708479909d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import _ from 'lodash'; import {isMatch} from 'picomatch'; -import commander from 'commander'; +import {Command} from 'commander'; import webpack from 'webpack'; import {loadContext} from '@docusaurus/core/src/server/site'; import { @@ -258,7 +258,7 @@ describe('simple website', () => { const mock = vi .spyOn(cliDocs, 'cliDocsVersionCommand') .mockImplementation(async () => {}); - const cli = new commander.Command(); + const cli = new Command(); plugin.extendCli!(cli); cli.parse(['node', 'test', 'docs:version', '1.0.0']); expect(mock).toHaveBeenCalledTimes(1); @@ -413,7 +413,7 @@ describe('versioned website', () => { const mock = vi .spyOn(cliDocs, 'cliDocsVersionCommand') .mockImplementation(async () => {}); - const cli = new commander.Command(); + const cli = new Command(); plugin.extendCli!(cli); cli.parse(['node', 'test', 'docs:version', '2.0.0']); expect(mock).toHaveBeenCalledTimes(1); @@ -598,7 +598,7 @@ describe('versioned website (community)', () => { const mock = vi .spyOn(cliDocs, 'cliDocsVersionCommand') .mockImplementation(async () => {}); - const cli = new commander.Command(); + const cli = new Command(); plugin.extendCli!(cli); cli.parse(['node', 'test', `docs:version:${pluginId}`, '2.0.0']); expect(mock).toHaveBeenCalledTimes(1); diff --git a/packages/docusaurus-types/package.json b/packages/docusaurus-types/package.json index df448b61bb7a..e0f8dcd52193 100644 --- a/packages/docusaurus-types/package.json +++ b/packages/docusaurus-types/package.json @@ -17,7 +17,7 @@ "@types/history": "^4.7.11", "@types/mdast": "^4.0.4", "@types/react": "19.3.0", - "commander": "^5.1.0", + "commander": "^15.0.0", "joi": "^18.2.8", "react-helmet-async": "npm:@slorber/react-helmet-async@1.3.0", "utility-types": "^3.11.0", diff --git a/packages/docusaurus-types/src/plugin.d.ts b/packages/docusaurus-types/src/plugin.d.ts index 53b3c8a1a547..5d0146001482 100644 --- a/packages/docusaurus-types/src/plugin.d.ts +++ b/packages/docusaurus-types/src/plugin.d.ts @@ -8,7 +8,7 @@ import type {CodeTranslations, TranslationFile} from './i18n'; import type {RuleSetRule, Configuration as WebpackConfiguration} from 'webpack'; import type {CustomizeRuleString} from 'webpack-merge/dist/types'; -import type {CommanderStatic} from 'commander'; +import type {Command} from 'commander'; import type Joi from 'joi'; import type {ThemeConfig} from './config'; import type {LoadContext, Props} from './context'; @@ -153,7 +153,7 @@ export type Plugin = { getTypeScriptThemePath?: () => string; getPathsToWatch?: () => string[]; getClientModules?: () => string[]; - extendCli?: (cli: CommanderStatic) => void; + extendCli?: (cli: Command) => void; injectHtmlTags?: (args: {content: Content}) => { headTags?: HtmlTags; preBodyTags?: HtmlTags; diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json index 4314b51b082d..416ace8d3674 100644 --- a/packages/docusaurus/package.json +++ b/packages/docusaurus/package.json @@ -44,7 +44,7 @@ "chokidar": "^3.6.0", "cli-table3": "^0.6.5", "combine-promises": "^1.2.0", - "commander": "^5.1.0", + "commander": "^15.0.0", "core-js": "^3.50.0", "detect-port": "^2.1.0", "escape-html": "^1.0.3", diff --git a/packages/docusaurus/src/commands/__tests__/__fixtures__/site/docusaurus.config.js b/packages/docusaurus/src/commands/__tests__/__fixtures__/site/docusaurus.config.js index a530fd22cee3..bcb19fe8624f 100644 --- a/packages/docusaurus/src/commands/__tests__/__fixtures__/site/docusaurus.config.js +++ b/packages/docusaurus/src/commands/__tests__/__fixtures__/site/docusaurus.config.js @@ -5,10 +5,53 @@ function myCLIPlugin(context, options) { cli .command('cliPlugin:test') .description('Run test cli command') - .option('-to, --test-option', 'Test option') + .option('-t, --test-option', 'Test option') .action(() => { console.log('TEST ACTION'); }); + + cli + .command('cliPlugin:legacy ', {hidden: true}) + .option('--label