Skip to content

node 24 support #1606

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: setup node
uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24
cache: 'npm'

- run: npm ci --ignore-scripts
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-preset-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fetch-depth: 1
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24

- name: npm ci
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
fetch-depth: 1
- uses: actions/setup-node@v4
with:
node-version: 22
node-version: 24

- name: npm ci
run: |
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
# Test node 18/20/22 on ubuntu
# Test node 22 on macos/windows
# Enable annotations only for node 22 + ubuntu
# Test node 18/20/22/24 on ubuntu
# Test node 24 on macos/windows
# Enable annotations only for node 24 + ubuntu
matrix:
os: [ubuntu-latest]
node: [18, 20, 22]
node: [18, 20, 22, 24]
include:
- os: macos-latest
node: 22
node: 24
- os: windows-latest
node: 22
node: 24
- os: ubuntu-latest
is_base_os_version: true
- node: 22
- node: 24
is_base_node_version: true
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.12.0
v24.0.1
2 changes: 1 addition & 1 deletion cli/csstools-cli/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e-package-managers/yarn/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/browserslist/package-json/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/postcss-cli/commonjs/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/postcss-cli/esm/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/typescript/commonjs/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/typescript/esm/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/webpack/bundle-through/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion e2e/webpack/postcss-loader/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion experimental/css-has-pseudo/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion experimental/postcss-gradient-stop-increments/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion experimental/postcss-nesting/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@
"knip": "knip"
},
"volta": {
"node": "22.12.0"
"node": "24.0.1"
}
}
2 changes: 1 addition & 1 deletion packages/base-cli/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/cascade-layer-name-parser/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/color-helpers/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/css-calc/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/css-color-parser/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/css-parser-algorithms/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/css-tokenizer/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/generate-test-cases/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
2 changes: 1 addition & 1 deletion packages/media-query-list-parser/.nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v22.11.0
v24.0.1
4 changes: 4 additions & 0 deletions packages/postcss-tape/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes to PostCSS Tape

### Unreleased (patch)

- Add support for Node 24

### 6.0.0

