From ce2d6b027176da329a852e1fd100c976d80cdbf7 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Mon, 28 Sep 2026 21:35:34 +0000 Subject: [PATCH 1/9] Add Node 26 support Expand the repository and published package engine ranges so downstream framework tests can run on Node 26. Add a Node 26 CI leg and document the new supported range. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6435e499-8b9d-4197-8ed5-ad0b0eb5ac37 --- .github/workflows/ci.yml | 3 +++ api/spfx-template-api/README.md | 2 +- apps/spfx-cli/README.md | 2 +- apps/spfx-cli/package.json | 2 +- rush.json | 2 +- tests/spfx-template-test/package.json | 2 +- tools/spfx-cli-build-rig/package.json | 2 +- 7 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23f183ce..4b418949 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,9 @@ jobs: - os: ubuntu-latest nodeVersion: 24.14.x displayName: Ubuntu + - os: ubuntu-latest + nodeVersion: 26.x + displayName: Ubuntu (Node 26) - os: windows-latest nodeVersion: 24.14.x displayName: Windows diff --git a/api/spfx-template-api/README.md b/api/spfx-template-api/README.md index fa81478d..ec3d42db 100644 --- a/api/spfx-template-api/README.md +++ b/api/spfx-template-api/README.md @@ -8,7 +8,7 @@ Programmatic API for loading, rendering, and writing [SharePoint Framework (SPFx npm install @microsoft/spfx-template-api ``` -**Requires Node.js `>=22.14.0 <23.0.0` or `>=24.12.0 <25.0.0`** +**Requires Node.js `>=22.14.0 <23.0.0`, `>=24.12.0 <25.0.0`, or `>=26.0.0 <27.0.0`** --- diff --git a/apps/spfx-cli/README.md b/apps/spfx-cli/README.md index 78eb4ca6..81de60c5 100644 --- a/apps/spfx-cli/README.md +++ b/apps/spfx-cli/README.md @@ -8,7 +8,7 @@ The official CLI for scaffolding [SharePoint Framework (SPFx)](https://aka.ms/sp npm install -g @microsoft/spfx-cli ``` -**Requires Node.js `>=22.14.0 <23.0.0` or `>=24.12.0 <25.0.0`** +**Requires Node.js `>=22.14.0 <23.0.0`, `>=24.12.0 <25.0.0`, or `>=26.0.0 <27.0.0`** --- diff --git a/apps/spfx-cli/package.json b/apps/spfx-cli/package.json index d409c3ea..575861df 100644 --- a/apps/spfx-cli/package.json +++ b/apps/spfx-cli/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "license": "MIT", "engines": { - "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean", diff --git a/rush.json b/rush.json index a2958054..7884deb0 100644 --- a/rush.json +++ b/rush.json @@ -42,7 +42,7 @@ * LTS schedule: https://nodejs.org/en/about/releases/ * LTS versions: https://nodejs.org/en/download/releases/ */ - "nodeSupportedVersionRange": ">=22.14.0 < 23.0.0 || >=24.12.0 < 25.0.0", + "nodeSupportedVersionRange": ">=22.14.0 < 23.0.0 || >=24.12.0 < 25.0.0 || >=26.0.0 < 27.0.0", /** * If the version check above fails, Rush will display a message showing the current diff --git a/tests/spfx-template-test/package.json b/tests/spfx-template-test/package.json index 85205098..61e7dc92 100644 --- a/tests/spfx-template-test/package.json +++ b/tests/spfx-template-test/package.json @@ -6,7 +6,7 @@ "main": "lib/index.js", "license": "MIT", "engines": { - "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft build --clean && heft test", diff --git a/tools/spfx-cli-build-rig/package.json b/tools/spfx-cli-build-rig/package.json index be6b0e96..f97c6c7a 100644 --- a/tools/spfx-cli-build-rig/package.json +++ b/tools/spfx-cli-build-rig/package.json @@ -10,7 +10,7 @@ ], "license": "MIT", "engines": { - "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "packageManager": "pnpm@10.15.1", "scripts": { From ce1bad2c6ac50a0c3384dc08e0b2dfcfd3ccfdd1 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Mon, 28 Sep 2026 21:36:09 +0000 Subject: [PATCH 2/9] Add Node 26 change file Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6435e499-8b9d-4197-8ed5-ad0b0eb5ac37 --- .../iclanton-node-26-support_2026-09-28-21-35-51.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@microsoft/spfx-cli/iclanton-node-26-support_2026-09-28-21-35-51.json diff --git a/common/changes/@microsoft/spfx-cli/iclanton-node-26-support_2026-09-28-21-35-51.json b/common/changes/@microsoft/spfx-cli/iclanton-node-26-support_2026-09-28-21-35-51.json new file mode 100644 index 00000000..6d630dbe --- /dev/null +++ b/common/changes/@microsoft/spfx-cli/iclanton-node-26-support_2026-09-28-21-35-51.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "", + "type": "none", + "packageName": "@microsoft/spfx-cli" + } + ], + "packageName": "@microsoft/spfx-cli", + "email": "ianc@microsoft.com" +} From 4072c12da035b9d7069de211cc47f26865f1ef1d Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Mon, 28 Sep 2026 21:53:14 +0000 Subject: [PATCH 3/9] Fix Jest warnings on Node 26 Require the Jest node environment version that fixes Node 26 localStorage warnings, and override the older transitive constraint from the Heft rig. This prevents successful tests from being reported as Rush warning failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6435e499-8b9d-4197-8ed5-ad0b0eb5ac37 --- common/config/rush/pnpm-config.json | 4 +- common/config/rush/pnpm-lock.yaml | 328 ++++++++++++++------------ common/config/rush/repo-state.json | 2 +- tools/spfx-cli-build-rig/package.json | 2 +- 4 files changed, 179 insertions(+), 157 deletions(-) diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index b276099c..89930951 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -203,7 +203,9 @@ "globalOverrides": { // "example1": "^1.0.0", // "example2": "npm:@company/example2@^1.0.0" - "baseline-browser-mapping": "^2.9.19" + "baseline-browser-mapping": "^2.9.19", + // Jest 30.4 fixes Node 26 localStorage warnings that cause Rush test phases to fail. + "jest-environment-node": "^30.4.0" }, /** diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index d8705155..5c684696 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -6,6 +6,7 @@ settings: overrides: baseline-browser-mapping: ^2.9.19 + jest-environment-node: ^30.4.0 packageExtensionsChecksum: sha256-6R0LZgepyPJVw81HMQ/3O4ZbifJ1cb0gItdR12MAr8w= @@ -127,7 +128,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -176,7 +177,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -225,7 +226,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -274,7 +275,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -323,7 +324,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -369,7 +370,7 @@ importers: version: 1.24.0-beta.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.24.0-beta.2 - version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.3.0)(zod@4.4.3) + version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.5.2)(zod@4.4.3) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -418,7 +419,7 @@ importers: version: 1.24.0-beta.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.24.0-beta.2 - version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.3.0)(zod@4.4.3) + version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.5.2)(zod@4.4.3) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -479,7 +480,7 @@ importers: version: 1.24.0-beta.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.24.0-beta.2 - version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.3.0)(zod@4.4.3) + version: 1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.5.2)(zod@4.4.3) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -543,7 +544,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -592,7 +593,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -641,7 +642,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -699,7 +700,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -766,7 +767,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -830,7 +831,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -894,7 +895,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -943,7 +944,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -983,7 +984,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -1041,7 +1042,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -1099,7 +1100,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -1166,7 +1167,7 @@ importers: version: 1.23.2(@types/node@22.19.13) '@microsoft/spfx-web-build-rig': specifier: 1.23.2 - version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0) + version: 1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2) '@rushstack/eslint-config': specifier: 4.6.4 version: 4.6.4(eslint@8.57.1)(typescript@5.8.3) @@ -1305,8 +1306,8 @@ importers: specifier: 50.6.11 version: 50.6.11(eslint@9.37.0) jest-environment-node: - specifier: ^30.1.2 - version: 30.2.0 + specifier: ^30.4.0 + version: 30.5.2 jest-junit: specifier: ~12.3.0 version: 12.3.0 @@ -2354,10 +2355,6 @@ packages: canvas: optional: true - '@jest/environment@30.2.0': - resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/environment@30.3.0': resolution: {integrity: sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2366,16 +2363,20 @@ packages: resolution: {integrity: sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/environment@30.5.2': + resolution: {integrity: sha512-nwFPOUMbmsjNNRCpnJpB9HbSZu4C07wDDds++5j+j1MezzPLxMPDdbdUVjr2o4RULDOValnDd70taPFI1EtxAg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect-utils@30.3.0': resolution: {integrity: sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/expect@30.3.0': - resolution: {integrity: sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==} + '@jest/expect-utils@30.5.2': + resolution: {integrity: sha512-d/HOLSrJUlBIl6n3LzOa7cjW3xdePm5H5gQw2lixZ/0h157l9sw3mLblzFqnPcTbhDzhRQdBOX3A3KcG73nm5Q==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/fake-timers@30.2.0': - resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} + '@jest/expect@30.3.0': + resolution: {integrity: sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} '@jest/fake-timers@30.3.0': @@ -2386,10 +2387,18 @@ packages: resolution: {integrity: sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/fake-timers@30.5.2': + resolution: {integrity: sha512-GKk0h0tKT5SpDPxDhPg3r9mm5s8/YCBzVNMOGdRiQXwUiMsjU10mVPlMaQstH6/cu50vOb8N9oQUMETHuwwxKw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/get-type@30.1.0': resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/get-type@30.5.0': + resolution: {integrity: sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/globals@30.3.0': resolution: {integrity: sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2402,6 +2411,10 @@ packages: resolution: {integrity: sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/pattern@30.5.0': + resolution: {integrity: sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/reporters@30.3.0': resolution: {integrity: sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2419,6 +2432,10 @@ packages: resolution: {integrity: sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/schemas@30.5.0': + resolution: {integrity: sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/snapshot-utils@30.3.0': resolution: {integrity: sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2439,10 +2456,6 @@ packages: resolution: {integrity: sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/types@30.2.0': - resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - '@jest/types@30.3.0': resolution: {integrity: sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2451,6 +2464,10 @@ packages: resolution: {integrity: sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/types@30.5.1': + resolution: {integrity: sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -3085,7 +3102,7 @@ packages: '@rushstack/heft': ^1.2.17 '@types/jest': ^30.0.0 jest-environment-jsdom: ^30.3.0 - jest-environment-node: ^30.3.0 + jest-environment-node: ^30.4.0 peerDependenciesMeta: '@types/jest': optional: true @@ -3100,7 +3117,7 @@ packages: '@rushstack/heft': ^1.2.19 '@types/jest': ^30.0.0 jest-environment-jsdom: ^30.3.0 - jest-environment-node: ^30.3.0 + jest-environment-node: ^30.4.0 peerDependenciesMeta: '@types/jest': optional: true @@ -3443,9 +3460,6 @@ packages: '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - '@sinonjs/fake-timers@13.0.5': - resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} - '@sinonjs/fake-timers@15.4.0': resolution: {integrity: sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==} @@ -5485,12 +5499,8 @@ packages: canvas: optional: true - jest-environment-node@30.2.0: - resolution: {integrity: sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-environment-node@30.3.0: - resolution: {integrity: sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==} + jest-environment-node@30.5.2: + resolution: {integrity: sha512-Ciz4KgTGIbojxSKpuFImgWJj5EyqfE8xMq9NxWmOXnQywHHS03H9Mv+vaCB29J5pr3JBrY27WbRV18rBdjh8Dg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-haste-map@30.3.0: @@ -5509,10 +5519,6 @@ packages: resolution: {integrity: sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-message-util@30.2.0: - resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-message-util@30.3.0: resolution: {integrity: sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -5521,8 +5527,8 @@ packages: resolution: {integrity: sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-mock@30.2.0: - resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} + jest-message-util@30.5.1: + resolution: {integrity: sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-mock@30.3.0: @@ -5533,6 +5539,10 @@ packages: resolution: {integrity: sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-mock@30.5.2: + resolution: {integrity: sha512-KTHb37Fhj8xY8qPFvTFaFJHcdsumQp+ExsUlgoX232Agmc706gagBs53+CYvulV7MVQo9AgXOUxsqzzVBoJlrA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-pnp-resolver@1.2.3: resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} engines: {node: '>=6'} @@ -5550,6 +5560,10 @@ packages: resolution: {integrity: sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-regex-util@30.5.0: + resolution: {integrity: sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve-dependencies@30.3.0: resolution: {integrity: sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -5570,10 +5584,6 @@ packages: resolution: {integrity: sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-util@30.2.0: - resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-util@30.3.0: resolution: {integrity: sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -5582,14 +5592,18 @@ packages: resolution: {integrity: sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - jest-validate@30.2.0: - resolution: {integrity: sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==} + jest-util@30.5.1: + resolution: {integrity: sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} jest-validate@30.3.0: resolution: {integrity: sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-validate@30.5.1: + resolution: {integrity: sha512-i/buJ56wTpxihE93hQYNMfdOThS87+HGvLZzZJmU4xggPcdTYQq051iwALLCHp3q+SkCGH+EFejQZz5EbBSkkg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-watcher@30.3.0: resolution: {integrity: sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -6377,10 +6391,6 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - pretty-format@30.2.0: - resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - pretty-format@30.3.0: resolution: {integrity: sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -6389,6 +6399,10 @@ packages: resolution: {integrity: sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + pretty-format@30.5.1: + resolution: {integrity: sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -9329,13 +9343,6 @@ snapshots: jest-util: 30.4.1 jsdom: 26.1.0 - '@jest/environment@30.2.0': - dependencies: - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 - '@types/node': 22.19.13 - jest-mock: 30.2.0 - '@jest/environment@30.3.0': dependencies: '@jest/fake-timers': 30.3.0 @@ -9350,10 +9357,21 @@ snapshots: '@types/node': 22.19.13 jest-mock: 30.4.1 + '@jest/environment@30.5.2': + dependencies: + '@jest/fake-timers': 30.5.2 + '@jest/types': 30.5.1 + '@types/node': 22.19.13 + jest-mock: 30.5.2 + '@jest/expect-utils@30.3.0': dependencies: '@jest/get-type': 30.1.0 + '@jest/expect-utils@30.5.2': + dependencies: + '@jest/get-type': 30.5.0 + '@jest/expect@30.3.0': dependencies: expect: 30.3.0 @@ -9361,15 +9379,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/fake-timers@30.2.0': - dependencies: - '@jest/types': 30.2.0 - '@sinonjs/fake-timers': 13.0.5 - '@types/node': 22.19.13 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - '@jest/fake-timers@30.3.0': dependencies: '@jest/types': 30.3.0 @@ -9388,8 +9397,19 @@ snapshots: jest-mock: 30.4.1 jest-util: 30.4.1 + '@jest/fake-timers@30.5.2': + dependencies: + '@jest/types': 30.5.1 + '@sinonjs/fake-timers': 15.4.0 + '@types/node': 22.19.13 + jest-message-util: 30.5.1 + jest-mock: 30.5.2 + jest-util: 30.5.1 + '@jest/get-type@30.1.0': {} + '@jest/get-type@30.5.0': {} + '@jest/globals@30.3.0': dependencies: '@jest/environment': 30.3.0 @@ -9409,6 +9429,11 @@ snapshots: '@types/node': 22.19.13 jest-regex-util: 30.4.0 + '@jest/pattern@30.5.0': + dependencies: + '@types/node': 22.19.13 + jest-regex-util: 30.5.0 + '@jest/reporters@30.3.0': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -9445,6 +9470,10 @@ snapshots: dependencies: '@sinclair/typebox': 0.34.48 + '@jest/schemas@30.5.0': + dependencies: + '@sinclair/typebox': 0.34.48 + '@jest/snapshot-utils@30.3.0': dependencies: '@jest/types': 30.3.0 @@ -9491,7 +9520,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@jest/types@30.2.0': + '@jest/types@30.3.0': dependencies: '@jest/pattern': 30.0.1 '@jest/schemas': 30.0.5 @@ -9501,20 +9530,20 @@ snapshots: '@types/yargs': 17.0.35 chalk: 4.1.2 - '@jest/types@30.3.0': + '@jest/types@30.4.1': dependencies: - '@jest/pattern': 30.0.1 - '@jest/schemas': 30.0.5 + '@jest/pattern': 30.4.0 + '@jest/schemas': 30.4.1 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 22.19.13 '@types/yargs': 17.0.35 chalk: 4.1.2 - '@jest/types@30.4.1': + '@jest/types@30.5.1': dependencies: - '@jest/pattern': 30.4.0 - '@jest/schemas': 30.4.1 + '@jest/pattern': 30.5.0 + '@jest/schemas': 30.5.0 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 '@types/node': 22.19.13 @@ -10626,13 +10655,13 @@ snapshots: - webpack-cli - zod - '@microsoft/spfx-web-build-rig@1.23.2(@types/node@22.19.13)(jest-environment-node@30.3.0)': + '@microsoft/spfx-web-build-rig@1.23.2(@types/node@22.19.13)(jest-environment-node@30.5.2)': dependencies: '@microsoft/api-extractor': 7.58.1(@types/node@22.19.13) '@microsoft/spfx-heft-plugins': 1.23.2(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft': 1.2.17(@types/node@22.19.13) '@rushstack/heft-dev-cert-plugin': 1.1.13(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) - '@rushstack/heft-jest-plugin': 2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.3.0) + '@rushstack/heft-jest-plugin': 2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.5.2) '@rushstack/heft-lint-plugin': 1.2.7(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft-sass-plugin': 1.4.1(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft-static-asset-typings-plugin': 0.1.3(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) @@ -10665,13 +10694,13 @@ snapshots: - utf-8-validate - webpack-cli - '@microsoft/spfx-web-build-rig@1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.3.0)(zod@4.4.3)': + '@microsoft/spfx-web-build-rig@1.24.0-beta.2(@types/node@22.19.13)(jest-environment-node@30.5.2)(zod@4.4.3)': dependencies: '@microsoft/api-extractor': 7.58.7(@types/node@22.19.13) '@microsoft/spfx-heft-plugins': 1.24.0-beta.2(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13)(zod@4.4.3) '@rushstack/heft': 1.2.17(@types/node@22.19.13) '@rushstack/heft-dev-cert-plugin': 1.1.18(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) - '@rushstack/heft-jest-plugin': 2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.3.0)(jest-environment-node@30.3.0) + '@rushstack/heft-jest-plugin': 2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.3.0)(jest-environment-node@30.5.2) '@rushstack/heft-lint-plugin': 1.2.17(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft-sass-plugin': 1.4.1(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft-static-asset-typings-plugin': 0.1.13(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/node@22.19.13) @@ -11100,7 +11129,7 @@ snapshots: transitivePeerDependencies: - '@types/node' - '@rushstack/heft-jest-plugin@2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.3.0)(jest-environment-node@30.3.0)': + '@rushstack/heft-jest-plugin@2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.3.0)(jest-environment-node@30.5.2)': dependencies: '@jest/core': 30.3.0 '@jest/reporters': 30.3.0 @@ -11115,7 +11144,7 @@ snapshots: optionalDependencies: '@types/jest': 30.0.0 jest-environment-jsdom: 30.3.0 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11124,7 +11153,7 @@ snapshots: - supports-color - ts-node - '@rushstack/heft-jest-plugin@2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.3.0)': + '@rushstack/heft-jest-plugin@2.0.6(@rushstack/heft@1.2.17(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.5.2)': dependencies: '@jest/core': 30.3.0 '@jest/reporters': 30.3.0 @@ -11139,7 +11168,7 @@ snapshots: optionalDependencies: '@types/jest': 30.0.0 jest-environment-jsdom: 30.4.1 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11148,7 +11177,7 @@ snapshots: - supports-color - ts-node - '@rushstack/heft-jest-plugin@2.0.9(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.3.0)': + '@rushstack/heft-jest-plugin@2.0.9(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.5.2)': dependencies: '@jest/core': 30.3.0 '@jest/reporters': 30.3.0 @@ -11163,7 +11192,7 @@ snapshots: optionalDependencies: '@types/jest': 30.0.0 jest-environment-jsdom: 30.4.1 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11205,12 +11234,12 @@ snapshots: '@rushstack/eslint-config': 4.6.4(eslint@9.37.0)(typescript@5.8.3) '@rushstack/heft': 1.2.19(@types/node@22.19.13) '@rushstack/heft-api-extractor-plugin': 1.3.19(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/node@22.19.13) - '@rushstack/heft-jest-plugin': 2.0.9(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.3.0) + '@rushstack/heft-jest-plugin': 2.0.9(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/jest@30.0.0)(@types/node@22.19.13)(jest-environment-jsdom@30.4.1)(jest-environment-node@30.5.2) '@rushstack/heft-lint-plugin': 1.2.19(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/node@22.19.13) '@rushstack/heft-typescript-plugin': 1.3.14(@rushstack/heft@1.2.19(@types/node@22.19.13))(@types/node@22.19.13) '@types/jest': 30.0.0 eslint: 9.37.0 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 typescript: 5.8.3 transitivePeerDependencies: - '@types/node' @@ -11667,10 +11696,6 @@ snapshots: dependencies: type-detect: 4.0.8 - '@sinonjs/fake-timers@13.0.5': - dependencies: - '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers@15.4.0': dependencies: '@sinonjs/commons': 3.0.1 @@ -14213,7 +14238,7 @@ snapshots: graceful-fs: 4.2.11 jest-circus: 30.3.0 jest-docblock: 30.2.0 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 jest-regex-util: 30.0.1 jest-resolve: 30.3.0 jest-runner: 30.3.0 @@ -14268,25 +14293,15 @@ snapshots: - supports-color - utf-8-validate - jest-environment-node@30.2.0: + jest-environment-node@30.5.2: dependencies: - '@jest/environment': 30.2.0 - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 + '@jest/environment': 30.5.2 + '@jest/fake-timers': 30.5.2 + '@jest/types': 30.5.1 '@types/node': 22.19.13 - jest-mock: 30.2.0 - jest-util: 30.2.0 - jest-validate: 30.2.0 - - jest-environment-node@30.3.0: - dependencies: - '@jest/environment': 30.3.0 - '@jest/fake-timers': 30.3.0 - '@jest/types': 30.3.0 - '@types/node': 22.19.13 - jest-mock: 30.3.0 - jest-util: 30.3.0 - jest-validate: 30.3.0 + jest-mock: 30.5.2 + jest-util: 30.5.1 + jest-validate: 30.5.1 jest-haste-map@30.3.0: dependencies: @@ -14322,18 +14337,6 @@ snapshots: jest-diff: 30.3.0 pretty-format: 30.3.0 - jest-message-util@30.2.0: - dependencies: - '@babel/code-frame': 7.29.0 - '@jest/types': 30.2.0 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 30.2.0 - slash: 3.0.0 - stack-utils: 2.0.6 - jest-message-util@30.3.0: dependencies: '@babel/code-frame': 7.29.0 @@ -14359,11 +14362,18 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-mock@30.2.0: + jest-message-util@30.5.1: dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.19.13 - jest-util: 30.2.0 + '@babel/code-frame': 7.29.0 + '@jest/types': 30.5.1 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-util: 30.5.1 + picomatch: 4.0.3 + pretty-format: 30.5.1 + slash: 3.0.0 + stack-utils: 2.0.6 jest-mock@30.3.0: dependencies: @@ -14377,6 +14387,13 @@ snapshots: '@types/node': 22.19.13 jest-util: 30.4.1 + jest-mock@30.5.2: + dependencies: + '@jest/expect-utils': 30.5.2 + '@jest/types': 30.5.1 + '@types/node': 22.19.13 + jest-util: 30.5.1 + jest-pnp-resolver@1.2.3(jest-resolve@30.3.0): optionalDependencies: jest-resolve: 30.3.0 @@ -14385,6 +14402,8 @@ snapshots: jest-regex-util@30.4.0: {} + jest-regex-util@30.5.0: {} + jest-resolve-dependencies@30.3.0: dependencies: jest-regex-util: 30.0.1 @@ -14416,7 +14435,7 @@ snapshots: exit-x: 0.2.2 graceful-fs: 4.2.11 jest-docblock: 30.2.0 - jest-environment-node: 30.3.0 + jest-environment-node: 30.5.2 jest-haste-map: 30.3.0 jest-leak-detector: 30.3.0 jest-message-util: 30.3.0 @@ -14483,50 +14502,50 @@ snapshots: transitivePeerDependencies: - supports-color - jest-util@30.2.0: + jest-util@30.3.0: dependencies: - '@jest/types': 30.2.0 + '@jest/types': 30.3.0 '@types/node': 22.19.13 chalk: 4.1.2 ci-info: 4.4.0 graceful-fs: 4.2.11 picomatch: 4.0.3 - jest-util@30.3.0: + jest-util@30.4.1: dependencies: - '@jest/types': 30.3.0 + '@jest/types': 30.4.1 '@types/node': 22.19.13 chalk: 4.1.2 ci-info: 4.4.0 graceful-fs: 4.2.11 picomatch: 4.0.3 - jest-util@30.4.1: + jest-util@30.5.1: dependencies: - '@jest/types': 30.4.1 + '@jest/types': 30.5.1 '@types/node': 22.19.13 chalk: 4.1.2 ci-info: 4.4.0 graceful-fs: 4.2.11 picomatch: 4.0.3 - jest-validate@30.2.0: + jest-validate@30.3.0: dependencies: '@jest/get-type': 30.1.0 - '@jest/types': 30.2.0 + '@jest/types': 30.3.0 camelcase: 6.3.0 chalk: 4.1.2 leven: 3.1.0 - pretty-format: 30.2.0 + pretty-format: 30.3.0 - jest-validate@30.3.0: + jest-validate@30.5.1: dependencies: - '@jest/get-type': 30.1.0 - '@jest/types': 30.3.0 + '@jest/get-type': 30.5.0 + '@jest/types': 30.5.1 camelcase: 6.3.0 chalk: 4.1.2 leven: 3.1.0 - pretty-format: 30.3.0 + pretty-format: 30.5.1 jest-watcher@30.3.0: dependencies: @@ -15454,12 +15473,6 @@ snapshots: prelude-ls@1.2.1: {} - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - pretty-format@30.3.0: dependencies: '@jest/schemas': 30.0.5 @@ -15473,6 +15486,13 @@ snapshots: react-is-18: react-is@18.3.1 react-is-19: react-is@19.2.7 + pretty-format@30.5.1: + dependencies: + '@jest/react-is-18': react-is@18.3.1 + '@jest/react-is-19': react-is@19.2.7 + '@jest/schemas': 30.5.0 + ansi-styles: 5.2.0 + process-nextick-args@2.0.1: {} prop-types@15.8.1: diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index c2f6e9c0..a0447909 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "03b9a8403725f70d0684106a3321c9f0e49b9897", + "pnpmShrinkwrapHash": "0d01c3e0d805c7d940d0cfa82a71071c4d556850", "preferredVersionsHash": "e0fe58342c5c916209e75bfdee56e81689af3359" } diff --git a/tools/spfx-cli-build-rig/package.json b/tools/spfx-cli-build-rig/package.json index f97c6c7a..d9d1d374 100644 --- a/tools/spfx-cli-build-rig/package.json +++ b/tools/spfx-cli-build-rig/package.json @@ -31,7 +31,7 @@ "eslint-plugin-headers": "~1.2.1", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsdoc": "50.6.11", - "jest-environment-node": "^30.1.2", + "jest-environment-node": "^30.4.0", "jest-junit": "~12.3.0", "typescript": "~5.8.3" }, From 8d68622ecb362ff3c657e73b4eba3894dab1d73f Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Tue, 29 Sep 2026 21:34:18 +0000 Subject: [PATCH 4/9] Suppress unrs-resolver/oxc-resolver postinstall to avoid CI feed 401 Jest 30's jest-resolve pulls in unrs-resolver, whose napi-postinstall script downloads a native binding directly from the registry. That raw download is unauthenticated against the internal ODSP feed and fails with a 401, breaking rush update in the SPFx framework test pipeline. Add both resolver packages to globalNeverBuiltDependencies so the postinstall never runs and the packages fall back to their bundled WASM build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5f52707e-be36-4e3b-852d-51275c6f6849 --- common/config/rush/pnpm-config.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index 89930951..47e232d5 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -277,7 +277,11 @@ * PNPM documentation: https://pnpm.io/package_json#pnpmneverbuiltdependencies */ "globalNeverBuiltDependencies": [ - // "fsevents" + // Skip postinstall scripts that download native bindings from the public + // registry; these fail in the internal CI feed and the packages fall back + // to their bundled WASM build. See jest-resolve -> unrs-resolver. + "oxc-resolver", + "unrs-resolver" ], /** From 6af14e8e986874fa59fb4ee9549575a7bb3c755a Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Tue, 29 Sep 2026 22:01:48 +0000 Subject: [PATCH 5/9] Document Node 26 in repo-wide guidance for consistency Update the root README badge and the dev-environment setup doc to list the full supported range (Node 22, 24, and 26), matching the per-package READMEs and rush.json. Addresses the Copilot PR review finding about inconsistent Node version guidance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5f52707e-be36-4e3b-852d-51275c6f6849 --- README.md | 2 +- common/docs/setting-up-your-dev-environment.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8beb0bda..6fe7148f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ CI npm version MIT License - Node.js 22.x | 24.x + Node.js 22.x | 24.x | 26.x SPFx 1.23.2

diff --git a/common/docs/setting-up-your-dev-environment.md b/common/docs/setting-up-your-dev-environment.md index 58780ebc..4d05f8f8 100644 --- a/common/docs/setting-up-your-dev-environment.md +++ b/common/docs/setting-up-your-dev-environment.md @@ -2,7 +2,7 @@ ## Node.js -This repository requires **Node.js >=22.14.0 <23.0.0** (specified in `rush.json`). +This repository requires **Node.js `>=22.14.0 <23.0.0`, `>=24.12.0 <25.0.0`, or `>=26.0.0 <27.0.0`** (specified in `rush.json`). We recommend [**nvs**](https://github.com/jasongin/nvs) (Node Version Switcher) to manage Node.js versions: @@ -14,7 +14,7 @@ nvs add 22 nvs use 22 ``` -Any Node.js version manager (nvm, fnm, volta, etc.) works — just make sure the active version satisfies `>=22.14.0 <23.0.0`. +Any Node.js version manager (nvm, fnm, volta, etc.) works — just make sure the active version satisfies `>=22.14.0 <23.0.0`, `>=24.12.0 <25.0.0`, or `>=26.0.0 <27.0.0`. ## Rush From bb506368fb7da65b4fa6d34bd936bb24fa463ff7 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Wed, 30 Sep 2026 00:20:11 +0000 Subject: [PATCH 6/9] Declare Node 24/26 support in templates, examples, and CLAUDE.md Newly scaffolded projects (and the checked-in examples) still pinned only Node 22 in their engines field, so they would not advertise Node 24/26 support even though the toolchain now allows it. Update all template and example package.json engines ranges to match rush.json and the spfx-cli package, and update the CLAUDE.md prerequisite note. Addresses review NIT. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5f52707e-be36-4e3b-852d-51275c6f6849 --- CLAUDE.md | 2 +- examples/ace-data-visualization/package.json | 2 +- examples/ace-generic-card/package.json | 2 +- examples/ace-generic-image-card/package.json | 2 +- examples/ace-generic-primarytext-card/package.json | 2 +- examples/ace-search-card/package.json | 2 +- examples/copilot-component-minimal/package.json | 2 +- examples/copilot-component-noframework/package.json | 2 +- examples/copilot-component-react/package.json | 2 +- examples/extension-application-customizer/package.json | 2 +- examples/extension-fieldcustomizer-minimal/package.json | 2 +- examples/extension-fieldcustomizer-noframework/package.json | 2 +- examples/extension-fieldcustomizer-react/package.json | 2 +- examples/extension-formcustomizer-noframework/package.json | 2 +- examples/extension-formcustomizer-react/package.json | 2 +- examples/extension-listviewcommandset/package.json | 2 +- examples/extension-search-query-modifier/package.json | 2 +- examples/library/package.json | 2 +- examples/webpart-minimal/package.json | 2 +- examples/webpart-noframework/package.json | 2 +- examples/webpart-react/package.json | 2 +- templates/ace-data-visualization/package.json | 2 +- templates/ace-generic-card/package.json | 2 +- templates/ace-generic-image-card/package.json | 2 +- templates/ace-generic-primarytext-card/package.json | 2 +- templates/ace-search-card/package.json | 2 +- templates/copilot-component-minimal/package.json | 2 +- templates/copilot-component-noframework/package.json | 2 +- templates/copilot-component-react/package.json | 2 +- templates/extension-application-customizer/package.json | 2 +- templates/extension-fieldcustomizer-minimal/package.json | 2 +- templates/extension-fieldcustomizer-noframework/package.json | 2 +- templates/extension-fieldcustomizer-react/package.json | 2 +- templates/extension-formcustomizer-noframework/package.json | 2 +- templates/extension-formcustomizer-react/package.json | 2 +- templates/extension-listviewcommandset/package.json | 2 +- templates/extension-search-query-modifier/package.json | 2 +- templates/library/package.json | 2 +- templates/webpart-minimal/package.json | 2 +- templates/webpart-noframework/package.json | 2 +- templates/webpart-react/package.json | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 3760a328..6c5e45ba 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This document contains important information for Claude (AI assistant) when work ### Node.js Version Management -This repository requires **Node.js 22.14.0 or later** (but < 23.0.0) as specified in `rush.json`. +This repository requires **Node.js `>=22.14.0 <23.0.0`, `>=24.12.0 <25.0.0`, or `>=26.0.0 <27.0.0`** as specified in `rush.json`. **IMPORTANT**: This system uses **nvs** (Node Version Switcher) to manage Node.js versions. diff --git a/examples/ace-data-visualization/package.json b/examples/ace-data-visualization/package.json index 346775a4..160bdfd2 100644 --- a/examples/ace-data-visualization/package.json +++ b/examples/ace-data-visualization/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/ace-generic-card/package.json b/examples/ace-generic-card/package.json index 44c4d9bc..1903ae99 100644 --- a/examples/ace-generic-card/package.json +++ b/examples/ace-generic-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/ace-generic-image-card/package.json b/examples/ace-generic-image-card/package.json index 0053b0c4..b9350f46 100644 --- a/examples/ace-generic-image-card/package.json +++ b/examples/ace-generic-image-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/ace-generic-primarytext-card/package.json b/examples/ace-generic-primarytext-card/package.json index 5a4a9384..2c38c267 100644 --- a/examples/ace-generic-primarytext-card/package.json +++ b/examples/ace-generic-primarytext-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/ace-search-card/package.json b/examples/ace-search-card/package.json index 180a8815..9ab6a19d 100644 --- a/examples/ace-search-card/package.json +++ b/examples/ace-search-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/copilot-component-minimal/package.json b/examples/copilot-component-minimal/package.json index f3d41f04..cfc0fa62 100644 --- a/examples/copilot-component-minimal/package.json +++ b/examples/copilot-component-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/copilot-component-noframework/package.json b/examples/copilot-component-noframework/package.json index b9a01a94..504c200d 100644 --- a/examples/copilot-component-noframework/package.json +++ b/examples/copilot-component-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/copilot-component-react/package.json b/examples/copilot-component-react/package.json index 5d0211b5..b1b3b594 100644 --- a/examples/copilot-component-react/package.json +++ b/examples/copilot-component-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-application-customizer/package.json b/examples/extension-application-customizer/package.json index 04164407..c8b377a3 100644 --- a/examples/extension-application-customizer/package.json +++ b/examples/extension-application-customizer/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-fieldcustomizer-minimal/package.json b/examples/extension-fieldcustomizer-minimal/package.json index fdbeee92..8f5773dd 100644 --- a/examples/extension-fieldcustomizer-minimal/package.json +++ b/examples/extension-fieldcustomizer-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-fieldcustomizer-noframework/package.json b/examples/extension-fieldcustomizer-noframework/package.json index 623fb773..395a46c0 100644 --- a/examples/extension-fieldcustomizer-noframework/package.json +++ b/examples/extension-fieldcustomizer-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-fieldcustomizer-react/package.json b/examples/extension-fieldcustomizer-react/package.json index 3ceaed10..d5fd4e55 100644 --- a/examples/extension-fieldcustomizer-react/package.json +++ b/examples/extension-fieldcustomizer-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-formcustomizer-noframework/package.json b/examples/extension-formcustomizer-noframework/package.json index 135c72fe..09cb3fdc 100644 --- a/examples/extension-formcustomizer-noframework/package.json +++ b/examples/extension-formcustomizer-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-formcustomizer-react/package.json b/examples/extension-formcustomizer-react/package.json index cc42884c..de2b84f6 100644 --- a/examples/extension-formcustomizer-react/package.json +++ b/examples/extension-formcustomizer-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-listviewcommandset/package.json b/examples/extension-listviewcommandset/package.json index 56858527..97f0ae74 100644 --- a/examples/extension-listviewcommandset/package.json +++ b/examples/extension-listviewcommandset/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/extension-search-query-modifier/package.json b/examples/extension-search-query-modifier/package.json index 91da37c7..d2b888c0 100644 --- a/examples/extension-search-query-modifier/package.json +++ b/examples/extension-search-query-modifier/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/library/package.json b/examples/library/package.json index 664b1be1..5e593127 100644 --- a/examples/library/package.json +++ b/examples/library/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": false, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/webpart-minimal/package.json b/examples/webpart-minimal/package.json index 28df21bb..b6b85937 100644 --- a/examples/webpart-minimal/package.json +++ b/examples/webpart-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/webpart-noframework/package.json b/examples/webpart-noframework/package.json index 91a5bcaa..5d495a30 100644 --- a/examples/webpart-noframework/package.json +++ b/examples/webpart-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/examples/webpart-react/package.json b/examples/webpart-react/package.json index c200892a..4e7cc997 100644 --- a/examples/webpart-react/package.json +++ b/examples/webpart-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/ace-data-visualization/package.json b/templates/ace-data-visualization/package.json index 89043b20..8236ce26 100644 --- a/templates/ace-data-visualization/package.json +++ b/templates/ace-data-visualization/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/ace-generic-card/package.json b/templates/ace-generic-card/package.json index 89043b20..8236ce26 100644 --- a/templates/ace-generic-card/package.json +++ b/templates/ace-generic-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/ace-generic-image-card/package.json b/templates/ace-generic-image-card/package.json index 89043b20..8236ce26 100644 --- a/templates/ace-generic-image-card/package.json +++ b/templates/ace-generic-image-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/ace-generic-primarytext-card/package.json b/templates/ace-generic-primarytext-card/package.json index 89043b20..8236ce26 100644 --- a/templates/ace-generic-primarytext-card/package.json +++ b/templates/ace-generic-primarytext-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/ace-search-card/package.json b/templates/ace-search-card/package.json index 89043b20..8236ce26 100644 --- a/templates/ace-search-card/package.json +++ b/templates/ace-search-card/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/copilot-component-minimal/package.json b/templates/copilot-component-minimal/package.json index 0d570307..16e2fb16 100644 --- a/templates/copilot-component-minimal/package.json +++ b/templates/copilot-component-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/copilot-component-noframework/package.json b/templates/copilot-component-noframework/package.json index 29445ae6..cc6c40e3 100644 --- a/templates/copilot-component-noframework/package.json +++ b/templates/copilot-component-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/copilot-component-react/package.json b/templates/copilot-component-react/package.json index a9462510..fde78ec5 100644 --- a/templates/copilot-component-react/package.json +++ b/templates/copilot-component-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-application-customizer/package.json b/templates/extension-application-customizer/package.json index f5f4fc47..7c50c053 100644 --- a/templates/extension-application-customizer/package.json +++ b/templates/extension-application-customizer/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-fieldcustomizer-minimal/package.json b/templates/extension-fieldcustomizer-minimal/package.json index e6de015c..6deb4c24 100644 --- a/templates/extension-fieldcustomizer-minimal/package.json +++ b/templates/extension-fieldcustomizer-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-fieldcustomizer-noframework/package.json b/templates/extension-fieldcustomizer-noframework/package.json index e6de015c..6deb4c24 100644 --- a/templates/extension-fieldcustomizer-noframework/package.json +++ b/templates/extension-fieldcustomizer-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-fieldcustomizer-react/package.json b/templates/extension-fieldcustomizer-react/package.json index 2d7f444f..7f77ae57 100644 --- a/templates/extension-fieldcustomizer-react/package.json +++ b/templates/extension-fieldcustomizer-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-formcustomizer-noframework/package.json b/templates/extension-formcustomizer-noframework/package.json index c22419c9..75b60a6f 100644 --- a/templates/extension-formcustomizer-noframework/package.json +++ b/templates/extension-formcustomizer-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-formcustomizer-react/package.json b/templates/extension-formcustomizer-react/package.json index b596c2b8..482a8b45 100644 --- a/templates/extension-formcustomizer-react/package.json +++ b/templates/extension-formcustomizer-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-listviewcommandset/package.json b/templates/extension-listviewcommandset/package.json index 26bd6f0c..435cc66b 100644 --- a/templates/extension-listviewcommandset/package.json +++ b/templates/extension-listviewcommandset/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/extension-search-query-modifier/package.json b/templates/extension-search-query-modifier/package.json index cd6ae260..6a4453b1 100644 --- a/templates/extension-search-query-modifier/package.json +++ b/templates/extension-search-query-modifier/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/library/package.json b/templates/library/package.json index b53ab947..f4bb5a02 100644 --- a/templates/library/package.json +++ b/templates/library/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": false, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/webpart-minimal/package.json b/templates/webpart-minimal/package.json index dee594c5..41dcdc06 100644 --- a/templates/webpart-minimal/package.json +++ b/templates/webpart-minimal/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/webpart-noframework/package.json b/templates/webpart-noframework/package.json index dee594c5..41dcdc06 100644 --- a/templates/webpart-noframework/package.json +++ b/templates/webpart-noframework/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", diff --git a/templates/webpart-react/package.json b/templates/webpart-react/package.json index 7f8f32ce..dea6af87 100644 --- a/templates/webpart-react/package.json +++ b/templates/webpart-react/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "engines": { - "node": ">=22.14.0 < 23.0.0" + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0" }, "scripts": { "build": "heft test --clean --production && heft package-solution --production", From a24770b9a8a1f001c870fd6f61431ae13be009a1 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Wed, 30 Sep 2026 03:55:28 +0000 Subject: [PATCH 7/9] fixup! Declare Node 24/26 support in templates, examples, and CLAUDE.md --- .../src/tests/__snapshots__/multi-component.test.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/spfx-template-test/src/tests/__snapshots__/multi-component.test.ts.snap b/tests/spfx-template-test/src/tests/__snapshots__/multi-component.test.ts.snap index 00d77a47..0e23e5b0 100644 --- a/tests/spfx-template-test/src/tests/__snapshots__/multi-component.test.ts.snap +++ b/tests/spfx-template-test/src/tests/__snapshots__/multi-component.test.ts.snap @@ -145,7 +145,7 @@ Object { "typescript": "~5.8.3", }, "engines": Object { - "node": ">=22.14.0 < 23.0.0", + "node": ">=22.14.0 <23.0.0 || >=24.12.0 <25.0.0 || >=26.0.0 <27.0.0", }, "name": "@spfx-template/multi-component-test", "private": true, From df3ab07e607fc5d8ac529828d3a54e2f977981b5 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Wed, 30 Sep 2026 04:16:44 +0000 Subject: [PATCH 8/9] Inject fs-extra into @microsoft/app-manifest to fix SPFx plugin load @microsoft/app-manifest's compiled build/index.js does require('fs-extra') but only declares @types/fs-extra, so under pnpm's strict isolation the SPFx copilotAgentPlugin fails to load with "Cannot find module 'fs-extra'" when scaffolded solutions are built. Add a globalPackageExtensions entry declaring the missing runtime dependency, mirroring the workaround already present in odsp-web. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5f52707e-be36-4e3b-852d-51275c6f6849 --- common/config/rush/pnpm-config.json | 11 +++++++++++ common/config/rush/pnpm-lock.yaml | 3 ++- common/config/rush/repo-state.json | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index 47e232d5..bce6fd77 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -262,6 +262,17 @@ "@rushstack/eslint-plugin-security": "*", "eslint-plugin-promise": "*" } + }, + + // @microsoft/app-manifest's compiled build/*.js does `require("fs-extra")`, but the package + // only declares `@types/fs-extra` — not the runtime `fs-extra`. npm/codespace installs resolve + // it via hoisting, but under pnpm's strict isolation (and BuildXL CI) it can't, so the SPFx + // copilotAgentPlugin fails to load with "Cannot find module 'fs-extra'". Declare the missing + // runtime dependency here, version-matched to the package's own `@types/fs-extra` (^11). + "@microsoft/app-manifest": { + "dependencies": { + "fs-extra": "^11.3.1" + } } }, diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5c684696..1471e68d 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -8,7 +8,7 @@ overrides: baseline-browser-mapping: ^2.9.19 jest-environment-node: ^30.4.0 -packageExtensionsChecksum: sha256-6R0LZgepyPJVw81HMQ/3O4ZbifJ1cb0gItdR12MAr8w= +packageExtensionsChecksum: sha256-ZPUcDJ3wZg5W+aLS1G0QW9fFXD6lhCTBDwmMllpLOzA= pnpmfileChecksum: sha256-E1T7OJ3DLTjpDqf4RdJzK9VDtAxgm4gDEQCLYdHD8nI= @@ -9789,6 +9789,7 @@ snapshots: ajv: 8.18.0 ajv-draft-04: 1.0.0(ajv@8.18.0) ajv-formats: 3.0.1 + fs-extra: 11.3.4 node-fetch: 3.3.2 strip-bom: 5.0.0 diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index a0447909..e35912ce 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "0d01c3e0d805c7d940d0cfa82a71071c4d556850", + "pnpmShrinkwrapHash": "f5808affa48b35c2f34ee02cdad35651b2579e5a", "preferredVersionsHash": "e0fe58342c5c916209e75bfdee56e81689af3359" } From 5d6a693eaeaf87d687c976ef063bc1c567ddafc8 Mon Sep 17 00:00:00 2001 From: Ian Clanton-Thuon Date: Wed, 30 Sep 2026 05:38:47 +0000 Subject: [PATCH 9/9] Revert "Inject fs-extra into @microsoft/app-manifest to fix SPFx plugin load" This reverts commit df3ab07e607fc5d8ac529828d3a54e2f977981b5. --- common/config/rush/pnpm-config.json | 11 ----------- common/config/rush/pnpm-lock.yaml | 3 +-- common/config/rush/repo-state.json | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index bce6fd77..47e232d5 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -262,17 +262,6 @@ "@rushstack/eslint-plugin-security": "*", "eslint-plugin-promise": "*" } - }, - - // @microsoft/app-manifest's compiled build/*.js does `require("fs-extra")`, but the package - // only declares `@types/fs-extra` — not the runtime `fs-extra`. npm/codespace installs resolve - // it via hoisting, but under pnpm's strict isolation (and BuildXL CI) it can't, so the SPFx - // copilotAgentPlugin fails to load with "Cannot find module 'fs-extra'". Declare the missing - // runtime dependency here, version-matched to the package's own `@types/fs-extra` (^11). - "@microsoft/app-manifest": { - "dependencies": { - "fs-extra": "^11.3.1" - } } }, diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 1471e68d..5c684696 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -8,7 +8,7 @@ overrides: baseline-browser-mapping: ^2.9.19 jest-environment-node: ^30.4.0 -packageExtensionsChecksum: sha256-ZPUcDJ3wZg5W+aLS1G0QW9fFXD6lhCTBDwmMllpLOzA= +packageExtensionsChecksum: sha256-6R0LZgepyPJVw81HMQ/3O4ZbifJ1cb0gItdR12MAr8w= pnpmfileChecksum: sha256-E1T7OJ3DLTjpDqf4RdJzK9VDtAxgm4gDEQCLYdHD8nI= @@ -9789,7 +9789,6 @@ snapshots: ajv: 8.18.0 ajv-draft-04: 1.0.0(ajv@8.18.0) ajv-formats: 3.0.1 - fs-extra: 11.3.4 node-fetch: 3.3.2 strip-bom: 5.0.0 diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index e35912ce..a0447909 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "f5808affa48b35c2f34ee02cdad35651b2579e5a", + "pnpmShrinkwrapHash": "0d01c3e0d805c7d940d0cfa82a71071c4d556850", "preferredVersionsHash": "e0fe58342c5c916209e75bfdee56e81689af3359" }