{"_id":"selparsecss-selector","_rev":"5-d94488fdd1a1fe508d4155eab507d4f9","name":"selparsecss-selector","dist-tags":{"latest":"2.2.0"},"versions":{"1.0.0":{"name":"selparsecss-selector","version":"1.0.0","keywords":["css","selector","parser","postcss","AST"],"author":{"name":"Ai Pyramid"},"license":"MIT","_id":"selparsecss-selector@1.0.0","maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"contributors":[{"url":"http://pyramid.info","name":"Ai Pyramid","email":"pyramid.info@gmail.com"}],"dist":{"shasum":"baaad29b45a0b5244b3779b1c70008f65fa55e24","tarball":"https://registry.npmjs.org/selparsecss-selector/-/selparsecss-selector-1.0.0.tgz","fileCount":45,"integrity":"sha512-IxGORn8O0lD4XXfozDMPTsZ7WSw08I95fUjhXIiiIqRt8KwZ6WtpiagvZ+HoW038+jPdicSEhFQPiWclW8Y8jw==","signatures":[{"sig":"MEQCIFcaKUrE3ryxaUwMNOFYiXOV+veFlKDDz/K3ePeLB2eaAiAFtGF8cjFPnHcQsAZMjd8vj3TM/d/1tReNxQTvXID54Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":255352},"main":"dist/index.js","types":"selparsecss-selector.d.ts","engines":{"node":">=4"},"gitHead":"e4d637e40d233a3e9b1a675838ab54c4bcaca114","scripts":{"lint":"oxlint","test":"npm run lint && npm run typecheck && npm run coverage","build":"npm run clean && tsc && node scripts/copy-fragment.js","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","tests":"node --test src/__tests__/*.mjs","format":"oxfmt src","prepare":"npm run build","release":"npx npmpub","coverage":"node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs","lint:fix":"oxlint --fix","pretests":"npm run build","typecheck":"tsc --noEmit --strict selparsecss-selector.d.ts selparsecss-selector.test.ts","precoverage":"npm run build","format:check":"oxfmt --check src"},"_npmUser":{"name":"aipyramid","email":"pyramid.info@proton.me"},"_npmVersion":"10.9.4","description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"cssesc":"^3.0.0","bytenode":"^1.5.7","util-deprecate":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.54.0","oxlint":"^1.69.0","postcss":"^8.4.31","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/selparsecss-selector_1.0.0_1784099940798_0.6331579666617331","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"selparsecss-selector","version":"1.1.0","keywords":["css","selector","parser","postcss","AST"],"author":{"name":"Ai Pyramid"},"license":"MIT","_id":"selparsecss-selector@1.1.0","maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"contributors":[{"url":"http://pyramid.info","name":"Ai Pyramid","email":"pyramid.info@gmail.com"}],"dist":{"shasum":"c4d1f8814e41f55a5ae22cb28a4f9cd4171ecc14","tarball":"https://registry.npmjs.org/selparsecss-selector/-/selparsecss-selector-1.1.0.tgz","fileCount":45,"integrity":"sha512-/r3RwVTR4AehaS6so4mZLcCyJO8zypEgCrzlrx/wlhyKoqQpgppSh0RqBfqKeYEH6fcr/h6xtCeUIMsJ9/26kw==","signatures":[{"sig":"MEUCIQDzSZdiLUrYFjiFVtNRwjPfwGJYm3T8Cxy1nJUualLNvQIgSSf6gKA6oy7ehCTDFCvtKz6ImPkOJyq+wfYpg/+Pklk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":255193},"main":"dist/index.js","types":"selparsecss-selector.d.ts","engines":{"node":">=4"},"gitHead":"e4d637e40d233a3e9b1a675838ab54c4bcaca114","scripts":{"lint":"oxlint","test":"npm run lint && npm run typecheck && npm run coverage","build":"npm run clean && tsc && node scripts/copy-fragment.js","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","tests":"node --test src/__tests__/*.mjs","format":"oxfmt src","prepare":"npm run build","release":"npx npmpub","coverage":"node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs","lint:fix":"oxlint --fix","pretests":"npm run build","typecheck":"tsc --noEmit --strict selparsecss-selector.d.ts selparsecss-selector.test.ts","precoverage":"npm run build","format:check":"oxfmt --check src"},"_npmUser":{"name":"aipyramid","email":"pyramid.info@proton.me"},"_npmVersion":"10.9.4","description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"cssesc":"^3.0.0","bytenode":"^1.5.7","util-deprecate":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.54.0","oxlint":"^1.69.0","postcss":"^8.4.31","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/selparsecss-selector_1.1.0_1784100630360_0.14870296051653242","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"selparsecss-selector","version":"2.0.0","keywords":["css","selector","parser","postcss","AST"],"author":{"name":"Ai Pyramid"},"license":"MIT","_id":"selparsecss-selector@2.0.0","maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"contributors":[{"url":"http://pyramid.info","name":"Ai Pyramid","email":"pyramid.info@gmail.com"}],"dist":{"shasum":"bcb15a276f1cd7f511c80ac01fa196b26004d8ea","tarball":"https://registry.npmjs.org/selparsecss-selector/-/selparsecss-selector-2.0.0.tgz","fileCount":45,"integrity":"sha512-qyJCGzGq1Bhy8jwYdFhuN1fJPaS00HG+cDh5lonZq7GBAjOPbAbSn1MhNPts3mV6Czh8miRg2+399EVrtetQUQ==","signatures":[{"sig":"MEYCIQD/AP35C2eY6RnNuSK8mFMVrE0MYuYoJxDLnt7bqa9VVgIhAOQt1mouqcoIZPZq2JkTDn1djC3HRLlYiiJoDo3Ejo7a","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236003},"main":"dist/index.js","types":"selparsecss-selector.d.ts","engines":{"node":">=4"},"gitHead":"e4d637e40d233a3e9b1a675838ab54c4bcaca114","scripts":{"lint":"oxlint","test":"npm run lint && npm run typecheck && npm run coverage","build":"npm run clean && tsc && node scripts/copy-fragment.js","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","tests":"node --test src/__tests__/*.mjs","format":"oxfmt src","prepare":"npm run build","release":"npx npmpub","coverage":"node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs","lint:fix":"oxlint --fix","pretests":"npm run build","typecheck":"tsc --noEmit --strict selparsecss-selector.d.ts selparsecss-selector.test.ts","precoverage":"npm run build","format:check":"oxfmt --check src"},"_npmUser":{"name":"aipyramid","email":"pyramid.info@proton.me"},"_npmVersion":"10.9.4","description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"cssesc":"^3.0.0","bytenode":"^1.5.7","util-deprecate":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.54.0","oxlint":"^1.69.0","postcss":"^8.4.31","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/selparsecss-selector_2.0.0_1784102648553_0.10224696073199246","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"selparsecss-selector","version":"2.1.0","keywords":["css","selector","parser","postcss","AST"],"author":{"name":"Ai Pyramid"},"license":"MIT","_id":"selparsecss-selector@2.1.0","maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"contributors":[{"url":"http://pyramid.info","name":"Ai Pyramid","email":"pyramid.info@gmail.com"}],"dist":{"shasum":"b9a4bfa3eb8bc617d0bf529d5625b7e842b66e20","tarball":"https://registry.npmjs.org/selparsecss-selector/-/selparsecss-selector-2.1.0.tgz","fileCount":45,"integrity":"sha512-mE0SxIR3U88M7T3n1XExoYwn/cPqz8k1TQXdBFsUhdyWBsHUvEhC57o0JUFR/dAEJf7ib21KVPKsxq1gE6cAIQ==","signatures":[{"sig":"MEUCIBRzOFF3VrPj/5UNDywLl6XimP7B1/BuFDBj0EIn4dQBAiEAymKu+1v200+8wphDOY7ZpUYcDKjuayMzjqaP9T2mvlM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236168},"main":"dist/index.js","types":"selparsecss-selector.d.ts","engines":{"node":">=4"},"gitHead":"e4d637e40d233a3e9b1a675838ab54c4bcaca114","scripts":{"lint":"oxlint","test":"npm run lint && npm run typecheck && npm run coverage","build":"npm run clean && tsc && node scripts/copy-fragment.js","clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","tests":"node --test src/__tests__/*.mjs","format":"oxfmt src","prepare":"npm run build","release":"npx npmpub","coverage":"node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs","lint:fix":"oxlint --fix","pretests":"npm run build","typecheck":"tsc --noEmit --strict selparsecss-selector.d.ts selparsecss-selector.test.ts","precoverage":"npm run build","format:check":"oxfmt --check src"},"_npmUser":{"name":"aipyramid","email":"pyramid.info@proton.me"},"_npmVersion":"10.9.4","description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","directories":{},"_nodeVersion":"22.22.1","dependencies":{"cssesc":"^3.0.0","bytenode":"^1.5.7","util-deprecate":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"oxfmt":"^0.54.0","oxlint":"^1.69.0","postcss":"^8.4.31","typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/selparsecss-selector_2.1.0_1784102907763_0.8862395355042212","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"selparsecss-selector","description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","version":"2.2.0","devDependencies":{"oxfmt":"^0.54.0","oxlint":"^1.69.0","postcss":"^8.4.31","typescript":"^5.4.0"},"main":"dist/index.js","types":"selparsecss-selector.d.ts","scripts":{"clean":"node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"","build":"npm run clean && tsc","typecheck":"tsc --noEmit --strict selparsecss-selector.d.ts selparsecss-selector.test.ts","lint":"oxlint","lint:fix":"oxlint --fix","format":"oxfmt src","format:check":"oxfmt --check src","pretests":"npm run build","tests":"node --test src/__tests__/*.mjs","precoverage":"npm run build","coverage":"node --enable-source-maps --test --experimental-test-coverage --test-coverage-exclude=\"**/__tests__/**\" --test-coverage-lines=94 --test-coverage-branches=94 --test-coverage-functions=96 --test-reporter=spec src/__tests__/*.mjs","test":"npm run lint && npm run typecheck && npm run coverage","prepare":"npm run build","release":"npx npmpub"},"dependencies":{"cssesc":"^3.0.0","util-deprecate":"^1.0.2"},"keywords":["css","selector","parser","postcss","AST"],"author":{"name":"Ai Pyramid"},"license":"MIT","engines":{"node":">=4"},"contributors":[{"name":"Ai Pyramid","email":"pyramid.info@gmail.com","url":"http://pyramid.info"}],"_id":"selparsecss-selector@2.2.0","gitHead":"e4d637e40d233a3e9b1a675838ab54c4bcaca114","_nodeVersion":"22.22.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-JpSQq2esCI8q+hP09TQwYkvTQvtQgW+3hVMDqPULvvuMFmovlOiPXCYTT7gkDDc6EvRHGUBWwrDctGf5gCme2A==","shasum":"1c9e5bfe0ef0075182c13fa4511e87ef532318b6","tarball":"https://registry.npmjs.org/selparsecss-selector/-/selparsecss-selector-2.2.0.tgz","fileCount":40,"unpackedSize":193251,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCq/gBMmQt38QoS09oHT4KHM8xFupF24E6Ho9JW0JwhwgIhANsxWOJxFCMJLNBRlWoap6G1XZbXt5r2BnZo+q3xp/Rp"}]},"_npmUser":{"name":"aipyramid","email":"pyramid.info@proton.me"},"directories":{},"maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/selparsecss-selector_2.2.0_1784573222628_0.2456625189180084"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-15T07:19:00.757Z","modified":"2026-07-20T18:47:02.933Z","1.0.0":"2026-07-15T07:19:00.952Z","1.1.0":"2026-07-15T07:30:30.508Z","2.0.0":"2026-07-15T08:04:08.701Z","2.1.0":"2026-07-15T08:08:27.956Z","2.2.0":"2026-07-20T18:47:02.790Z"},"author":{"name":"Ai Pyramid"},"license":"MIT","keywords":["css","selector","parser","postcss","AST"],"description":"A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.","contributors":[{"name":"Ai Pyramid","email":"pyramid.info@gmail.com","url":"http://pyramid.info"}],"maintainers":[{"name":"aipyramid","email":"pyramid.info@proton.me"}],"readme":"# selparsecss-selector\n\n[![npm package version](https://img.shields.io/npm/v/selparsecss-selector) ![npm downloads](https://img.shields.io/npm/dm/selparsecss-selector)](https://www.npmjs.com/package/selparsecss-selector)\n\n> A lightweight CSS selector parser providing built-in methods to parse, transform, and work with selector strings.\n\n## Install\n\nWith [npm](https://npmjs.com/package/selparsecss-selector) do:\n\n```\nnpm install selparsecss-selector\n```\n\n## Quick Start\n\n```js\nconst selparser = require('selparsecss-selector');\nconst transform = selectors => {\n    selectors.walk(selector => {\n        // do something with the selector\n        console.log(String(selector))\n    });\n};\n\nconst transformed = selparser(transform).processSync('h1, h2, h3','h4');\n```\n\nTo normalize selector whitespace:\n\n```js\nconst selparser = require('selparsecss-selector');\nconst normalized = selparser().processSync('h1, h2, h3','h4', {lossless: false});\n// -> h1,h2,h3,h4\n```\n\nAsync support is provided through `parser.process` and will resolve a Promise\nwith the resulting selector string.\n\n## API\n\nPlease see [API.md](API.md).\n\n## Notes\n\n### Selector nesting depth (CVE-2026-9358)\n\nThe parser walks the selector AST recursively, both when parsing and when\nserializing it back to a string (`.toString()`). In versions up to and\nincluding `2.1.0`, a selector with extreme nesting — for example thousands of\nnested `:not(...)` — could recurse deeply enough to overflow the call stack and\nthrow `RangeError: Maximum call stack size exceeded`, a potential\ndenial-of-service when processing untrusted CSS.\n\nThis is now bounded by a maximum nesting depth (default: `256`). Beyond that\ndepth, parsing and serialization throw a regular, catchable `Error` at a\npredictable point instead of relying on the runtime hitting its stack limit.\nThe default is far above any realistic selector, so it does not affect normal\nuse.\n\n**Practical impact is low.** The only attacker-controlled input is the selector\nstring itself, which is now capped by the default limit. The limit is\nadjustable through the `maxNestingDepth` option, but that option is trusted\nconfiguration provided by the integrating code — it is never derived from the\nparsed CSS, so a malicious selector cannot change it:\n\n```js\n// Tighten the limit when parsing untrusted input:\nselparser().processSync(untrustedSelector, {maxNestingDepth: 128});\n```\n\nRaising `maxNestingDepth` to a very large value is an explicit, informed choice\nand can reintroduce the stack-overflow risk in environments with a small call\nstack (e.g. browser workers). The default is recommended unless you have a\nspecific need.\n\n\n## License\n\nMIT\n","readmeFilename":"README.md"}