_February 12, 2025_
Expand Down
2 changes: 1 addition & 1 deletion packages/postcss-tape/dist/index.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/* node:coverage disable */
"use strict";var e=require("node:assert/strict"),s=require("node:fs/promises"),t=require("node:fs"),n=require("node:path"),o=require("postcss"),r=require("postcss-8.4"),i=require("node:test"),a=require("node:url");const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function fileContentsOrEmptyString(e){try{return await s.readFile(e,"utf8")}catch{return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}noopPlugin.postcss=!0;const c={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},p={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"rule-cloner",RuleExit(s){e.has(s)||"to-clone"===s.selector&&(e.add(s),s.cloneBefore({selector:"cloned"}))}}}},l={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"at-rule-cloner",AtRuleExit(s){if(!e.has(s))return"to-clone"===s.params?(e.add(s),void s.cloneBefore({params:"cloned"})):"to-clone"===s.name?(e.add(s),void s.cloneBefore({name:"cloned"})):void 0}}}};class PackageDescriptionError extends Error{constructor(e,s){super(e),this.name="PackageDescriptionError",this.stack=`${this.name}: ${this.message}\n at "${s}" (${a.pathToFileURL(n.resolve("package.json")).href}:1:1)`}}class OutcomeError extends Error{constructor(e,s){super(e),this.name="OutcomeError",this.stack=`${this.name}: ${this.message}\n at ${a.pathToFileURL(n.resolve(s)).href}:1:1`}}exports.atRuleClonerPlugin=l,exports.declarationClonerPlugin=c,exports.postcssTape=function postcssTape(a,c){return async p=>{c=c??{},await i("`postcss` flag is set on exported plugin creator",(()=>{e.equal(a.postcss,!0)})),await i("exported plugin creator is a function",(()=>{e.equal(typeof a,"function")})),await i("`postcssPlugin` is set on a plugin instance",(()=>{const s=a();e.ok(s.postcssPlugin),e.equal(typeof s.postcssPlugin,"string")})),await i("package.json",(async t=>{const n=await s.readFile("./package.json","utf-8"),o=JSON.parse(n);await t.test('includes "postcss-plugin" keyword',(()=>{e.ok(Array.isArray(o.keywords)&&o.keywords?.includes("postcss-plugin"),new PackageDescriptionError('Missing "postcss-plugin" keyword in package.json',"keywords"))})),await t.test('name starts with "postcss-"',{skip:c?.skipPackageNameCheck},(()=>{let s="string"==typeof o.name?o.name:"";if(s.startsWith("@")){const e=s.split("/");s=e.slice(1).join("/")}e.ok(s.startsWith("postcss-"),new PackageDescriptionError(`package name "${s}" does not start with "postcss-"`,"name"))})),await t.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in a},(()=>{e.ok(Object.keys(Object(o.peerDependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must be listed in "peerDependencies"',"peerDependencies")),e.ok(!Object.keys(Object(o.dependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must not be listed in "dependencies"',"dependencies"))}))}));const l=a().postcssPlugin;await i(l,(async i=>{for(const c in p)await i.test(c,(async i=>{const l=p[c];l.before&&await l.before();const u=n.join(".","test",...c.split(":")[0].split(n.posix.sep)),d=n.join(".","test",...c.replace(/:/g,".").split(n.posix.sep)),g="css";let w=`${u}.${g}`,m=`${d}.expect.${g}`,f=`${d}.result.${g}`;l.source&&(w=n.join(".","test",l.source)),l.expect&&(m=n.join(".","test",l.expect)),l.result&&(f=n.join(".","test",l.result));const k=l.plugins??[a(l.options)],h=await fileContentsOrEmptyString(w),y=await fileContentsOrEmptyString(m);let E;try{E=await o(k).process(h,{from:w,to:f,map:{inline:!1,annotation:!1}})}catch(e){if(!(e instanceof Error))throw e;if(reduceInformationInCssSyntaxError(e),l.exception&&l.exception.test(e.message))return;throw e}e.ok(!l.exception,new OutcomeError(`expected an exception matching "${l.exception}"`,w));const x=E.css.toString();{const e=[s.writeFile(f,x,"utf8")];process.env.REWRITE_EXPECTS&&e.push(s.writeFile(m,x,"utf8")),await Promise.all(e)}y||e.ok(t.existsSync(m),new OutcomeError(`Missing expect file: "${m}"`,w)),await i.test("has expected output",(()=>{e.deepEqual(x,y),e.deepEqual(E.warnings().length,l.warnings??0,`Unexpected number warnings:\n${E.warnings().toString()}`)})),await i.test("sourcemaps",(()=>{e.ok(!E.map.toJSON().sources.includes("<no source>"),'Sourcemap is broken. This is most likely a newly created PostCSS AST Node without a value for "source". See: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes')})),l.after&&await l.after(),await i.test("output is parsable with PostCSS",(async()=>{const s=await fileContentsOrEmptyString(f),t=await o([noopPlugin()]).process(s,{from:f,to:f,map:{inline:!1,annotation:!1}});e.deepEqual(t.warnings(),[],"Unexpected warnings on second pass")})),await i.test("The oldest and current PostCSS version produce the same result",{skip:o([noopPlugin()]).version===r([noopPlugin()]).version},(async()=>{const s=await r(k).process(h,{from:w,to:f,map:{inline:!1,annotation:!1}});e.deepEqual(s.css.toString(),x)}))}))}))}},exports.ruleClonerPlugin=p;
"use strict";var e=require("node:assert/strict"),s=require("node:fs/promises"),t=require("node:fs"),n=require("node:path"),o=require("postcss"),r=require("postcss-8.4"),i=require("node:test"),a=require("node:url");const noopPlugin=()=>({postcssPlugin:"noop-plugin",Once(){}});async function fileContentsOrEmptyString(e){try{return await s.readFile(e,"utf8")}catch{return""}}function reduceInformationInCssSyntaxError(e){process.env.DEBUG||(delete e.source,e.input&&delete e.input.source,delete e.postcssNode)}noopPlugin.postcss=!0;const c={postcssPlugin:"declaration-cloner",Declaration(e){"to-clone"===e.prop&&e.cloneBefore({prop:"cloned"})}},p={postcssPlugin:"rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"rule-cloner",RuleExit(s){e.has(s)||"to-clone"===s.selector&&(e.add(s),s.cloneBefore({selector:"cloned"}))}}}},l={postcssPlugin:"at-rule-cloner",prepare(){const e=new WeakSet;return{postcssPlugin:"at-rule-cloner",AtRuleExit(s){if(!e.has(s))return"to-clone"===s.params?(e.add(s),void s.cloneBefore({params:"cloned"})):"to-clone"===s.name?(e.add(s),void s.cloneBefore({name:"cloned"})):void 0}}}};class PackageDescriptionError extends Error{constructor(e,s){super(e),this.name="PackageDescriptionError",this.stack=`${this.name}: ${this.message}\n at "${s}" (${a.pathToFileURL(n.resolve("package.json")).href}:1:1)`}}class OutcomeError extends Error{constructor(e,s){super(e),this.name="OutcomeError",this.stack=`${this.name}: ${this.message}\n at ${a.pathToFileURL(n.resolve(s)).href}:1:1`}}exports.atRuleClonerPlugin=l,exports.declarationClonerPlugin=c,exports.postcssTape=function postcssTape(a,c){return async p=>{c=c??{},await i("`postcss` flag is set on exported plugin creator",(()=>{e.equal(a.postcss,!0)})),await i("exported plugin creator is a function",(()=>{e.equal(typeof a,"function")})),await i("`postcssPlugin` is set on a plugin instance",(()=>{const s=a();e.ok(s.postcssPlugin),e.equal(typeof s.postcssPlugin,"string")})),await i("package.json",(async t=>{const n=await s.readFile("./package.json","utf-8"),o=JSON.parse(n);await t.test('includes "postcss-plugin" keyword',(()=>{e.ok(Array.isArray(o.keywords)&&o.keywords?.includes("postcss-plugin"),new PackageDescriptionError('Missing "postcss-plugin" keyword in package.json',"keywords"))})),await t.test('name starts with "postcss-"',{skip:c?.skipPackageNameCheck},(()=>{let s="string"==typeof o.name?o.name:"";if(s.startsWith("@")){const e=s.split("/");s=e.slice(1).join("/")}e.ok(s.startsWith("postcss-"),new PackageDescriptionError(`package name "${s}" does not start with "postcss-"`,"name"))})),await t.test("`postcss` is a peer dependency and not a direct dependency",{skip:"postcssTapeSelfTest"in a},(()=>{e.ok(Object.keys(Object(o.peerDependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must be listed in "peerDependencies"',"peerDependencies")),e.ok(!Object.keys(Object(o.dependencies)).includes("postcss"),new PackageDescriptionError('"postcss" must not be listed in "dependencies"',"dependencies"))}))}));const l=a().postcssPlugin;await i(l,(async i=>{for(const c in p)await i.test(c,(async i=>{const l=p[c];l.before&&await l.before();const u=n.join(".","test",...c.split(":")[0].split(n.posix.sep)),d=n.join(".","test",...c.replace(/:/g,".").split(n.posix.sep)),g="css";let w=`${u}.${g}`,m=`${d}.expect.${g}`,f=`${d}.result.${g}`;l.source&&(w=n.join(".","test",l.source)),l.expect&&(m=n.join(".","test",l.expect)),l.result&&(f=n.join(".","test",l.result));const k=l.plugins??[a(l.options)],h=await fileContentsOrEmptyString(w),y=await fileContentsOrEmptyString(m);let E,x=null;const P=o([noopPlugin()]).version===r([noopPlugin()]).version;try{E=await o(k).process(h,{from:w,to:f,map:{inline:!1,annotation:!1}});try{x=P?null:await r(k).process(h,{from:w,to:f,map:{inline:!1,annotation:!1}})}catch{}}catch(e){if(!(e instanceof Error))throw e;if(reduceInformationInCssSyntaxError(e),l.exception&&l.exception.test(e.message))return;throw e}e.ok(!l.exception,new OutcomeError(`expected an exception matching "${l.exception}"`,w));const S=E.css.toString();{const e=[s.writeFile(f,S,"utf8")];process.env.REWRITE_EXPECTS&&e.push(s.writeFile(m,S,"utf8")),await Promise.all(e)}y||e.ok(t.existsSync(m),new OutcomeError(`Missing expect file: "${m}"`,w)),l.after&&await l.after();const $=await fileContentsOrEmptyString(f);let q=null;try{q=await o([noopPlugin()]).process($,{from:f,to:f,map:{inline:!1,annotation:!1}})}catch{}await i.test("has expected output",(()=>{e.deepEqual(S,y),e.deepEqual(E.warnings().length,l.warnings??0,`Unexpected number warnings:\n${E.warnings().toString()}`)})),await i.test("sourcemaps",(()=>{e.ok(!E.map.toJSON().sources.includes("<no source>"),'Sourcemap is broken. This is most likely a newly created PostCSS AST Node without a value for "source". See: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#24-set-nodesource-for-new-nodes')})),await i.test("output is parsable with PostCSS",(()=>{e.deepEqual(q?.warnings(),[],"Unexpected warnings on second pass")})),await i.test("The oldest and current PostCSS version produce the same result",{skip:P},(()=>{e.deepEqual(x?.css?.toString(),S)}))}))}))}},exports.ruleClonerPlugin=p;
/* node:coverage enable */
Loading