pax_global_header00006660000000000000000000000064147144607010014516gustar00rootroot0000000000000052 comment=aed8b899884db4bc89f60782771eecd8c7861b32 postcss-8.4.49/000077500000000000000000000000001471446070100133225ustar00rootroot00000000000000postcss-8.4.49/.editorconfig000066400000000000000000000002231471446070100157740ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true postcss-8.4.49/.github/000077500000000000000000000000001471446070100146625ustar00rootroot00000000000000postcss-8.4.49/.github/CONTRIBUTING.md000066400000000000000000000042421471446070100171150ustar00rootroot00000000000000# Contributing Guide to PostCSS If you want to contribute to PostCSS, there are a few things that you should be familiar with. ## Adding Your Plugin to the List If you created or found a plugin and want to add it to the PostCSS plugins list follow these simple steps: PR should not change plugins defined in README — it only contains favorite plugins moderated by the PostCSS author. Plugins submitted by the community are located in [`docs/plugins`]. * **Keep plugins ordered** Be sure that a plugin is not already present and find a suitable position for it in alphabetical order. However plugins with `postcss-` prefix should come first. * **Check spelling** Before submitting a PR make sure the spelling check is passing. To run the check use `npm test`. If it fails with an unknown word error, add it as a word to `.yaspellerrc` dictionary. * **Check PostCSS plugin guidelines** The suggested plugin should match plugin [guidelines]. - **Provide link to suggested plugin** Make sure your pull request description contains a link to the plugin you want to add. [`docs/plugins`]: https://github.com/postcss/postcss/blob/main/docs/plugins.md [guidelines]: https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md ## TypeScript Declaration Improvements If you found a bug or want to add certain improvements to types declaration file: * **Check current TypeScript styling** Be sure that your changes match TypeScript styling rules defined in typings file. * We use classes for existing JS classes like `Stringifier`. * Namespaces used for separating functions related to the same subject. * Interfaces used for defining custom types. Make sure you read through declaration file writing [best practices] by the TypeScript team. [best practices]: https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html ## Core Development If you want to add new features or fix existing issues - **Become familiar with PostCSS architecture** For a gentle intro to PostCSS architecture look through our [guide]. [guide]: https://github.com/postcss/postcss/blob/main/docs/architecture.md postcss-8.4.49/.github/FUNDING.yml000066400000000000000000000000721471446070100164760ustar00rootroot00000000000000open_collective: postcss tidelift: npm/postcss github: ai postcss-8.4.49/.github/workflows/000077500000000000000000000000001471446070100167175ustar00rootroot00000000000000postcss-8.4.49/.github/workflows/release.yml000066400000000000000000000025511471446070100210650ustar00rootroot00000000000000name: Release on: push: tags: - '*' permissions: contents: write jobs: release: name: Release On Tag if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Extract the changelog id: changelog run: | TAG_NAME=${GITHUB_REF/refs\/tags\//} READ_SECTION=false CHANGELOG="" while IFS= read -r line; do if [[ "$line" =~ ^#+\ +(.*) ]]; then if [[ "${BASH_REMATCH[1]}" == "$TAG_NAME" ]]; then READ_SECTION=true elif [[ "$READ_SECTION" == true ]]; then break fi elif [[ "$READ_SECTION" == true ]]; then CHANGELOG+="$line"$'\n' fi done < "CHANGELOG.md" CHANGELOG=$(echo "$CHANGELOG" | awk '/./ {$1=$1;print}') echo "changelog_content<> $GITHUB_OUTPUT echo "$CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - name: Create the release if: steps.changelog.outputs.changelog_content != '' uses: softprops/action-gh-release@v2 with: name: ${{ github.ref_name }} body: '${{ steps.changelog.outputs.changelog_content }}' draft: false prerelease: false postcss-8.4.49/.github/workflows/test.yml000066400000000000000000000050341471446070100204230ustar00rootroot00000000000000name: Test on: push: branches: - main pull_request: permissions: contents: read jobs: full: name: Node.js Latest Full runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Install Node.js uses: actions/setup-node@v4 with: node-version: 23 cache: pnpm - name: Install dependencies run: pnpm install --ignore-scripts - name: Run tests run: pnpm test short: runs-on: ubuntu-latest strategy: matrix: node-version: - 22 - 20 - 18 name: Node.js ${{ matrix.node-version }} Quick steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Install Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: pnpm - name: Install dependencies run: pnpm install --ignore-scripts - name: Run unit tests run: pnpm run unit old: runs-on: ubuntu-latest strategy: matrix: node-version: - 16 - 14 - 12 - 10 name: Node.js ${{ matrix.node-version }} Quick steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 3 env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true - name: Install Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - name: Install dependencies run: pnpm install --ignore-scripts - name: Downgrade TypeScript run: pnpm install typescript@4 - name: Run unit tests run: pnpm run old windows: runs-on: windows-latest name: Windows Quick steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 with: version: 9 - name: Install Node.js LTS uses: actions/setup-node@v4 with: node-version: 22 cache: pnpm - name: Install dependencies run: pnpm install --ignore-scripts - name: Run unit tests run: pnpm run unit postcss-8.4.49/.gitignore000066400000000000000000000000771471446070100153160ustar00rootroot00000000000000node_modules/ coverage/ docs/api/index.html docs/api/assets/ postcss-8.4.49/.npmignore000066400000000000000000000000671471446070100153240ustar00rootroot00000000000000coverage/ test/ docs/ tsconfig.json eslint.config.mjs postcss-8.4.49/CHANGELOG.md000066400000000000000000000741421471446070100151430ustar00rootroot00000000000000# Change Log This project adheres to [Semantic Versioning](https://semver.org/). ## 8.4.49 * Fixed custom syntax without `source.offset` (by @romainmenke). ## 8.4.48 * Fixed position calculation in error/warnings methods (by @romainmenke). ## 8.4.47 * Removed debug code. ## 8.4.46 * Fixed `Cannot read properties of undefined (reading 'before')`. ## 8.4.45 * Removed unnecessary fix which could lead to infinite loop. ## 8.4.44 * Another way to fix `markClean is not a function` error. ## 8.4.43 * Fixed `markClean is not a function` error. ## 8.4.42 * Fixed CSS syntax error on long minified files (by @varpstar). ## 8.4.41 * Fixed types (by @nex3 and @querkmachine). * Cleaned up RegExps (by @bluwy). ## 8.4.40 * Moved to getter/setter in nodes types to help Sass team (by @nex3). ## 8.4.39 * Fixed `CssSyntaxError` types (by @romainmenke). ## 8.4.38 * Fixed `endIndex: 0` in errors and warnings (by @romainmenke). ## 8.4.37 * Fixed `original.column are not numbers` error in another case. ## 8.4.36 * Fixed `original.column are not numbers` error on broken previous source map. ## 8.4.35 * Avoid `!` in `node.parent.nodes` type. * Allow to pass `undefined` to node adding method to simplify types. ## 8.4.34 * Fixed `AtRule#nodes` type (by Tim Weißenfels). * Cleaned up code (by Dmitry Kirillov). ## 8.4.33 * Fixed `NoWorkResult` behavior difference with normal mode (by Romain Menke). * Fixed `NoWorkResult` usage conditions (by @ahmdammarr). ## 8.4.32 * Fixed `postcss().process()` types (by Andrew Ferreira). ## 8.4.31 * Fixed `\r` parsing to fix CVE-2023-44270. ## 8.4.30 * Improved source map performance (by Romain Menke). ## 8.4.29 * Fixed `Node#source.offset` (by Ido Rosenthal). * Fixed docs (by Christian Oliff). ## 8.4.28 * Fixed `Root.source.end` for better source map (by Romain Menke). * Fixed `Result.root` types when `process()` has no parser. ## 8.4.27 * Fixed `Container` clone methods types. ## 8.4.26 * Fixed clone methods types. ## 8.4.25 * Improve stringify performance (by Romain Menke). * Fixed docs (by @vikaskaliramna07). ## 8.4.24 * Fixed `Plugin` types. ## 8.4.23 * Fixed warnings in TypeDoc. ## 8.4.22 * Fixed TypeScript support with `node16` (by Remco Haszing). ## 8.4.21 * Fixed `Input#error` types (by Aleks Hudochenkov). ## 8.4.20 * Fixed source map generation for childless at-rules like `@layer`. ## 8.4.19 * Fixed whitespace preserving after AST transformations (by Romain Menke). ## 8.4.18 * Fixed an error on `absolute: true` with empty `sourceContent` (by Rene Haas). ## 8.4.17 * Fixed `Node.before()` unexpected behavior (by Romain Menke). * Added TOC to docs (by Mikhail Dedov). ## 8.4.16 * Fixed `Root` AST migration. ## 8.4.15 * Fixed AST normalization after using custom parser with old PostCSS AST. ## 8.4.14 * Print “old plugin API” warning only if plugin was used (by @zardoy). ## 8.4.13 * Fixed `append()` error after using `.parent` (by Jordan Pittman). ## 8.4.12 * Fixed `package.funding` to have same value between all PostCSS packages. ## 8.4.11 * Fixed `Declaration#raws.value` type. ## 8.4.10 * Fixed `package.funding` URL format. ## 8.4.9 * Fixed `package.funding` (by Álvaro Mondéjar). ## 8.4.8 * Fixed end position in empty Custom Properties. ## 8.4.7 * Fixed `Node#warn()` type (by Masafumi Koba). * Fixed comment removal in values after `,`. ## 8.4.6 * Prevented comment removing when it change meaning of CSS. * Fixed parsing space in last semicolon-less CSS Custom Properties. * Fixed comment cleaning in CSS Custom Properties with space. * Fixed throwing an error on `.root` access for plugin-less case. ## 8.4.5 * Fixed `raws` types to make object extendable (by James Garbutt). * Moved from Yarn 1 to pnpm. ## 8.4.4 * Fixed absolute path in source map on zero plugins mode. ## 8.4.3 * Fixed `this.css.replace is not a function` error. ## 8.4.2 * Fixed previous source map support in zero plugins mode. ## 8.4.1 * Fixed `Stringifier` types (by James Garbutt). ## 8.4 “President Camio” * Added ranges for errors and warnings (by Adaline Valentina Simonian). * Added `Stringifier` types (by James Garbutt). * Added `Processor` types. * Removed `PostCSS does nothing` warning by lazy parser (Bogdan Dolin). * Fixed `Node#walkRules()` types (by Aleks Hudochenkov). * Fixed types `Root` and `Document` in result values (by James Garbutt). * Reduced npm install size by 0.5 MB. * Moved tests from Jest to `uvu` (by Andrey Kim). * Fixed docs (by Paul Shryock). ## 8.3.11 * Remove debugging code. ## 8.3.10 * Fixed `Maximum call stack` issue of some source maps (by Yeting Li). ## 8.3.9 * Replaced `nanocolors` to `picocolors`. * Reduced package size. ## 8.3.8 * Update `nanocolors`. ## 8.3.7 * Replaced `colorette` to `nanocolors`. * Added bug field to `package.json` (by Christian Oliff). * Improved docs (by Andrew Bruce and Paul Shryock). ## 8.3.6 * Fixed column in `missed semicolon` error (by @Gusted). ## 8.3.5 * Fixed broken AST detection. ## 8.3.4 * Fixed broken AST detection. ## 8.3.3 * Fixed broken AST on `postcss` dependency duplication in custom parsers. ## 8.3.2 * Update changelog. ## 8.3.1 * Fixed false positives `PostCSS does nothing` warning on `syntax` option. ## 8.3 “Duke Murmur” * Added `Node#assign()` shortcut (by Jonathan Neal). * Added experimental `Document` node to AST (by Aleks Hudochenkov). * Moved to faster fork of `source-map` (by Valentin Semirulnik). ## 8.2.15 * Fixed `list` type definitions (by @n19htz). ## 8.2.14 * Removed `source-map` from client-side bundle (by Barak Igal). ## 8.2.13 * Fixed ReDoS vulnerabilities in source map parsing (by Yeting Li). ## 8.2.12 * Fixed `package.json` exports. ## 8.2.11 * Fixed `DEP0148` warning in Node.js 16. * Fixed docs (by @semiromid). ## 8.2.10 * Fixed ReDoS vulnerabilities in source map parsing. * Fixed webpack 5 support (by Barak Igal). * Fixed docs (by Roeland Moors). ## 8.2.9 * Exported `NodeErrorOptions` type (by Rouven Weßling). ## 8.2.8 * Fixed browser builds in webpack 4 (by Matt Jones). ## 8.2.7 * Fixed browser builds in webpack 5 (by Matt Jones). ## 8.2.6 * Fixed `Maximum call stack size exceeded` in `Node#toJSON`. * Fixed docs (by inokawa). ## 8.2.5 * Fixed escaped characters handling in `list.split` (by Natalie Weizenbaum). ## 8.2.4 * Added plugin name to `postcss.plugin()` warning (by Tom Williams). * Fixed docs (by Bill Columbia). ## 8.2.3 * Fixed `JSON.stringify(Node[])` support (by Niklas Mischkulnig). ## 8.2.2 * Fixed CSS-in-JS support (by James Garbutt). * Fixed plugin types (by Ludovico Fischer). * Fixed `Result#warn()` types. ## 8.2.1 * Fixed `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig). ## 8.2 “Prince Orobas” * Added `Node#toJSON()` and `postcss.fromJSON()` (by Niklas Mischkulnig). ## 8.1.14 * Fixed parser performance regression. ## 8.1.13 * Fixed broken AST after moving nodes in visitor API. ## 8.1.12 * Fixed Autoprefixer regression. ## 8.1.11 * Added PostCSS update suggestion on unknown event in plugin. ## 8.1.10 * Fixed `LazyResult` type export (by Evan You). * Fixed `LazyResult` type compatibility with `Promise` (by Anton Kastritskiy). ## 8.1.9 * Reduced dependencies number (by Bogdan Chadkin). ## 8.1.8 * Fixed `LazyResult` type compatibility with `Promise` (by Ludovico Fischer). * Fixed HTTPS links in documentation. ## 8.1.7 * Fixed `import` support in TypeScript (by Remco Haszing). ## 8.1.6 * Reverted `package.exports` Node.js 15 fix. ## 8.1.5 * Fixed Node.js 15 warning (by 沈鸿飞). ## 8.1.4 * Fixed TypeScript definition (by Arthur Petrie). ## 8.1.3 * Added `package.types`. ## 8.1.2 * Fixed API docs (by Arthur Petrie). * Improved plugin guide (by Yunus Gaziev). * Prepared code base for Deno support (by Oscar Otero). ## 8.1.1 * Updated funding link. ## 8.1 “Duke Gemory” * Added `Once` and `OnceExit` events. * Fixed `Root` and `RootExit` events re-visiting. * Fixed node re-visiting on deep children changes. * Added docs for visitor API events. ## 8.0.9 * Replace prototype in PostCSS 7 nodes instead of recreating them. * Added missed `Transformer` to exported types (by Pierre-Marie Dartus). ## 8.0.8 * Fix `8.0.7` regression on PostCSS 7 nodes converting (by Adam Wathan). ## 8.0.7 * Fixed compatibility issue with mixin AST with PostCSS 7 and 8 nodes. * Added migration guide translation to Chinese to the warning. ## 8.0.6 * Fixed child adding methods in `Container`. ## 8.0.5 * Update changelog. ## 8.0.4 * Fixed `Cannot read property 'line' of null` error. * Fixed source map support for declarations. ## 8.0.3 * Fixed client-side bundling support. ## 8.0.2 * Fixed plugin packs support. ## 8.0.1 * Updated `Processor#version`. ## 8.0 “President Ose” * Removed support for Node.js 6.x, 8.x, 11.x, and 13.x versions. * Removed `postcss.vendor` helpers. * Deprecated `postcss.plugin()` API. * Treats `sourceMap.sources` as URL instead of file path. * Plugins and runners must have `postcss` in `peerDependencies`. * Prohibited to extend PostCSS AST classes. * Moved from JSDoc to TypeDoc. * Moved unknown source from counter to random IDs. * Added visitor API for plugins (by Alexey Bondarenko). * Added ES modules support. * Added named exports for public classes `const { Rule } = require('postcss)`. * Added `position.url` to `Node#origin()` result. * Added `opts.maps.absolute = true` option. * Added `opts.maps.annotation = (file, root) => url` option support. * Added `Node#source.offset` (by Ayaz Zaynutdinov). * Added `Declaration#variable`. * Added JSON source map support. * Added index source map support. * Added `Declaration#value` auto-converting to string. * Fixed parsing `{}` in at-rule parameters. * Fixed parsing empty Custom Properties. `--foo: ;` will have ` ` value. * Fixed building PostCSS with Rollup (by MapGrid). * Fixed TypeScript types. * Fixed source map relative paths. * Fixed calling `replaceWith` with input replaced node (by Joseph Kaptur). * Improved “Writing a PostCSS Plugin” docs (by Alexey Bondarenko). * Removed Babel from the project’s release process. * Removed docs from npm package. * Replaced `chalk` to `colorette`. ## 7.0.38 * Update `Processor#version`. ## 7.0.37 * Backport `chalk` to `nanocolors` migration. ## 7.0.36 * Backport ReDoS vulnerabilities from PostCSS 8. ## 7.0.35 * Add migration guide link to PostCSS 8 error text. ## 7.0.34 * Fix compatibility with `postcss-scss` 2. ## 7.0.33 * Add error message for PostCSS 8 plugins. ## 7.0.32 * Fix error message (by @admosity). ## 7.0.31 * Use only the latest source map annotation (by Emmanouil Zoumpoulakis). ## 7.0.30 * Fix TypeScript definition (by Natalie Weizenbaum). ## 7.0.29 * Update `Processor#version`. ## 7.0.28 * Fix TypeScript definition (by Natalie Weizenbaum). ## 7.0.27 * Fix TypeScript definition (by Natalie Weizenbaum). ## 7.0.26 * Fix TypeScript definition (by Natalie Weizenbaum). ## 7.0.25 * Fix absolute path support for Windows (by Tom Raviv). ## 7.0.24 * Fix TypeScript definition (by Keith Cirkel). ## 7.0.23 * Update `Processor#version`. ## 7.0.22 * Add funding link for `npm fund`. ## 7.0.21 * Revert passing `nodes` property to node constructor. ## 7.0.20 * Allow to pass PostCSS’s nodes in `nodes` property to node constructor. ## 7.0.19 * Fix passing `nodes` property to node constructor. ## 7.0.18 * Fix TypeScript type definitions (by Jan Buschtöns). ## 7.0.17 * Fix TypeScript type definitions (by Bob Matcuk and Jan Buschtöns). ## 7.0.16 * Revert Custom Properties fix until PostCSS 8.0. ## 7.0.15 * Fix Custom Properties support (by Ivan Solovev). ## 7.0.14 * Fix tokenizer for `postcss-less` (by Matt Lyons). ## 7.0.13 * Fix parsing regression in 7.0.12 for comments between property and value. ## 7.0.12 * Fix parsing broken CSS with two words in declaration property. ## 7.0.11 * Fix source maps on declaration semicolon (by Niklas Mischkulnig). ## 7.0.10 * Fix source maps (by Niklas Mischkulnig). ## 7.0.9 * Increase stringifing performance for non-raws AST. ## 7.0.8 * Fix TypeScript definitions (by Ankur Oberoi). * Use `support-colors` 6.0. ## 7.0.7 * Extend `Error` in `CssSyntaxError`. ## 7.0.6 * Fix parsing files with BOM (by Veniamin Krol). ## 7.0.5 * Reduce npm package size (by Gilad Peleg). ## 7.0.4 * Fix safe parser regression. ## 7.0.3 * Fix tokenizer extendability (by Andrew Powell). * Reduce npm package size. ## 7.0.2 * Fix warning text (by Rui Pedro M Lima). ## 7.0.1 * Fix JSDoc (by Steven Lambert). ## 7.0 “President Amy” * Remove Node.js 9 and Node.js 4 support. * Remove IE and “dead” browsers support for client-side Babel transpiling. * Add CSS position on error happened inside `walk()` (by Nikhil Gaba). * Add `LazyResult#finally` (by Igor Kamyshev). * Add warning on calling PostCSS without plugins and syntax options. * Reduce client-side size. ## 6.0.23 * Fix parsing nested at-rules without semicolon, params, and spaces. * Fix docs (by Kevin Schiffer and Pat Cavit). ## 6.0.22 * Fix `Node#prev` and `Node#next` on missed parent. ## 6.0.21 * Rename Chinese docs to fix `yarnpkg.com` issue. ## 6.0.20 * Better error message on `null` as input CSS. ## 6.0.19 * Fix TypeScript definitions for source maps (by Oleh Kuchuk). * Fix `source` field in TypeScript definitions (by Sylvain Pollet-Villard). ## 6.0.18 * Use primitive object in TypeScript definitions (by Sylvain Pollet-Villard). ## 6.0.17 * Fix parsing comment in selector between word tokens (by Oleh Kuchuk). ## 6.0.16 * Fix warning text (by Michael Keller). ## 6.0.15 * Add warning about missed `from` option on `process().then()` call. * Add IE 10 support. ## 6.0.14 * Fix TypeScript definitions (by Jed Mao). ## 6.0.13 * Fix TypeScript definitions for case of multiple PostCSS versions in `node_modules` (by Chris Eppstein). * Use `source-map` 0.6. ## 6.0.12 * Don’t copy `*` hack to declaration indent. ## 6.0.11 * Add upper case `!IMPORTANT` support. ## 6.0.10 * Reduce PostCSS size in webpack bundle. ## 6.0.9 * Improve error message for plugin with old PostCSS (by Igor Adamenko). ## 6.0.8 * Fix Node.js 4.2.2 support. ## 6.0.7 * Fix base64 decoding for old Node.js and browser. ## 6.0.6 * Fix `end` position in at-rule without semicolon (by Oleh Kuchuk). ## 6.0.5 * Move Babel config from `package.json` for `node_modules` compiling cases. ## 6.0.4 * Fix parsing `;;` after rules. * Use Chalk 2.0. ## 6.0.3 * Fix escape sequences parsing (by Oleh Kuchuk). * Added ability to force disable colors with an environment variable. * Improved color detection of some terminal apps. ## 6.0.2 * Keep `raws.before` on moving `Root` children to new `Root`. ## 6.0.1 * Fix parser extensibility to use it in Safe Parser. ## 6.0 “Marquis Orias” * Remove node.js 0.12 support. * Remove deprecated method from PostCSS 4. * Insert methods remove child from previous parent, instead of closing. * Insert methods and cloning doesn’t clean `raws` anymore. * Methods `moveTo`, `moveAfter`, `moveBefore` were deprecated. * Options was changed in `Plugin#process(css, processOptions, pluginOptions)`. * Add stream parser to reduce memory usage (by Oleh Kuchuk). * Add `before()`/`after()` shortcuts for `node.parent.insertBefore(node, x)`. * Add `Rule#raws.ownSemicolon` for semicolon after templates for `@apply`. * Use `babel-preset-env` to compile npm package. * Remove `js-base64` from dependencies (by Roman Dvornov). * Fix error message on single `:` in CSS. * Move tests to Jest. * Clean up test (by Gabriel Kalani). ## 5.2.18 * Fix TypeScript definitions for case of multiple PostCSS versions in `node_modules` (by Chris Eppstein). ## 5.2.17 * Add `postcss-sass` suggestion to syntax error on `.sass` input. ## 5.2.16 * Better error on wrong argument in node constructor. ## 5.2.15 * Fix TypeScript definitions (by bumbleblym). ## 5.2.14 * Fix browser bundle building in webpack (by janschoenherr). ## 5.2.13 * Do not add comment to important raws. * Fix JSDoc (by Dmitry Semigradsky). ## 5.2.12 * Fix typo in deprecation message (by Garet McKinley). ## 5.2.11 * Fix TypeScript definitions (by Jed Mao). ## 5.2.10 * Fix TypeScript definitions (by Jed Mao). ## 5.2.9 * Update TypeScript definitions (by Jed Mao). ## 5.2.8 * Fix error message (by Ben Briggs). ## 5.2.7 * Better error message on syntax object in plugins list. ## 5.2.6 * Fix `postcss.vendor` for values with spaces (by 刘祺). ## 5.2.5 * Better error message on unclosed string (by Ben Briggs). ## 5.2.4 * Improve terminal CSS syntax highlight (by Simon Lydell). ## 5.2.3 * Better color highlight in syntax error code frame. * Fix color highlight support in old systems. ## 5.2.2 * Update `Processor#version`. ## 5.2.1 * Fix source map path for CSS without `from` option (by Michele Locati). ## 5.2 “Duke Vapula” * Add syntax highlight to code frame in syntax error (by Andrey Popp). * Use Babel code frame style and size in syntax error. * Add `[` and `]` tokens to parse `[attr=;] {}` correctly. * Add `ignoreErrors` options to tokenizer (by Andrey Popp). * Fix error position on tab indent (by Simon Lydell). ## 5.1.2 * Suggests SCSS/Less parsers on parse errors depends on file extension. ## 5.1.1 * Fix TypeScript definitions (by Efremov Alexey). ## 5.1 “King and President Zagan” * Add URI in source map support (by Mark Finger). * Add `map.from` option (by Mark Finger). * Add `` mappings for nodes without source (by Bogdan Chadkin). * Add function value support to `map.prev` option (by Chris Montoro). * Add declaration value type check in shortcut creating (by 刘祺). * `Result#warn` now returns new created warning. * Don’t call plugin creator in `postcss.plugin` call. * Add source maps to PostCSS ES5 build. * Add JSDoc to PostCSS classes. * Clean npm package from unnecessary docs. ## 5.0.21 * Fix support with input source mao with `utf8` encoding name. ## 5.0.20 * Fix between raw value parsing (by David Clark). * Update TypeScript definitions (by Jed Mao). * Clean fake node.source after `append(string)`. ## 5.0.19 * Fix indent-based syntaxes support. ## 5.0.18 * Parse new lines according W3C CSS syntax specification. ## 5.0.17 * Fix options argument in `Node#warn` (by Ben Briggs). * Fix TypeScript definitions (by Jed Mao). ## 5.0.16 * Fix CSS syntax error position on unclosed quotes. ## 5.0.15 * Fix `Node#clone()` on `null` value somewhere in node. ## 5.0.14 * Allow to use PostCSS in webpack bundle without JSON loader. ## 5.0.13 * Fix `index` and `word` options in `Warning#toString` (by Bogdan Chadkin). * Fix input source content loading in errors. * Fix map options on using `LazyResult` as input CSS. * 100% test coverage. * Use Babel 6. ## 5.0.12 * Allow passing a previous map with no mappings (by Andreas Lind). ## 5.0.11 * Increase plugins performance by 1.5 times. ## 5.0.10 * Fix warning from nodes without source. ## 5.0.9 * Fix source map type detection (by @asan). ## 5.0.8 * Fixed a missed step in `5.0.7` that caused the module to be published as ES6 code. ## 5.0.7 * PostCSS now requires that node 0.12 is installed via the engines property in package.json (by Howard Zuo). ## 5.0.6 * Fix parsing nested at-rule without semicolon (by Matt Drake). * Trim `Declaration#value` (by Bogdan Chadkin). ## 5.0.5 * Fix multi-tokens property parsing (by Matt Drake). ## 5.0.4 * Fix start position in `Root#source`. * Fix source map annotation, when CSS uses `\r\n` (by Mohammad Younes). ## 5.0.3 * Fix `url()` parsing. * Fix using `selectors` in `Rule` constructor. * Add start source to `Root` node. ## 5.0.2 * Fix `remove(index)` to be compatible with 4.x plugin. ## 5.0.1 * Fix PostCSS 4.x plugins compatibility. * Fix type definition loading (by Jed Mao). ## 5.0 “President Valac” * Remove `safe` option. Move Safe Parser to separate project. * `Node#toString` does not include `before` for root nodes. * Remove plugin returning `Root` API. * Remove Promise polyfill for node.js 0.10. * Deprecate `eachInside`, `eachDecl`, `eachRule`, `eachAtRule` and `eachComment` in favor of `walk`, `walkDecls`, `walkRules`, `walkAtRules` and `walkComments` (by Jed Mao). * Deprecate `Container#remove` and `Node#removeSelf` in favor of `Container#removeChild` and `Node#remove` (by Ben Briggs). * Deprecate `Node#replace` in favor of `replaceWith` (by Ben Briggs). * Deprecate raw properties in favor of `Node#raws` object. * Deprecate `Node#style` in favor of `raw`. * Deprecate `CssSyntaxError#generated` in favor of `input`. * Deprecate `Node#cleanStyles` in favor of `cleanRaws`. * Deprecate `Root#prevMap` in favor of `Root.source.input.map`. * Add `syntax`, `parser` and `stringifier` options for Custom Syntaxes. * Add stringifier option to `Node#toString`. * Add `Result#content` alias for non-CSS syntaxes. * Add `plugin.process(css)` shortcut to every plugin function (by Ben Briggs). * Add multiple nodes support to insert methods (by Jonathan Neal). * Add `Node#warn` shortcut (by Ben Briggs). * Add `word` and `index` options to errors and warnings (by David Clark). * Add `line`, `column` properties to `Warning`. * Use `supports-color` library to detect color support in error output. * Add type definitions for TypeScript plugin developers (by Jed Mao). * `Rule#selectors` setter detects separators. * Add `postcss.stringify` method. * Throw descriptive errors for incorrectly formatted plugins. * Add docs to npm release. * Fix `url()` parsing. * Fix Windows support (by Jed Mao). ## 4.1.16 * Fix errors without stack trace. ## 4.1.15 * Allow asynchronous plugins to change processor plugins list (by Ben Briggs). ## 4.1.14 * Fix for plugins packs defined by `postcss.plugin`. ## 4.1.13 * Fix input inlined source maps with UTF-8 encoding. ## 4.1.12 * Update Promise polyfill. ## 4.1.11 * Fix error message on wrong plugin format. ## 4.1.10 * Fix Promise behavior on sync plugin errors. * Automatically fill `plugin` field in `CssSyntaxError`. * Fix warning message (by Ben Briggs). ## 4.1.9 * Speed up `node.clone()`. ## 4.1.8 * Accepts `Processor` instance in `postcss()` constructor too. ## 4.1.7 * Speed up `postcss.list` (by Bogdan Chadkin). ## 4.1.6 * Fix Promise behavior on parsing error. ## 4.1.5 * Parse at-words in declaration values. ## 4.1.4 * Fix Promise polyfill dependency (by Anton Yakushev and Matija Marohnić). ## 4.1.3 * Add Promise polyfill for node.js 0.10 and IE. ## 4.1.2 * List helpers can be accessed independently `var space = postcss.list.space`. ## 4.1.1 * Show deprecated message only once. ## 4.1 “Marquis Andras” * Asynchronous plugin support. * Add warnings from plugins and `Result#messages`. * Add `postcss.plugin()` to create plugins with a standard API. * Insert nodes by CSS string. * Show version warning message on error from an outdated plugin. * Send `Result` instance to plugins as the second argument. * Add `CssSyntaxError#plugin`. * Add `CssSyntaxError#showSourceCode()`. * Add `postcss.list` and `postcss.vendor` aliases. * Add `Processor#version`. * Parse wrong closing bracket. * Parse `!important` statement with spaces and comments inside (by Ben Briggs). * Throw an error on declaration without `prop` or `value` (by Philip Peterson). * Fix source map mappings position. * Add indexed source map support. * Always set `error.generated`. * Clean all source map annotation comments. ## 4.0.6 * Remove `babel` from released package dependencies (by Andres Suarez). ## 4.0.5 * Fix error message on double colon in declaration. ## 4.0.4 * Fix indent detection in some rare cases. ## 4.0.3 * Faster API with 6to5 Loose mode. * Fix indexed source maps support. ## 4.0.2 * Do not copy IE hacks to code style. ## 4.0.1 * Add `source.input` to `Root` too. ## 4.0 “Duke Flauros” * Rename `Container#childs` to `nodes`. * Rename `PostCSS#processors` to `plugins`. * Add `Node#replaceValues()` method. * Add `Node#moveTo()`, `moveBefore()` and `moveAfter()` methods. * Add `Node#cloneBefore()` and `cloneAfter()` shortcuts. * Add `Node#next()`, `prev()` and `root()` shortcuts. * Add `Node#replaceWith()` method. * Add `Node#error()` method. * Add `Container#removeAll()` method. * Add filter argument to `eachDecl()` and `eachAtRule()`. * Add `Node#source.input` and move `source.file` or `source.id` to `input`. * Change code indent, when node was moved. * Better fix code style on `Rule`, `AtRule` and `Comment` nodes changes. * Allow to create rules and at-rules by hash shortcut in append methods. * Add class name to CSS syntax error output. ## 3.0.7 * Fix IE filter parsing with multiple commands. * Safer way to consume PostCSS object as plugin (by Maxime Thirouin). ## 3.0.6 * Fix missing semicolon when comment comes after last declaration. * Fix Safe Mode declaration parsing on unclosed blocks. ## 3.0.5 * Fix parser to support difficult cases with backslash escape and brackets. * Add `CssSyntaxError#stack` (by Maxime Thirouin). ## 3.0.4 * Fix Safe Mode on unknown word before declaration. ## 3.0.3 * Increase tokenizer speed (by Roman Dvornov). ## 3.0.2 * Fix empty comment parsing. * Fix `Root#normalize` in some inserts. ## 3.0.1 * Fix Rhino JS runtime support. * Typo in deprecated warning (by Maxime Thirouin). ## 3.0 “Marquis Andrealphus” * New parser, which become the fastest ever CSS parser written in JavaScript. * Parser can now parse declarations and rules in one parent (like in `@page`) and nested declarations for plugins like `postcss-nested`. * Child nodes array is now in `childs` property, instead of `decls` and `rules`. * `map.inline` and `map.sourcesContent` options are now `true` by default. * Fix iterators (`each`, `insertAfter`) on children array changes. * Use previous source map to show origin source of CSS syntax error. * Use 6to5 ES6 compiler, instead of ES6 Transpiler. * Use code style for manually added rules from existing rules. * Use `from` option from previous source map `file` field. * Set `to` value to `from` if `to` option is missing. * Use better node source name when missing `from` option. * Show a syntax error when `;` is missed between declarations. * Allow to pass `PostCSS` instance or list of plugins to `use()` method. * Allow to pass `Result` instance to `process()` method. * Trim Unicode BOM on source maps parsing. * Parse at-rules without spaces like `@import"file"`. * Better previous `sourceMappingURL` annotation comment cleaning. * Do not remove previous `sourceMappingURL` comment on `map.annotation: false`. * Parse nameless at-rules in Safe Mode. * Fix source map generation for nodes without source. * Fix next child `before` if `Root` first child got removed. ## 2.2.6 * Fix map generation for nodes without source (by Josiah Savary). ## 2.2.5 * Fix source map with BOM marker support (by Mohammad Younes). * Fix source map paths (by Mohammad Younes). ## 2.2.4 * Fix `prepend()` on empty `Root`. ## 2.2.3 * Allow to use object shortcut in `use()` with functions like `autoprefixer`. ## 2.2.2 * Add shortcut to set processors in `use()` via object with `.postcss` property. ## 2.2.1 * Send `opts` from `Processor#process(css, opts)` to processors. ## 2.2 “Marquis Cimeies” * Use GNU style syntax error messages. * Add `Node#replace` method. * Add `CssSyntaxError#reason` property. ## 2.1.2 * Fix UTF-8 support in inline source map. * Fix source map `sourcesContent` if there is no `from` and `to` options. ## 2.1.1 * Allow to miss `to` and `from` options for inline source maps. * Add `Node#source.id` if file name is unknown. * Better detect splitter between rules in CSS concatenation tools. * Automatically clone node in insert methods. ## 2.1 “King Amdusias” * Change Traceur ES6 compiler to ES6 Transpiler. * Show broken CSS line in syntax error. ## 2.0 “King Belial” * Project was rewritten from CoffeeScript to ES6. * Add Safe Mode to works with live input or with hacks from legacy code. * More safer parser to pass all hacks from Browserhacks.com. * Use real properties instead of magic getter/setter for raw properties. ## 1.0 “Marquis Decarabia” * Save previous source map for each node to support CSS concatenation with multiple previous maps. * Add `map.sourcesContent` option to add origin content to `sourcesContent` inside map. * Allow to set different place of output map in annotation comment. * Allow to use arrays and `Root` in `Container#append` and same methods. * Add `Root#prevMap` with information about previous map. * Allow to use latest PostCSS from GitHub by npm. * `Result` now is lazy and it will generate output CSS only if you use `css` or `map` property. * Use separated `map.prev` option to set previous map. * Rename `inlineMap` option to `map.inline`. * Rename `mapAnnotation` option to `map.annotation`. * `Result#map` now return `SourceMapGenerator` object, instead of string. * Run previous map autodetect only if input CSS contains annotation comment. * Add `map: 'inline'` shortcut for `map: { inline: true }` option. * `Node#source.file` now will contains absolute path. * Clean `Declaration#between` style on node clone. ## 0.3.5 * Allow to use `Root` or `Result` as first argument in `process()`. * Save parsed AST to `Result#root`. ## 0.3.4 * Better space symbol detect to read UTF-8 BOM correctly. ## 0.3.3 * Remove source map hacks by using new Mozilla’s `source-map` (by Simon Lydell). ## 0.3.2 * Add URI encoding support for inline source maps. ## 0.3.1 * Fix relative paths from previous source map. * Safer space split in `Rule#selectors` (by Simon Lydell). ## 0.3 “Prince Seere” * Add `Comment` node for comments between declarations or rules. * Add source map annotation comment to output CSS. * Allow to inline source map to annotation comment by data:uri. * Fix source maps on Windows. * Fix source maps for subdirectory (by Dmitry Nikitenko and Simon Lydell). * Autodetect previous source map. * Add `first` and `last` shortcuts to container nodes. * Parse `!important` to separated property in `Declaration`. * Allow to break iteration by returning `false`. * Copy code style to new nodes. * Add `eachInside` method to recursively iterate all nodes. * Add `selectors` shortcut to get selectors array. * Add `toResult` method to `Rule` to simplify work with several input files. * Clean declaration’s `value`, rule’s `selector` and at-rule’s `params` by storing spaces in `between` property. ## 0.2 “Duke Dantalion” * Add source map support. * Add shortcuts to create nodes. * Method `process()` now returns object with `css` and `map` keys. * Origin CSS file option was renamed from `file` to `from`. * Rename `Node#remove()` method to `removeSelf()` to fix name conflict. * Node source was moved to `source` property with origin file and node end position. * You can set own CSS generate function. ## 0.1 “Count Andromalius” * Initial release. postcss-8.4.49/LICENSE000066400000000000000000000021071471446070100143270ustar00rootroot00000000000000The MIT License (MIT) Copyright 2013 Andrey Sitnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. postcss-8.4.49/README.md000066400000000000000000000425171471446070100146120ustar00rootroot00000000000000# PostCSS Philosopher’s stone, logo of PostCSS PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more. PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba, and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins is one of the most popular CSS tools. ---   Made at Evil Martians, product consulting for developer tools. --- [Abstract Syntax Tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree [Evil Martians]: https://evilmartians.com/?utm_source=postcss [Autoprefixer]: https://github.com/postcss/autoprefixer [Stylelint]: https://stylelint.io/ [plugins]: https://github.com/postcss/postcss#plugins ## Sponsorship PostCSS needs your support. We are accepting donations [at Open Collective](https://opencollective.com/postcss/). Sponsored by Tailwind CSS       Sponsored by ThemeIsle ## Plugins PostCSS takes a CSS file and provides an API to analyze and modify its rules (by transforming them into an [Abstract Syntax Tree]). This API can then be used by [plugins] to do a lot of useful things, e.g., to find errors automatically, or to insert vendor prefixes. Currently, PostCSS has more than 200 plugins. You can find all of the plugins in the [plugins list]. Below is a list of our favorite plugins — the best demonstrations of what can be built on top of PostCSS. If you have any new ideas, [PostCSS plugin development] is really easy. [plugins list]: https://github.com/postcss/postcss/blob/main/docs/plugins.md ### Solve Global CSS Problem * [`postcss-use`] allows you to explicitly set PostCSS plugins within CSS and execute them only for the current file. * [`postcss-modules`] and [`react-css-modules`] automatically isolate selectors within components. * [`postcss-autoreset`] is an alternative to using a global reset that is better for isolatable components. * [`postcss-initial`] adds `all: initial` support, which resets all inherited styles. * [`cq-prolyfill`] adds container query support, allowing styles that respond to the width of the parent. ### Use Future CSS, Today * [`autoprefixer`] adds vendor prefixes, using data from Can I Use. * [`postcss-preset-env`] allows you to use future CSS features today. ### Better CSS Readability * [`postcss-nested`] unwraps nested rules the way Sass does. * [`postcss-sorting`] sorts the content of rules and at-rules. * [`postcss-utilities`] includes the most commonly used shortcuts and helpers. * [`short`] adds and extends numerous shorthand properties. ### Images and Fonts * [`postcss-url`] postcss plugin to rebase url(), inline or copy asset. * [`postcss-sprites`] generates image sprites. * [`font-magician`] generates all the `@font-face` rules needed in CSS. * [`postcss-inline-svg`] allows you to inline SVG and customize its styles. * [`postcss-write-svg`] allows you to write simple SVG directly in your CSS. * [`webp-in-css`] to use WebP image format in CSS background. * [`avif-in-css`] to use AVIF image format in CSS background. ### Linters * [`stylelint`] is a modular stylesheet linter. * [`stylefmt`] is a tool that automatically formats CSS according `stylelint` rules. * [`doiuse`] lints CSS for browser support, using data from Can I Use. * [`colorguard`] helps you maintain a consistent color palette. ### Other * [`cssnano`] is a modular CSS minifier. * [`lost`] is a feature-rich `calc()` grid system. * [`rtlcss`] mirrors styles for right-to-left locales. [PostCSS plugin development]: https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md [`postcss-inline-svg`]: https://github.com/TrySound/postcss-inline-svg [`postcss-preset-env`]: https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env [`react-css-modules`]: https://github.com/gajus/react-css-modules [`postcss-autoreset`]: https://github.com/maximkoretskiy/postcss-autoreset [`postcss-write-svg`]: https://github.com/csstools/postcss-write-svg [`postcss-utilities`]: https://github.com/ismamz/postcss-utilities [`postcss-initial`]: https://github.com/maximkoretskiy/postcss-initial [`postcss-sprites`]: https://github.com/2createStudio/postcss-sprites [`postcss-modules`]: https://github.com/outpunk/postcss-modules [`postcss-sorting`]: https://github.com/hudochenkov/postcss-sorting [`font-magician`]: https://github.com/csstools/postcss-font-magician [`autoprefixer`]: https://github.com/postcss/autoprefixer [`cq-prolyfill`]: https://github.com/ausi/cq-prolyfill [`postcss-url`]: https://github.com/postcss/postcss-url [`postcss-use`]: https://github.com/postcss/postcss-use [`css-modules`]: https://github.com/css-modules/css-modules [`webp-in-css`]: https://github.com/ai/webp-in-css [`avif-in-css`]: https://github.com/nucliweb/avif-in-css [`colorguard`]: https://github.com/SlexAxton/css-colorguard [`stylelint`]: https://github.com/stylelint/stylelint [`stylefmt`]: https://github.com/morishitter/stylefmt [`cssnano`]: https://cssnano.github.io/cssnano/ [`postcss-nested`]: https://github.com/postcss/postcss-nested [`doiuse`]: https://github.com/anandthakker/doiuse [`rtlcss`]: https://github.com/MohammadYounes/rtlcss [`short`]: https://github.com/csstools/postcss-short [`lost`]: https://github.com/peterramsing/lost ## Syntaxes PostCSS can transform styles in any syntax, not just CSS. If there is not yet support for your favorite syntax, you can write a parser and/or stringifier to extend PostCSS. * [`sugarss`] is a indent-based syntax like Sass or Stylus. * [`postcss-syntax`] switch syntax automatically by file extensions. * [`postcss-html`] parsing styles in `' * ) * document.type //=> 'document' * document.nodes.length //=> 2 * ``` */ declare class Document_ extends Container { nodes: Root[] parent: undefined type: 'document' constructor(defaults?: Document.DocumentProps) assign(overrides: Document.DocumentProps | object): this clone(overrides?: Partial): this cloneAfter(overrides?: Partial): this cloneBefore(overrides?: Partial): this /** * Returns a `Result` instance representing the document’s CSS roots. * * ```js * const root1 = postcss.parse(css1, { from: 'a.css' }) * const root2 = postcss.parse(css2, { from: 'b.css' }) * const document = postcss.document() * document.append(root1) * document.append(root2) * const result = document.toResult({ to: 'all.css', map: true }) * ``` * * @param opts Options. * @return Result with current document’s CSS. */ toResult(options?: ProcessOptions): Result } declare class Document extends Document_ {} export = Document postcss-8.4.49/lib/document.js000066400000000000000000000012161471446070100162440ustar00rootroot00000000000000'use strict' let Container = require('./container') let LazyResult, Processor class Document extends Container { constructor(defaults) { // type needs to be passed to super, otherwise child roots won't be normalized correctly super({ type: 'document', ...defaults }) if (!this.nodes) { this.nodes = [] } } toResult(opts = {}) { let lazy = new LazyResult(new Processor(), this, opts) return lazy.stringify() } } Document.registerLazyResult = dependant => { LazyResult = dependant } Document.registerProcessor = dependant => { Processor = dependant } module.exports = Document Document.default = Document postcss-8.4.49/lib/fromJSON.d.ts000066400000000000000000000002421471446070100163150ustar00rootroot00000000000000import { JSONHydrator } from './postcss.js' interface FromJSON extends JSONHydrator { default: FromJSON } declare const fromJSON: FromJSON export = fromJSON postcss-8.4.49/lib/fromJSON.js000066400000000000000000000027421471446070100160700ustar00rootroot00000000000000'use strict' let AtRule = require('./at-rule') let Comment = require('./comment') let Declaration = require('./declaration') let Input = require('./input') let PreviousMap = require('./previous-map') let Root = require('./root') let Rule = require('./rule') function fromJSON(json, inputs) { if (Array.isArray(json)) return json.map(n => fromJSON(n)) let { inputs: ownInputs, ...defaults } = json if (ownInputs) { inputs = [] for (let input of ownInputs) { let inputHydrated = { ...input, __proto__: Input.prototype } if (inputHydrated.map) { inputHydrated.map = { ...inputHydrated.map, __proto__: PreviousMap.prototype } } inputs.push(inputHydrated) } } if (defaults.nodes) { defaults.nodes = json.nodes.map(n => fromJSON(n, inputs)) } if (defaults.source) { let { inputId, ...source } = defaults.source defaults.source = source if (inputId != null) { defaults.source.input = inputs[inputId] } } if (defaults.type === 'root') { return new Root(defaults) } else if (defaults.type === 'decl') { return new Declaration(defaults) } else if (defaults.type === 'rule') { return new Rule(defaults) } else if (defaults.type === 'comment') { return new Comment(defaults) } else if (defaults.type === 'atrule') { return new AtRule(defaults) } else { throw new Error('Unknown node type: ' + json.type) } } module.exports = fromJSON fromJSON.default = fromJSON postcss-8.4.49/lib/input.d.ts000066400000000000000000000106351471446070100160260ustar00rootroot00000000000000import { CssSyntaxError, ProcessOptions } from './postcss.js' import PreviousMap from './previous-map.js' declare namespace Input { export interface FilePosition { /** * Column of inclusive start position in source file. */ column: number /** * Column of exclusive end position in source file. */ endColumn?: number /** * Line of exclusive end position in source file. */ endLine?: number /** * Absolute path to the source file. */ file?: string /** * Line of inclusive start position in source file. */ line: number /** * Source code. */ source?: string /** * URL for the source file. */ url: string } // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Input_ as default } } /** * Represents the source CSS. * * ```js * const root = postcss.parse(css, { from: file }) * const input = root.source.input * ``` */ declare class Input_ { /** * Input CSS source. * * ```js * const input = postcss.parse('a{}', { from: file }).input * input.css //=> "a{}" * ``` */ css: string /** * The absolute path to the CSS source file defined * with the `from` option. * * ```js * const root = postcss.parse(css, { from: 'a.css' }) * root.source.input.file //=> '/home/ai/a.css' * ``` */ file?: string /** * The flag to indicate whether or not the source code has Unicode BOM. */ hasBOM: boolean /** * The unique ID of the CSS source. It will be created if `from` option * is not provided (because PostCSS does not know the file path). * * ```js * const root = postcss.parse(css) * root.source.input.file //=> undefined * root.source.input.id //=> "" * ``` */ id?: string /** * The input source map passed from a compilation step before PostCSS * (for example, from Sass compiler). * * ```js * root.source.input.map.consumer().sources //=> ['a.sass'] * ``` */ map: PreviousMap /** * @param css Input CSS source. * @param opts Process options. */ constructor(css: string, opts?: ProcessOptions) error( message: string, start: | { column: number line: number } | { offset: number }, end: | { column: number line: number } | { offset: number }, opts?: { plugin?: CssSyntaxError['plugin'] } ): CssSyntaxError /** * Returns `CssSyntaxError` with information about the error and its position. */ error( message: string, line: number, column: number, opts?: { plugin?: CssSyntaxError['plugin'] } ): CssSyntaxError error( message: string, offset: number, opts?: { plugin?: CssSyntaxError['plugin'] } ): CssSyntaxError /** * Converts source offset to line and column. * * @param offset Source offset. */ fromOffset(offset: number): { col: number; line: number } | null /** * Reads the input source map and returns a symbol position * in the input source (e.g., in a Sass file that was compiled * to CSS before being passed to PostCSS). Optionally takes an * end position, exclusive. * * ```js * root.source.input.origin(1, 1) //=> { file: 'a.css', line: 3, column: 1 } * root.source.input.origin(1, 1, 1, 4) * //=> { file: 'a.css', line: 3, column: 1, endLine: 3, endColumn: 4 } * ``` * * @param line Line for inclusive start position in input CSS. * @param column Column for inclusive start position in input CSS. * @param endLine Line for exclusive end position in input CSS. * @param endColumn Column for exclusive end position in input CSS. * * @return Position in input source. */ origin( line: number, column: number, endLine?: number, endColumn?: number ): false | Input.FilePosition /** Converts this to a JSON-friendly object representation. */ toJSON(): object /** * The CSS source identifier. Contains `Input#file` if the user * set the `from` option, or `Input#id` if they did not. * * ```js * const root = postcss.parse(css, { from: 'a.css' }) * root.source.input.from //=> "/home/ai/a.css" * * const root = postcss.parse(css) * root.source.input.from //=> "" * ``` */ get from(): string } declare class Input extends Input_ {} export = Input postcss-8.4.49/lib/input.js000066400000000000000000000140561471446070100155730ustar00rootroot00000000000000'use strict' let { nanoid } = require('nanoid/non-secure') let { isAbsolute, resolve } = require('path') let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') let { fileURLToPath, pathToFileURL } = require('url') let CssSyntaxError = require('./css-syntax-error') let PreviousMap = require('./previous-map') let terminalHighlight = require('./terminal-highlight') let fromOffsetCache = Symbol('fromOffsetCache') let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) let pathAvailable = Boolean(resolve && isAbsolute) class Input { constructor(css, opts = {}) { if ( css === null || typeof css === 'undefined' || (typeof css === 'object' && !css.toString) ) { throw new Error(`PostCSS received ${css} instead of CSS string`) } this.css = css.toString() if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { this.hasBOM = true this.css = this.css.slice(1) } else { this.hasBOM = false } if (opts.from) { if ( !pathAvailable || /^\w+:\/\//.test(opts.from) || isAbsolute(opts.from) ) { this.file = opts.from } else { this.file = resolve(opts.from) } } if (pathAvailable && sourceMapAvailable) { let map = new PreviousMap(this.css, opts) if (map.text) { this.map = map let file = map.consumer().file if (!this.file && file) this.file = this.mapResolve(file) } } if (!this.file) { this.id = '' } if (this.map) this.map.file = this.from } error(message, line, column, opts = {}) { let endColumn, endLine, result if (line && typeof line === 'object') { let start = line let end = column if (typeof start.offset === 'number') { let pos = this.fromOffset(start.offset) line = pos.line column = pos.col } else { line = start.line column = start.column } if (typeof end.offset === 'number') { let pos = this.fromOffset(end.offset) endLine = pos.line endColumn = pos.col } else { endLine = end.line endColumn = end.column } } else if (!column) { let pos = this.fromOffset(line) line = pos.line column = pos.col } let origin = this.origin(line, column, endLine, endColumn) if (origin) { result = new CssSyntaxError( message, origin.endLine === undefined ? origin.line : { column: origin.column, line: origin.line }, origin.endLine === undefined ? origin.column : { column: origin.endColumn, line: origin.endLine }, origin.source, origin.file, opts.plugin ) } else { result = new CssSyntaxError( message, endLine === undefined ? line : { column, line }, endLine === undefined ? column : { column: endColumn, line: endLine }, this.css, this.file, opts.plugin ) } result.input = { column, endColumn, endLine, line, source: this.css } if (this.file) { if (pathToFileURL) { result.input.url = pathToFileURL(this.file).toString() } result.input.file = this.file } return result } fromOffset(offset) { let lastLine, lineToIndex if (!this[fromOffsetCache]) { let lines = this.css.split('\n') lineToIndex = new Array(lines.length) let prevIndex = 0 for (let i = 0, l = lines.length; i < l; i++) { lineToIndex[i] = prevIndex prevIndex += lines[i].length + 1 } this[fromOffsetCache] = lineToIndex } else { lineToIndex = this[fromOffsetCache] } lastLine = lineToIndex[lineToIndex.length - 1] let min = 0 if (offset >= lastLine) { min = lineToIndex.length - 1 } else { let max = lineToIndex.length - 2 let mid while (min < max) { mid = min + ((max - min) >> 1) if (offset < lineToIndex[mid]) { max = mid - 1 } else if (offset >= lineToIndex[mid + 1]) { min = mid + 1 } else { min = mid break } } } return { col: offset - lineToIndex[min] + 1, line: min + 1 } } mapResolve(file) { if (/^\w+:\/\//.test(file)) { return file } return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file) } origin(line, column, endLine, endColumn) { if (!this.map) return false let consumer = this.map.consumer() let from = consumer.originalPositionFor({ column, line }) if (!from.source) return false let to if (typeof endLine === 'number') { to = consumer.originalPositionFor({ column: endColumn, line: endLine }) } let fromUrl if (isAbsolute(from.source)) { fromUrl = pathToFileURL(from.source) } else { fromUrl = new URL( from.source, this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile) ) } let result = { column: from.column, endColumn: to && to.column, endLine: to && to.line, line: from.line, url: fromUrl.toString() } if (fromUrl.protocol === 'file:') { if (fileURLToPath) { result.file = fileURLToPath(fromUrl) } else { /* c8 ignore next 2 */ throw new Error(`file: protocol is not available in this PostCSS build`) } } let source = consumer.sourceContentFor(from.source) if (source) result.source = source return result } toJSON() { let json = {} for (let name of ['hasBOM', 'css', 'file', 'id']) { if (this[name] != null) { json[name] = this[name] } } if (this.map) { json.map = { ...this.map } if (json.map.consumerCache) { json.map.consumerCache = undefined } } return json } get from() { return this.file || this.id } } module.exports = Input Input.default = Input if (terminalHighlight && terminalHighlight.registerInput) { terminalHighlight.registerInput(Input) } postcss-8.4.49/lib/lazy-result.d.ts000066400000000000000000000116171471446070100171630ustar00rootroot00000000000000import Document from './document.js' import { SourceMap } from './postcss.js' import Processor from './processor.js' import Result, { Message, ResultOptions } from './result.js' import Root from './root.js' import Warning from './warning.js' declare namespace LazyResult { // eslint-disable-next-line @typescript-eslint/no-use-before-define export { LazyResult_ as default } } /** * A Promise proxy for the result of PostCSS transformations. * * A `LazyResult` instance is returned by `Processor#process`. * * ```js * const lazy = postcss([autoprefixer]).process(css) * ``` */ declare class LazyResult_ implements PromiseLike> { /** * Processes input CSS through synchronous and asynchronous plugins * and calls onRejected for each error thrown in any plugin. * * It implements standard Promise API. * * ```js * postcss([autoprefixer]).process(css).then(result => { * console.log(result.css) * }).catch(error => { * console.error(error) * }) * ``` */ catch: Promise>['catch'] /** * Processes input CSS through synchronous and asynchronous plugins * and calls onFinally on any error or when all plugins will finish work. * * It implements standard Promise API. * * ```js * postcss([autoprefixer]).process(css).finally(() => { * console.log('processing ended') * }) * ``` */ finally: Promise>['finally'] /** * Processes input CSS through synchronous and asynchronous plugins * and calls `onFulfilled` with a Result instance. If a plugin throws * an error, the `onRejected` callback will be executed. * * It implements standard Promise API. * * ```js * postcss([autoprefixer]).process(css, { from: cssPath }).then(result => { * console.log(result.css) * }) * ``` */ then: Promise>['then'] /** * @param processor Processor used for this transformation. * @param css CSS to parse and transform. * @param opts Options from the `Processor#process` or `Root#toResult`. */ constructor(processor: Processor, css: string, opts: ResultOptions) /** * Run plugin in async way and return `Result`. * * @return Result with output content. */ async(): Promise> /** * Run plugin in sync way and return `Result`. * * @return Result with output content. */ sync(): Result /** * Alias for the `LazyResult#css` property. * * ```js * lazy + '' === lazy.css * ``` * * @return Output CSS. */ toString(): string /** * Processes input CSS through synchronous plugins * and calls `Result#warnings`. * * @return Warnings from plugins. */ warnings(): Warning[] /** * An alias for the `css` property. Use it with syntaxes * that generate non-CSS output. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. * * PostCSS runners should always use `LazyResult#then`. */ get content(): string /** * Processes input CSS through synchronous plugins, converts `Root` * to a CSS string and returns `Result#css`. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. * * PostCSS runners should always use `LazyResult#then`. */ get css(): string /** * Processes input CSS through synchronous plugins * and returns `Result#map`. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. * * PostCSS runners should always use `LazyResult#then`. */ get map(): SourceMap /** * Processes input CSS through synchronous plugins * and returns `Result#messages`. * * This property will only work with synchronous plugins. If the processor * contains any asynchronous plugins it will throw an error. * * PostCSS runners should always use `LazyResult#then`. */ get messages(): Message[] /** * Options from the `Processor#process` call. */ get opts(): ResultOptions /** * Returns a `Processor` instance, which will be used * for CSS transformations. */ get processor(): Processor /** * Processes input CSS through synchronous plugins * and returns `Result#root`. * * This property will only work with synchronous plugins. If the processor * contains any asynchronous plugins it will throw an error. * * PostCSS runners should always use `LazyResult#then`. */ get root(): RootNode /** * Returns the default string description of an object. * Required to implement the Promise interface. */ get [Symbol.toStringTag](): string } declare class LazyResult< RootNode = Document | Root > extends LazyResult_ {} export = LazyResult postcss-8.4.49/lib/lazy-result.js000066400000000000000000000323721471446070100167300ustar00rootroot00000000000000'use strict' let Container = require('./container') let Document = require('./document') let MapGenerator = require('./map-generator') let parse = require('./parse') let Result = require('./result') let Root = require('./root') let stringify = require('./stringify') let { isClean, my } = require('./symbols') let warnOnce = require('./warn-once') const TYPE_TO_CLASS_NAME = { atrule: 'AtRule', comment: 'Comment', decl: 'Declaration', document: 'Document', root: 'Root', rule: 'Rule' } const PLUGIN_PROPS = { AtRule: true, AtRuleExit: true, Comment: true, CommentExit: true, Declaration: true, DeclarationExit: true, Document: true, DocumentExit: true, Once: true, OnceExit: true, postcssPlugin: true, prepare: true, Root: true, RootExit: true, Rule: true, RuleExit: true } const NOT_VISITORS = { Once: true, postcssPlugin: true, prepare: true } const CHILDREN = 0 function isPromise(obj) { return typeof obj === 'object' && typeof obj.then === 'function' } function getEvents(node) { let key = false let type = TYPE_TO_CLASS_NAME[node.type] if (node.type === 'decl') { key = node.prop.toLowerCase() } else if (node.type === 'atrule') { key = node.name.toLowerCase() } if (key && node.append) { return [ type, type + '-' + key, CHILDREN, type + 'Exit', type + 'Exit-' + key ] } else if (key) { return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key] } else if (node.append) { return [type, CHILDREN, type + 'Exit'] } else { return [type, type + 'Exit'] } } function toStack(node) { let events if (node.type === 'document') { events = ['Document', CHILDREN, 'DocumentExit'] } else if (node.type === 'root') { events = ['Root', CHILDREN, 'RootExit'] } else { events = getEvents(node) } return { eventIndex: 0, events, iterator: 0, node, visitorIndex: 0, visitors: [] } } function cleanMarks(node) { node[isClean] = false if (node.nodes) node.nodes.forEach(i => cleanMarks(i)) return node } let postcss = {} class LazyResult { constructor(processor, css, opts) { this.stringified = false this.processed = false let root if ( typeof css === 'object' && css !== null && (css.type === 'root' || css.type === 'document') ) { root = cleanMarks(css) } else if (css instanceof LazyResult || css instanceof Result) { root = cleanMarks(css.root) if (css.map) { if (typeof opts.map === 'undefined') opts.map = {} if (!opts.map.inline) opts.map.inline = false opts.map.prev = css.map } } else { let parser = parse if (opts.syntax) parser = opts.syntax.parse if (opts.parser) parser = opts.parser if (parser.parse) parser = parser.parse try { root = parser(css, opts) } catch (error) { this.processed = true this.error = error } if (root && !root[my]) { /* c8 ignore next 2 */ Container.rebuild(root) } } this.result = new Result(processor, root, opts) this.helpers = { ...postcss, postcss, result: this.result } this.plugins = this.processor.plugins.map(plugin => { if (typeof plugin === 'object' && plugin.prepare) { return { ...plugin, ...plugin.prepare(this.result) } } else { return plugin } }) } async() { if (this.error) return Promise.reject(this.error) if (this.processed) return Promise.resolve(this.result) if (!this.processing) { this.processing = this.runAsync() } return this.processing } catch(onRejected) { return this.async().catch(onRejected) } finally(onFinally) { return this.async().then(onFinally, onFinally) } getAsyncError() { throw new Error('Use process(css).then(cb) to work with async plugins') } handleError(error, node) { let plugin = this.result.lastPlugin try { if (node) node.addToError(error) this.error = error if (error.name === 'CssSyntaxError' && !error.plugin) { error.plugin = plugin.postcssPlugin error.setMessage() } else if (plugin.postcssVersion) { if (process.env.NODE_ENV !== 'production') { let pluginName = plugin.postcssPlugin let pluginVer = plugin.postcssVersion let runtimeVer = this.result.processor.version let a = pluginVer.split('.') let b = runtimeVer.split('.') if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) { // eslint-disable-next-line no-console console.error( 'Unknown error from PostCSS plugin. Your current PostCSS ' + 'version is ' + runtimeVer + ', but ' + pluginName + ' uses ' + pluginVer + '. Perhaps this is the source of the error below.' ) } } } } catch (err) { /* c8 ignore next 3 */ // eslint-disable-next-line no-console if (console && console.error) console.error(err) } return error } prepareVisitors() { this.listeners = {} let add = (plugin, type, cb) => { if (!this.listeners[type]) this.listeners[type] = [] this.listeners[type].push([plugin, cb]) } for (let plugin of this.plugins) { if (typeof plugin === 'object') { for (let event in plugin) { if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) { throw new Error( `Unknown event ${event} in ${plugin.postcssPlugin}. ` + `Try to update PostCSS (${this.processor.version} now).` ) } if (!NOT_VISITORS[event]) { if (typeof plugin[event] === 'object') { for (let filter in plugin[event]) { if (filter === '*') { add(plugin, event, plugin[event][filter]) } else { add( plugin, event + '-' + filter.toLowerCase(), plugin[event][filter] ) } } } else if (typeof plugin[event] === 'function') { add(plugin, event, plugin[event]) } } } } } this.hasListener = Object.keys(this.listeners).length > 0 } async runAsync() { this.plugin = 0 for (let i = 0; i < this.plugins.length; i++) { let plugin = this.plugins[i] let promise = this.runOnRoot(plugin) if (isPromise(promise)) { try { await promise } catch (error) { throw this.handleError(error) } } } this.prepareVisitors() if (this.hasListener) { let root = this.result.root while (!root[isClean]) { root[isClean] = true let stack = [toStack(root)] while (stack.length > 0) { let promise = this.visitTick(stack) if (isPromise(promise)) { try { await promise } catch (e) { let node = stack[stack.length - 1].node throw this.handleError(e, node) } } } } if (this.listeners.OnceExit) { for (let [plugin, visitor] of this.listeners.OnceExit) { this.result.lastPlugin = plugin try { if (root.type === 'document') { let roots = root.nodes.map(subRoot => visitor(subRoot, this.helpers) ) await Promise.all(roots) } else { await visitor(root, this.helpers) } } catch (e) { throw this.handleError(e) } } } } this.processed = true return this.stringify() } runOnRoot(plugin) { this.result.lastPlugin = plugin try { if (typeof plugin === 'object' && plugin.Once) { if (this.result.root.type === 'document') { let roots = this.result.root.nodes.map(root => plugin.Once(root, this.helpers) ) if (isPromise(roots[0])) { return Promise.all(roots) } return roots } return plugin.Once(this.result.root, this.helpers) } else if (typeof plugin === 'function') { return plugin(this.result.root, this.result) } } catch (error) { throw this.handleError(error) } } stringify() { if (this.error) throw this.error if (this.stringified) return this.result this.stringified = true this.sync() let opts = this.result.opts let str = stringify if (opts.syntax) str = opts.syntax.stringify if (opts.stringifier) str = opts.stringifier if (str.stringify) str = str.stringify let map = new MapGenerator(str, this.result.root, this.result.opts) let data = map.generate() this.result.css = data[0] this.result.map = data[1] return this.result } sync() { if (this.error) throw this.error if (this.processed) return this.result this.processed = true if (this.processing) { throw this.getAsyncError() } for (let plugin of this.plugins) { let promise = this.runOnRoot(plugin) if (isPromise(promise)) { throw this.getAsyncError() } } this.prepareVisitors() if (this.hasListener) { let root = this.result.root while (!root[isClean]) { root[isClean] = true this.walkSync(root) } if (this.listeners.OnceExit) { if (root.type === 'document') { for (let subRoot of root.nodes) { this.visitSync(this.listeners.OnceExit, subRoot) } } else { this.visitSync(this.listeners.OnceExit, root) } } } return this.result } then(onFulfilled, onRejected) { if (process.env.NODE_ENV !== 'production') { if (!('from' in this.opts)) { warnOnce( 'Without `from` option PostCSS could generate wrong source map ' + 'and will not find Browserslist config. Set it to CSS file path ' + 'or to `undefined` to prevent this warning.' ) } } return this.async().then(onFulfilled, onRejected) } toString() { return this.css } visitSync(visitors, node) { for (let [plugin, visitor] of visitors) { this.result.lastPlugin = plugin let promise try { promise = visitor(node, this.helpers) } catch (e) { throw this.handleError(e, node.proxyOf) } if (node.type !== 'root' && node.type !== 'document' && !node.parent) { return true } if (isPromise(promise)) { throw this.getAsyncError() } } } visitTick(stack) { let visit = stack[stack.length - 1] let { node, visitors } = visit if (node.type !== 'root' && node.type !== 'document' && !node.parent) { stack.pop() return } if (visitors.length > 0 && visit.visitorIndex < visitors.length) { let [plugin, visitor] = visitors[visit.visitorIndex] visit.visitorIndex += 1 if (visit.visitorIndex === visitors.length) { visit.visitors = [] visit.visitorIndex = 0 } this.result.lastPlugin = plugin try { return visitor(node.toProxy(), this.helpers) } catch (e) { throw this.handleError(e, node) } } if (visit.iterator !== 0) { let iterator = visit.iterator let child while ((child = node.nodes[node.indexes[iterator]])) { node.indexes[iterator] += 1 if (!child[isClean]) { child[isClean] = true stack.push(toStack(child)) return } } visit.iterator = 0 delete node.indexes[iterator] } let events = visit.events while (visit.eventIndex < events.length) { let event = events[visit.eventIndex] visit.eventIndex += 1 if (event === CHILDREN) { if (node.nodes && node.nodes.length) { node[isClean] = true visit.iterator = node.getIterator() } return } else if (this.listeners[event]) { visit.visitors = this.listeners[event] return } } stack.pop() } walkSync(node) { node[isClean] = true let events = getEvents(node) for (let event of events) { if (event === CHILDREN) { if (node.nodes) { node.each(child => { if (!child[isClean]) this.walkSync(child) }) } } else { let visitors = this.listeners[event] if (visitors) { if (this.visitSync(visitors, node.toProxy())) return } } } } warnings() { return this.sync().warnings() } get content() { return this.stringify().content } get css() { return this.stringify().css } get map() { return this.stringify().map } get messages() { return this.sync().messages } get opts() { return this.result.opts } get processor() { return this.result.processor } get root() { return this.sync().root } get [Symbol.toStringTag]() { return 'LazyResult' } } LazyResult.registerPostcss = dependant => { postcss = dependant } module.exports = LazyResult LazyResult.default = LazyResult Root.registerLazyResult(LazyResult) Document.registerLazyResult(LazyResult) postcss-8.4.49/lib/list.d.ts000066400000000000000000000026221471446070100156370ustar00rootroot00000000000000declare namespace list { type List = { /** * Safely splits comma-separated values (such as those for `transition-*` * and `background` properties). * * ```js * Once (root, { list }) { * list.comma('black, linear-gradient(white, black)') * //=> ['black', 'linear-gradient(white, black)'] * } * ``` * * @param str Comma-separated values. * @return Split values. */ comma(str: string): string[] default: List /** * Safely splits space-separated values (such as those for `background`, * `border-radius`, and other shorthand properties). * * ```js * Once (root, { list }) { * list.space('1px calc(10% + 1px)') //=> ['1px', 'calc(10% + 1px)'] * } * ``` * * @param str Space-separated values. * @return Split values. */ space(str: string): string[] /** * Safely splits values. * * ```js * Once (root, { list }) { * list.split('1px calc(10% + 1px)', [' ', '\n', '\t']) //=> ['1px', 'calc(10% + 1px)'] * } * ``` * * @param string separated values. * @param separators array of separators. * @param last boolean indicator. * @return Split values. */ split( string: string, separators: readonly string[], last: boolean ): string[] } } declare const list: list.List export = list postcss-8.4.49/lib/list.js000066400000000000000000000023131471446070100154000ustar00rootroot00000000000000'use strict' let list = { comma(string) { return list.split(string, [','], true) }, space(string) { let spaces = [' ', '\n', '\t'] return list.split(string, spaces) }, split(string, separators, last) { let array = [] let current = '' let split = false let func = 0 let inQuote = false let prevQuote = '' let escape = false for (let letter of string) { if (escape) { escape = false } else if (letter === '\\') { escape = true } else if (inQuote) { if (letter === prevQuote) { inQuote = false } } else if (letter === '"' || letter === "'") { inQuote = true prevQuote = letter } else if (letter === '(') { func += 1 } else if (letter === ')') { if (func > 0) func -= 1 } else if (func === 0) { if (separators.includes(letter)) split = true } if (split) { if (current !== '') array.push(current.trim()) current = '' split = false } else { current += letter } } if (last || current !== '') array.push(current.trim()) return array } } module.exports = list list.default = list postcss-8.4.49/lib/map-generator.js000066400000000000000000000227711471446070100172000ustar00rootroot00000000000000'use strict' let { dirname, relative, resolve, sep } = require('path') let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') let { pathToFileURL } = require('url') let Input = require('./input') let sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator) let pathAvailable = Boolean(dirname && resolve && relative && sep) class MapGenerator { constructor(stringify, root, opts, cssString) { this.stringify = stringify this.mapOpts = opts.map || {} this.root = root this.opts = opts this.css = cssString this.originalCSS = cssString this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute this.memoizedFileURLs = new Map() this.memoizedPaths = new Map() this.memoizedURLs = new Map() } addAnnotation() { let content if (this.isInline()) { content = 'data:application/json;base64,' + this.toBase64(this.map.toString()) } else if (typeof this.mapOpts.annotation === 'string') { content = this.mapOpts.annotation } else if (typeof this.mapOpts.annotation === 'function') { content = this.mapOpts.annotation(this.opts.to, this.root) } else { content = this.outputFile() + '.map' } let eol = '\n' if (this.css.includes('\r\n')) eol = '\r\n' this.css += eol + '/*# sourceMappingURL=' + content + ' */' } applyPrevMaps() { for (let prev of this.previous()) { let from = this.toUrl(this.path(prev.file)) let root = prev.root || dirname(prev.file) let map if (this.mapOpts.sourcesContent === false) { map = new SourceMapConsumer(prev.text) if (map.sourcesContent) { map.sourcesContent = null } } else { map = prev.consumer() } this.map.applySourceMap(map, from, this.toUrl(this.path(root))) } } clearAnnotation() { if (this.mapOpts.annotation === false) return if (this.root) { let node for (let i = this.root.nodes.length - 1; i >= 0; i--) { node = this.root.nodes[i] if (node.type !== 'comment') continue if (node.text.startsWith('# sourceMappingURL=')) { this.root.removeChild(i) } } } else if (this.css) { this.css = this.css.replace(/\n*\/\*#[\S\s]*?\*\/$/gm, '') } } generate() { this.clearAnnotation() if (pathAvailable && sourceMapAvailable && this.isMap()) { return this.generateMap() } else { let result = '' this.stringify(this.root, i => { result += i }) return [result] } } generateMap() { if (this.root) { this.generateString() } else if (this.previous().length === 1) { let prev = this.previous()[0].consumer() prev.file = this.outputFile() this.map = SourceMapGenerator.fromSourceMap(prev, { ignoreInvalidMapping: true }) } else { this.map = new SourceMapGenerator({ file: this.outputFile(), ignoreInvalidMapping: true }) this.map.addMapping({ generated: { column: 0, line: 1 }, original: { column: 0, line: 1 }, source: this.opts.from ? this.toUrl(this.path(this.opts.from)) : '' }) } if (this.isSourcesContent()) this.setSourcesContent() if (this.root && this.previous().length > 0) this.applyPrevMaps() if (this.isAnnotation()) this.addAnnotation() if (this.isInline()) { return [this.css] } else { return [this.css, this.map] } } generateString() { this.css = '' this.map = new SourceMapGenerator({ file: this.outputFile(), ignoreInvalidMapping: true }) let line = 1 let column = 1 let noSource = '' let mapping = { generated: { column: 0, line: 0 }, original: { column: 0, line: 0 }, source: '' } let last, lines this.stringify(this.root, (str, node, type) => { this.css += str if (node && type !== 'end') { mapping.generated.line = line mapping.generated.column = column - 1 if (node.source && node.source.start) { mapping.source = this.sourcePath(node) mapping.original.line = node.source.start.line mapping.original.column = node.source.start.column - 1 this.map.addMapping(mapping) } else { mapping.source = noSource mapping.original.line = 1 mapping.original.column = 0 this.map.addMapping(mapping) } } lines = str.match(/\n/g) if (lines) { line += lines.length last = str.lastIndexOf('\n') column = str.length - last } else { column += str.length } if (node && type !== 'start') { let p = node.parent || { raws: {} } let childless = node.type === 'decl' || (node.type === 'atrule' && !node.nodes) if (!childless || node !== p.last || p.raws.semicolon) { if (node.source && node.source.end) { mapping.source = this.sourcePath(node) mapping.original.line = node.source.end.line mapping.original.column = node.source.end.column - 1 mapping.generated.line = line mapping.generated.column = column - 2 this.map.addMapping(mapping) } else { mapping.source = noSource mapping.original.line = 1 mapping.original.column = 0 mapping.generated.line = line mapping.generated.column = column - 1 this.map.addMapping(mapping) } } } }) } isAnnotation() { if (this.isInline()) { return true } if (typeof this.mapOpts.annotation !== 'undefined') { return this.mapOpts.annotation } if (this.previous().length) { return this.previous().some(i => i.annotation) } return true } isInline() { if (typeof this.mapOpts.inline !== 'undefined') { return this.mapOpts.inline } let annotation = this.mapOpts.annotation if (typeof annotation !== 'undefined' && annotation !== true) { return false } if (this.previous().length) { return this.previous().some(i => i.inline) } return true } isMap() { if (typeof this.opts.map !== 'undefined') { return !!this.opts.map } return this.previous().length > 0 } isSourcesContent() { if (typeof this.mapOpts.sourcesContent !== 'undefined') { return this.mapOpts.sourcesContent } if (this.previous().length) { return this.previous().some(i => i.withContent()) } return true } outputFile() { if (this.opts.to) { return this.path(this.opts.to) } else if (this.opts.from) { return this.path(this.opts.from) } else { return 'to.css' } } path(file) { if (this.mapOpts.absolute) return file if (file.charCodeAt(0) === 60 /* `<` */) return file if (/^\w+:\/\//.test(file)) return file let cached = this.memoizedPaths.get(file) if (cached) return cached let from = this.opts.to ? dirname(this.opts.to) : '.' if (typeof this.mapOpts.annotation === 'string') { from = dirname(resolve(from, this.mapOpts.annotation)) } let path = relative(from, file) this.memoizedPaths.set(file, path) return path } previous() { if (!this.previousMaps) { this.previousMaps = [] if (this.root) { this.root.walk(node => { if (node.source && node.source.input.map) { let map = node.source.input.map if (!this.previousMaps.includes(map)) { this.previousMaps.push(map) } } }) } else { let input = new Input(this.originalCSS, this.opts) if (input.map) this.previousMaps.push(input.map) } } return this.previousMaps } setSourcesContent() { let already = {} if (this.root) { this.root.walk(node => { if (node.source) { let from = node.source.input.from if (from && !already[from]) { already[from] = true let fromUrl = this.usesFileUrls ? this.toFileUrl(from) : this.toUrl(this.path(from)) this.map.setSourceContent(fromUrl, node.source.input.css) } } }) } else if (this.css) { let from = this.opts.from ? this.toUrl(this.path(this.opts.from)) : '' this.map.setSourceContent(from, this.css) } } sourcePath(node) { if (this.mapOpts.from) { return this.toUrl(this.mapOpts.from) } else if (this.usesFileUrls) { return this.toFileUrl(node.source.input.from) } else { return this.toUrl(this.path(node.source.input.from)) } } toBase64(str) { if (Buffer) { return Buffer.from(str).toString('base64') } else { return window.btoa(unescape(encodeURIComponent(str))) } } toFileUrl(path) { let cached = this.memoizedFileURLs.get(path) if (cached) return cached if (pathToFileURL) { let fileURL = pathToFileURL(path).toString() this.memoizedFileURLs.set(path, fileURL) return fileURL } else { throw new Error( '`map.absolute` option is not available in this PostCSS build' ) } } toUrl(path) { let cached = this.memoizedURLs.get(path) if (cached) return cached if (sep === '\\') { path = path.replace(/\\/g, '/') } let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent) this.memoizedURLs.set(path, url) return url } } module.exports = MapGenerator postcss-8.4.49/lib/no-work-result.d.ts000066400000000000000000000030451471446070100175740ustar00rootroot00000000000000import LazyResult from './lazy-result.js' import { SourceMap } from './postcss.js' import Processor from './processor.js' import Result, { Message, ResultOptions } from './result.js' import Root from './root.js' import Warning from './warning.js' declare namespace NoWorkResult { // eslint-disable-next-line @typescript-eslint/no-use-before-define export { NoWorkResult_ as default } } /** * A Promise proxy for the result of PostCSS transformations. * This lazy result instance doesn't parse css unless `NoWorkResult#root` or `Result#root` * are accessed. See the example below for details. * A `NoWork` instance is returned by `Processor#process` ONLY when no plugins defined. * * ```js * const noWorkResult = postcss().process(css) // No plugins are defined. * // CSS is not parsed * let root = noWorkResult.root // now css is parsed because we accessed the root * ``` */ declare class NoWorkResult_ implements LazyResult { catch: Promise>['catch'] finally: Promise>['finally'] then: Promise>['then'] constructor(processor: Processor, css: string, opts: ResultOptions) async(): Promise> sync(): Result toString(): string warnings(): Warning[] get content(): string get css(): string get map(): SourceMap get messages(): Message[] get opts(): ResultOptions get processor(): Processor get root(): Root get [Symbol.toStringTag](): string } declare class NoWorkResult extends NoWorkResult_ {} export = NoWorkResult postcss-8.4.49/lib/no-work-result.js000066400000000000000000000051001471446070100173320ustar00rootroot00000000000000'use strict' let MapGenerator = require('./map-generator') let parse = require('./parse') const Result = require('./result') let stringify = require('./stringify') let warnOnce = require('./warn-once') class NoWorkResult { constructor(processor, css, opts) { css = css.toString() this.stringified = false this._processor = processor this._css = css this._opts = opts this._map = undefined let root let str = stringify this.result = new Result(this._processor, root, this._opts) this.result.css = css let self = this Object.defineProperty(this.result, 'root', { get() { return self.root } }) let map = new MapGenerator(str, root, this._opts, css) if (map.isMap()) { let [generatedCSS, generatedMap] = map.generate() if (generatedCSS) { this.result.css = generatedCSS } if (generatedMap) { this.result.map = generatedMap } } else { map.clearAnnotation() this.result.css = map.css } } async() { if (this.error) return Promise.reject(this.error) return Promise.resolve(this.result) } catch(onRejected) { return this.async().catch(onRejected) } finally(onFinally) { return this.async().then(onFinally, onFinally) } sync() { if (this.error) throw this.error return this.result } then(onFulfilled, onRejected) { if (process.env.NODE_ENV !== 'production') { if (!('from' in this._opts)) { warnOnce( 'Without `from` option PostCSS could generate wrong source map ' + 'and will not find Browserslist config. Set it to CSS file path ' + 'or to `undefined` to prevent this warning.' ) } } return this.async().then(onFulfilled, onRejected) } toString() { return this._css } warnings() { return [] } get content() { return this.result.css } get css() { return this.result.css } get map() { return this.result.map } get messages() { return [] } get opts() { return this.result.opts } get processor() { return this.result.processor } get root() { if (this._root) { return this._root } let root let parser = parse try { root = parser(this._css, this._opts) } catch (error) { this.error = error } if (this.error) { throw this.error } else { this._root = root return root } } get [Symbol.toStringTag]() { return 'NoWorkResult' } } module.exports = NoWorkResult NoWorkResult.default = NoWorkResult postcss-8.4.49/lib/node.d.ts000066400000000000000000000334341471446070100156160ustar00rootroot00000000000000import AtRule = require('./at-rule.js') import { AtRuleProps } from './at-rule.js' import Comment, { CommentProps } from './comment.js' import Container, { NewChild } from './container.js' import CssSyntaxError from './css-syntax-error.js' import Declaration, { DeclarationProps } from './declaration.js' import Document from './document.js' import Input from './input.js' import { Stringifier, Syntax } from './postcss.js' import Result from './result.js' import Root from './root.js' import Rule, { RuleProps } from './rule.js' import Warning, { WarningOptions } from './warning.js' declare namespace Node { export type ChildNode = AtRule.default | Comment | Declaration | Rule export type AnyNode = | AtRule.default | Comment | Declaration | Document | Root | Rule export type ChildProps = | AtRuleProps | CommentProps | DeclarationProps | RuleProps export interface Position { /** * Source line in file. In contrast to `offset` it starts from 1. */ column: number /** * Source column in file. */ line: number /** * Source offset in file. It starts from 0. */ offset: number } export interface Range { /** * End position, exclusive. */ end: Position /** * Start position, inclusive. */ start: Position } /** * Source represents an interface for the {@link Node.source} property. */ export interface Source { /** * The inclusive ending position for the source * code of a node. */ end?: Position /** * The source file from where a node has originated. */ input: Input /** * The inclusive starting position for the source * code of a node. */ start?: Position } /** * Interface represents an interface for an object received * as parameter by Node class constructor. */ export interface NodeProps { source?: Source } export interface NodeErrorOptions { /** * An ending index inside a node's string that should be highlighted as * source of error. */ endIndex?: number /** * An index inside a node's string that should be highlighted as source * of error. */ index?: number /** * Plugin name that created this error. PostCSS will set it automatically. */ plugin?: string /** * A word inside a node's string, that should be highlighted as source * of error. */ word?: string } // eslint-disable-next-line @typescript-eslint/no-shadow class Node extends Node_ {} export { Node as default } } /** * It represents an abstract class that handles common * methods for other CSS abstract syntax tree nodes. * * Any node that represents CSS selector or value should * not extend the `Node` class. */ declare abstract class Node_ { /** * It represents parent of the current node. * * ```js * root.nodes[0].parent === root //=> true * ``` */ parent: Container | Document | undefined /** * It represents unnecessary whitespace and characters present * in the css source code. * * Information to generate byte-to-byte equal node string as it was * in the origin input. * * The properties of the raws object are decided by parser, * the default parser uses the following properties: * * * `before`: the space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). * * `after`: the space symbols after the last child of the node * to the end of the node. * * `between`: the symbols between the property and value * for declarations, selector and `{` for rules, or last parameter * and `{` for at-rules. * * `semicolon`: contains true if the last child has * an (optional) semicolon. * * `afterName`: the space between the at-rule name and its parameters. * * `left`: the space symbols between `/*` and the comment’s text. * * `right`: the space symbols between the comment’s text * and */. * - `important`: the content of the important statement, * if it is not just `!important`. * * PostCSS filters out the comments inside selectors, declaration values * and at-rule parameters but it stores the origin content in raws. * * ```js * const root = postcss.parse('a {\n color:black\n}') * root.first.first.raws //=> { before: '\n ', between: ':' } * ``` */ raws: any /** * It represents information related to origin of a node and is required * for generating source maps. * * The nodes that are created manually using the public APIs * provided by PostCSS will have `source` undefined and * will be absent in the source map. * * For this reason, the plugin developer should consider * duplicating nodes as the duplicate node will have the * same source as the original node by default or assign * source to a node created manually. * * ```js * decl.source.input.from //=> '/home/ai/source.css' * decl.source.start //=> { line: 10, column: 2 } * decl.source.end //=> { line: 10, column: 12 } * ``` * * ```js * // Incorrect method, source not specified! * const prefixed = postcss.decl({ * prop: '-moz-' + decl.prop, * value: decl.value * }) * * // Correct method, source is inherited when duplicating. * const prefixed = decl.clone({ * prop: '-moz-' + decl.prop * }) * ``` * * ```js * if (atrule.name === 'add-link') { * const rule = postcss.rule({ * selector: 'a', * source: atrule.source * }) * * atrule.parent.insertBefore(atrule, rule) * } * ``` */ source?: Node.Source /** * It represents type of a node in * an abstract syntax tree. * * A type of node helps in identification of a node * and perform operation based on it's type. * * ```js * const declaration = new Declaration({ * prop: 'color', * value: 'black' * }) * * declaration.type //=> 'decl' * ``` */ type: string constructor(defaults?: object) /** * If this node isn't already dirty, marks it and its ancestors as such. This * indicates to the LazyResult processor that the {@link Root} has been * modified by the current plugin and may need to be processed again by other * plugins. */ protected markDirty(): void /** * Insert new node after current node to current node’s parent. * * Just alias for `node.parent.insertAfter(node, add)`. * * ```js * decl.after('color: black') * ``` * * @param newNode New node. * @return This node for methods chain. */ after( newNode: Node | Node.ChildProps | readonly Node[] | string | undefined ): this /** * It assigns properties to an existing node instance. * * ```js * decl.assign({ prop: 'word-wrap', value: 'break-word' }) * ``` * * @param overrides New properties to override the node. * * @return `this` for method chaining. */ assign(overrides: object): this /** * Insert new node before current node to current node’s parent. * * Just alias for `node.parent.insertBefore(node, add)`. * * ```js * decl.before('content: ""') * ``` * * @param newNode New node. * @return This node for methods chain. */ before( newNode: Node | Node.ChildProps | readonly Node[] | string | undefined ): this /** * Clear the code style properties for the node and its children. * * ```js * node.raws.before //=> ' ' * node.cleanRaws() * node.raws.before //=> undefined * ``` * * @param keepBetween Keep the `raws.between` symbols. */ cleanRaws(keepBetween?: boolean): void /** * It creates clone of an existing node, which includes all the properties * and their values, that includes `raws` but not `type`. * * ```js * decl.raws.before //=> "\n " * const cloned = decl.clone({ prop: '-moz-' + decl.prop }) * cloned.raws.before //=> "\n " * cloned.toString() //=> -moz-transform: scale(0) * ``` * * @param overrides New properties to override in the clone. * * @return Duplicate of the node instance. */ clone(overrides?: object): this /** * Shortcut to clone the node and insert the resulting cloned node * after the current node. * * @param overrides New properties to override in the clone. * @return New node. */ cloneAfter(overrides?: object): this /** * Shortcut to clone the node and insert the resulting cloned node * before the current node. * * ```js * decl.cloneBefore({ prop: '-moz-' + decl.prop }) * ``` * * @param overrides Mew properties to override in the clone. * * @return New node */ cloneBefore(overrides?: object): this /** * It creates an instance of the class `CssSyntaxError` and parameters passed * to this method are assigned to the error instance. * * The error instance will have description for the * error, original position of the node in the * source, showing line and column number. * * If any previous map is present, it would be used * to get original position of the source. * * The Previous Map here is referred to the source map * generated by previous compilation, example: Less, * Stylus and Sass. * * This method returns the error instance instead of * throwing it. * * ```js * if (!variables[name]) { * throw decl.error(`Unknown variable ${name}`, { word: name }) * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black * // color: $black * // a * // ^ * // background: white * } * ``` * * @param message Description for the error instance. * @param options Options for the error instance. * * @return Error instance is returned. */ error(message: string, options?: Node.NodeErrorOptions): CssSyntaxError /** * Returns the next child of the node’s parent. * Returns `undefined` if the current node is the last child. * * ```js * if (comment.text === 'delete next') { * const next = comment.next() * if (next) { * next.remove() * } * } * ``` * * @return Next node. */ next(): Node.ChildNode | undefined /** * Get the position for a word or an index inside the node. * * @param opts Options. * @return Position. */ positionBy(opts?: Pick): Node.Position /** * Convert string index to line/column. * * @param index The symbol number in the node’s string. * @return Symbol position in file. */ positionInside(index: number): Node.Position /** * Returns the previous child of the node’s parent. * Returns `undefined` if the current node is the first child. * * ```js * const annotation = decl.prev() * if (annotation.type === 'comment') { * readAnnotation(annotation.text) * } * ``` * * @return Previous node. */ prev(): Node.ChildNode | undefined /** * Get the range for a word or start and end index inside the node. * The start index is inclusive; the end index is exclusive. * * @param opts Options. * @return Range. */ rangeBy( opts?: Pick ): Node.Range /** * Returns a `raws` value. If the node is missing * the code style property (because the node was manually built or cloned), * PostCSS will try to autodetect the code style property by looking * at other nodes in the tree. * * ```js * const root = postcss.parse('a { background: white }') * root.nodes[0].append({ prop: 'color', value: 'black' }) * root.nodes[0].nodes[1].raws.before //=> undefined * root.nodes[0].nodes[1].raw('before') //=> ' ' * ``` * * @param prop Name of code style property. * @param defaultType Name of default value, it can be missed * if the value is the same as prop. * @return {string} Code style value. */ raw(prop: string, defaultType?: string): string /** * It removes the node from its parent and deletes its parent property. * * ```js * if (decl.prop.match(/^-webkit-/)) { * decl.remove() * } * ``` * * @return `this` for method chaining. */ remove(): this /** * Inserts node(s) before the current node and removes the current node. * * ```js * AtRule: { * mixin: atrule => { * atrule.replaceWith(mixinRules[atrule.params]) * } * } * ``` * * @param nodes Mode(s) to replace current one. * @return Current node to methods chain. */ replaceWith(...nodes: NewChild[]): this /** * Finds the Root instance of the node’s tree. * * ```js * root.nodes[0].nodes[0].root() === root * ``` * * @return Root parent. */ root(): Root /** * Fix circular links on `JSON.stringify()`. * * @return Cleaned object. */ toJSON(): object /** * It compiles the node to browser readable cascading style sheets string * depending on it's type. * * ```js * new Rule({ selector: 'a' }).toString() //=> "a {}" * ``` * * @param stringifier A syntax to use in string generation. * @return CSS string of this node. */ toString(stringifier?: Stringifier | Syntax): string /** * It is a wrapper for {@link Result#warn}, providing convenient * way of generating warnings. * * ```js * Declaration: { * bad: (decl, { result }) => { * decl.warn(result, 'Deprecated property: bad') * } * } * ``` * * @param result The `Result` instance that will receive the warning. * @param message Description for the warning. * @param options Options for the warning. * * @return `Warning` instance is returned */ warn(result: Result, message: string, options?: WarningOptions): Warning } declare class Node extends Node_ {} export = Node postcss-8.4.49/lib/node.js000066400000000000000000000226431471446070100153620ustar00rootroot00000000000000'use strict' let CssSyntaxError = require('./css-syntax-error') let Stringifier = require('./stringifier') let stringify = require('./stringify') let { isClean, my } = require('./symbols') function cloneNode(obj, parent) { let cloned = new obj.constructor() for (let i in obj) { if (!Object.prototype.hasOwnProperty.call(obj, i)) { /* c8 ignore next 2 */ continue } if (i === 'proxyCache') continue let value = obj[i] let type = typeof value if (i === 'parent' && type === 'object') { if (parent) cloned[i] = parent } else if (i === 'source') { cloned[i] = value } else if (Array.isArray(value)) { cloned[i] = value.map(j => cloneNode(j, cloned)) } else { if (type === 'object' && value !== null) value = cloneNode(value) cloned[i] = value } } return cloned } function sourceOffset(inputCSS, position) { // Not all custom syntaxes support `offset` in `source.start` and `source.end` if ( position && typeof position.offset !== 'undefined' ) { return position.offset; } let column = 1 let line = 1 let offset = 0 for (let i = 0; i < inputCSS.length; i++) { if (line === position.line && column === position.column) { offset = i break } if (inputCSS[i] === '\n') { column = 1 line += 1 } else { column += 1 } } return offset } class Node { constructor(defaults = {}) { this.raws = {} this[isClean] = false this[my] = true for (let name in defaults) { if (name === 'nodes') { this.nodes = [] for (let node of defaults[name]) { if (typeof node.clone === 'function') { this.append(node.clone()) } else { this.append(node) } } } else { this[name] = defaults[name] } } } addToError(error) { error.postcssNode = this if (error.stack && this.source && /\n\s{4}at /.test(error.stack)) { let s = this.source error.stack = error.stack.replace( /\n\s{4}at /, `$&${s.input.from}:${s.start.line}:${s.start.column}$&` ) } return error } after(add) { this.parent.insertAfter(this, add) return this } assign(overrides = {}) { for (let name in overrides) { this[name] = overrides[name] } return this } before(add) { this.parent.insertBefore(this, add) return this } cleanRaws(keepBetween) { delete this.raws.before delete this.raws.after if (!keepBetween) delete this.raws.between } clone(overrides = {}) { let cloned = cloneNode(this) for (let name in overrides) { cloned[name] = overrides[name] } return cloned } cloneAfter(overrides = {}) { let cloned = this.clone(overrides) this.parent.insertAfter(this, cloned) return cloned } cloneBefore(overrides = {}) { let cloned = this.clone(overrides) this.parent.insertBefore(this, cloned) return cloned } error(message, opts = {}) { if (this.source) { let { end, start } = this.rangeBy(opts) return this.source.input.error( message, { column: start.column, line: start.line }, { column: end.column, line: end.line }, opts ) } return new CssSyntaxError(message) } getProxyProcessor() { return { get(node, prop) { if (prop === 'proxyOf') { return node } else if (prop === 'root') { return () => node.root().toProxy() } else { return node[prop] } }, set(node, prop, value) { if (node[prop] === value) return true node[prop] = value if ( prop === 'prop' || prop === 'value' || prop === 'name' || prop === 'params' || prop === 'important' || /* c8 ignore next */ prop === 'text' ) { node.markDirty() } return true } } } /* c8 ignore next 3 */ markClean() { this[isClean] = true } markDirty() { if (this[isClean]) { this[isClean] = false let next = this while ((next = next.parent)) { next[isClean] = false } } } next() { if (!this.parent) return undefined let index = this.parent.index(this) return this.parent.nodes[index + 1] } positionBy(opts) { let pos = this.source.start if (opts.index) { pos = this.positionInside(opts.index) } else if (opts.word) { let stringRepresentation = this.source.input.css.slice( sourceOffset(this.source.input.css, this.source.start), sourceOffset(this.source.input.css, this.source.end) ) let index = stringRepresentation.indexOf(opts.word) if (index !== -1) pos = this.positionInside(index) } return pos } positionInside(index) { let column = this.source.start.column let line = this.source.start.line let offset = sourceOffset(this.source.input.css, this.source.start) let end = offset + index for (let i = offset; i < end; i++) { if (this.source.input.css[i] === '\n') { column = 1 line += 1 } else { column += 1 } } return { column, line } } prev() { if (!this.parent) return undefined let index = this.parent.index(this) return this.parent.nodes[index - 1] } rangeBy(opts) { let start = { column: this.source.start.column, line: this.source.start.line } let end = this.source.end ? { column: this.source.end.column + 1, line: this.source.end.line } : { column: start.column + 1, line: start.line } if (opts.word) { let stringRepresentation = this.source.input.css.slice( sourceOffset(this.source.input.css, this.source.start), sourceOffset(this.source.input.css, this.source.end) ) let index = stringRepresentation.indexOf(opts.word) if (index !== -1) { start = this.positionInside(index) end = this.positionInside( index + opts.word.length, ) } } else { if (opts.start) { start = { column: opts.start.column, line: opts.start.line } } else if (opts.index) { start = this.positionInside(opts.index) } if (opts.end) { end = { column: opts.end.column, line: opts.end.line } } else if (typeof opts.endIndex === 'number') { end = this.positionInside(opts.endIndex) } else if (opts.index) { end = this.positionInside(opts.index + 1) } } if ( end.line < start.line || (end.line === start.line && end.column <= start.column) ) { end = { column: start.column + 1, line: start.line } } return { end, start } } raw(prop, defaultType) { let str = new Stringifier() return str.raw(this, prop, defaultType) } remove() { if (this.parent) { this.parent.removeChild(this) } this.parent = undefined return this } replaceWith(...nodes) { if (this.parent) { let bookmark = this let foundSelf = false for (let node of nodes) { if (node === this) { foundSelf = true } else if (foundSelf) { this.parent.insertAfter(bookmark, node) bookmark = node } else { this.parent.insertBefore(bookmark, node) } } if (!foundSelf) { this.remove() } } return this } root() { let result = this while (result.parent && result.parent.type !== 'document') { result = result.parent } return result } toJSON(_, inputs) { let fixed = {} let emitInputs = inputs == null inputs = inputs || new Map() let inputsNextIndex = 0 for (let name in this) { if (!Object.prototype.hasOwnProperty.call(this, name)) { /* c8 ignore next 2 */ continue } if (name === 'parent' || name === 'proxyCache') continue let value = this[name] if (Array.isArray(value)) { fixed[name] = value.map(i => { if (typeof i === 'object' && i.toJSON) { return i.toJSON(null, inputs) } else { return i } }) } else if (typeof value === 'object' && value.toJSON) { fixed[name] = value.toJSON(null, inputs) } else if (name === 'source') { let inputId = inputs.get(value.input) if (inputId == null) { inputId = inputsNextIndex inputs.set(value.input, inputsNextIndex) inputsNextIndex++ } fixed[name] = { end: value.end, inputId, start: value.start } } else { fixed[name] = value } } if (emitInputs) { fixed.inputs = [...inputs.keys()].map(input => input.toJSON()) } return fixed } toProxy() { if (!this.proxyCache) { this.proxyCache = new Proxy(this, this.getProxyProcessor()) } return this.proxyCache } toString(stringifier = stringify) { if (stringifier.stringify) stringifier = stringifier.stringify let result = '' stringifier(this, i => { result += i }) return result } warn(result, text, opts) { let data = { node: this } for (let i in opts) data[i] = opts[i] return result.warn(text, data) } get proxyOf() { return this } } module.exports = Node Node.default = Node postcss-8.4.49/lib/parse.d.ts000066400000000000000000000002071471446070100157730ustar00rootroot00000000000000import { Parser } from './postcss.js' interface Parse extends Parser { default: Parse } declare const parse: Parse export = parse postcss-8.4.49/lib/parse.js000066400000000000000000000021731471446070100155430ustar00rootroot00000000000000'use strict' let Container = require('./container') let Input = require('./input') let Parser = require('./parser') function parse(css, opts) { let input = new Input(css, opts) let parser = new Parser(input) try { parser.parse() } catch (e) { if (process.env.NODE_ENV !== 'production') { if (e.name === 'CssSyntaxError' && opts && opts.from) { if (/\.scss$/i.test(opts.from)) { e.message += '\nYou tried to parse SCSS with ' + 'the standard CSS parser; ' + 'try again with the postcss-scss parser' } else if (/\.sass/i.test(opts.from)) { e.message += '\nYou tried to parse Sass with ' + 'the standard CSS parser; ' + 'try again with the postcss-sass parser' } else if (/\.less$/i.test(opts.from)) { e.message += '\nYou tried to parse Less with ' + 'the standard CSS parser; ' + 'try again with the postcss-less parser' } } } throw e } return parser.root } module.exports = parse parse.default = parse Container.registerParse(parse) postcss-8.4.49/lib/parser.js000066400000000000000000000345771471446070100157420ustar00rootroot00000000000000'use strict' let AtRule = require('./at-rule') let Comment = require('./comment') let Declaration = require('./declaration') let Root = require('./root') let Rule = require('./rule') let tokenizer = require('./tokenize') const SAFE_COMMENT_NEIGHBOR = { empty: true, space: true } function findLastWithPosition(tokens) { for (let i = tokens.length - 1; i >= 0; i--) { let token = tokens[i] let pos = token[3] || token[2] if (pos) return pos } } class Parser { constructor(input) { this.input = input this.root = new Root() this.current = this.root this.spaces = '' this.semicolon = false this.createTokenizer() this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } } atrule(token) { let node = new AtRule() node.name = token[1].slice(1) if (node.name === '') { this.unnamedAtrule(node, token) } this.init(node, token[2]) let type let prev let shift let last = false let open = false let params = [] let brackets = [] while (!this.tokenizer.endOfFile()) { token = this.tokenizer.nextToken() type = token[0] if (type === '(' || type === '[') { brackets.push(type === '(' ? ')' : ']') } else if (type === '{' && brackets.length > 0) { brackets.push('}') } else if (type === brackets[brackets.length - 1]) { brackets.pop() } if (brackets.length === 0) { if (type === ';') { node.source.end = this.getPosition(token[2]) node.source.end.offset++ this.semicolon = true break } else if (type === '{') { open = true break } else if (type === '}') { if (params.length > 0) { shift = params.length - 1 prev = params[shift] while (prev && prev[0] === 'space') { prev = params[--shift] } if (prev) { node.source.end = this.getPosition(prev[3] || prev[2]) node.source.end.offset++ } } this.end(token) break } else { params.push(token) } } else { params.push(token) } if (this.tokenizer.endOfFile()) { last = true break } } node.raws.between = this.spacesAndCommentsFromEnd(params) if (params.length) { node.raws.afterName = this.spacesAndCommentsFromStart(params) this.raw(node, 'params', params) if (last) { token = params[params.length - 1] node.source.end = this.getPosition(token[3] || token[2]) node.source.end.offset++ this.spaces = node.raws.between node.raws.between = '' } } else { node.raws.afterName = '' node.params = '' } if (open) { node.nodes = [] this.current = node } } checkMissedSemicolon(tokens) { let colon = this.colon(tokens) if (colon === false) return let founded = 0 let token for (let j = colon - 1; j >= 0; j--) { token = tokens[j] if (token[0] !== 'space') { founded += 1 if (founded === 2) break } } // If the token is a word, e.g. `!important`, `red` or any other valid property's value. // Then we need to return the colon after that word token. [3] is the "end" colon of that word. // And because we need it after that one we do +1 to get the next one. throw this.input.error( 'Missed semicolon', token[0] === 'word' ? token[3] + 1 : token[2] ) } colon(tokens) { let brackets = 0 let prev, token, type for (let [i, element] of tokens.entries()) { token = element type = token[0] if (type === '(') { brackets += 1 } if (type === ')') { brackets -= 1 } if (brackets === 0 && type === ':') { if (!prev) { this.doubleColon(token) } else if (prev[0] === 'word' && prev[1] === 'progid') { continue } else { return i } } prev = token } return false } comment(token) { let node = new Comment() this.init(node, token[2]) node.source.end = this.getPosition(token[3] || token[2]) node.source.end.offset++ let text = token[1].slice(2, -2) if (/^\s*$/.test(text)) { node.text = '' node.raws.left = text node.raws.right = '' } else { let match = text.match(/^(\s*)([^]*\S)(\s*)$/) node.text = match[2] node.raws.left = match[1] node.raws.right = match[3] } } createTokenizer() { this.tokenizer = tokenizer(this.input) } decl(tokens, customProperty) { let node = new Declaration() this.init(node, tokens[0][2]) let last = tokens[tokens.length - 1] if (last[0] === ';') { this.semicolon = true tokens.pop() } node.source.end = this.getPosition( last[3] || last[2] || findLastWithPosition(tokens) ) node.source.end.offset++ while (tokens[0][0] !== 'word') { if (tokens.length === 1) this.unknownWord(tokens) node.raws.before += tokens.shift()[1] } node.source.start = this.getPosition(tokens[0][2]) node.prop = '' while (tokens.length) { let type = tokens[0][0] if (type === ':' || type === 'space' || type === 'comment') { break } node.prop += tokens.shift()[1] } node.raws.between = '' let token while (tokens.length) { token = tokens.shift() if (token[0] === ':') { node.raws.between += token[1] break } else { if (token[0] === 'word' && /\w/.test(token[1])) { this.unknownWord([token]) } node.raws.between += token[1] } } if (node.prop[0] === '_' || node.prop[0] === '*') { node.raws.before += node.prop[0] node.prop = node.prop.slice(1) } let firstSpaces = [] let next while (tokens.length) { next = tokens[0][0] if (next !== 'space' && next !== 'comment') break firstSpaces.push(tokens.shift()) } this.precheckMissedSemicolon(tokens) for (let i = tokens.length - 1; i >= 0; i--) { token = tokens[i] if (token[1].toLowerCase() === '!important') { node.important = true let string = this.stringFrom(tokens, i) string = this.spacesFromEnd(tokens) + string if (string !== ' !important') node.raws.important = string break } else if (token[1].toLowerCase() === 'important') { let cache = tokens.slice(0) let str = '' for (let j = i; j > 0; j--) { let type = cache[j][0] if (str.trim().startsWith('!') && type !== 'space') { break } str = cache.pop()[1] + str } if (str.trim().startsWith('!')) { node.important = true node.raws.important = str tokens = cache } } if (token[0] !== 'space' && token[0] !== 'comment') { break } } let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') if (hasWord) { node.raws.between += firstSpaces.map(i => i[1]).join('') firstSpaces = [] } this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) if (node.value.includes(':') && !customProperty) { this.checkMissedSemicolon(tokens) } } doubleColon(token) { throw this.input.error( 'Double colon', { offset: token[2] }, { offset: token[2] + token[1].length } ) } emptyRule(token) { let node = new Rule() this.init(node, token[2]) node.selector = '' node.raws.between = '' this.current = node } end(token) { if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon } this.semicolon = false this.current.raws.after = (this.current.raws.after || '') + this.spaces this.spaces = '' if (this.current.parent) { this.current.source.end = this.getPosition(token[2]) this.current.source.end.offset++ this.current = this.current.parent } else { this.unexpectedClose(token) } } endFile() { if (this.current.parent) this.unclosedBlock() if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon } this.current.raws.after = (this.current.raws.after || '') + this.spaces this.root.source.end = this.getPosition(this.tokenizer.position()) } freeSemicolon(token) { this.spaces += token[1] if (this.current.nodes) { let prev = this.current.nodes[this.current.nodes.length - 1] if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) { prev.raws.ownSemicolon = this.spaces this.spaces = '' } } } // Helpers getPosition(offset) { let pos = this.input.fromOffset(offset) return { column: pos.col, line: pos.line, offset } } init(node, offset) { this.current.push(node) node.source = { input: this.input, start: this.getPosition(offset) } node.raws.before = this.spaces this.spaces = '' if (node.type !== 'comment') this.semicolon = false } other(start) { let end = false let type = null let colon = false let bracket = null let brackets = [] let customProperty = start[1].startsWith('--') let tokens = [] let token = start while (token) { type = token[0] tokens.push(token) if (type === '(' || type === '[') { if (!bracket) bracket = token brackets.push(type === '(' ? ')' : ']') } else if (customProperty && colon && type === '{') { if (!bracket) bracket = token brackets.push('}') } else if (brackets.length === 0) { if (type === ';') { if (colon) { this.decl(tokens, customProperty) return } else { break } } else if (type === '{') { this.rule(tokens) return } else if (type === '}') { this.tokenizer.back(tokens.pop()) end = true break } else if (type === ':') { colon = true } } else if (type === brackets[brackets.length - 1]) { brackets.pop() if (brackets.length === 0) bracket = null } token = this.tokenizer.nextToken() } if (this.tokenizer.endOfFile()) end = true if (brackets.length > 0) this.unclosedBracket(bracket) if (end && colon) { if (!customProperty) { while (tokens.length) { token = tokens[tokens.length - 1][0] if (token !== 'space' && token !== 'comment') break this.tokenizer.back(tokens.pop()) } } this.decl(tokens, customProperty) } else { this.unknownWord(tokens) } } parse() { let token while (!this.tokenizer.endOfFile()) { token = this.tokenizer.nextToken() switch (token[0]) { case 'space': this.spaces += token[1] break case ';': this.freeSemicolon(token) break case '}': this.end(token) break case 'comment': this.comment(token) break case 'at-word': this.atrule(token) break case '{': this.emptyRule(token) break default: this.other(token) break } } this.endFile() } precheckMissedSemicolon(/* tokens */) { // Hook for Safe Parser } raw(node, prop, tokens, customProperty) { let token, type let length = tokens.length let value = '' let clean = true let next, prev for (let i = 0; i < length; i += 1) { token = tokens[i] type = token[0] if (type === 'space' && i === length - 1 && !customProperty) { clean = false } else if (type === 'comment') { prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty' next = tokens[i + 1] ? tokens[i + 1][0] : 'empty' if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) { if (value.slice(-1) === ',') { clean = false } else { value += token[1] } } else { clean = false } } else { value += token[1] } } if (!clean) { let raw = tokens.reduce((all, i) => all + i[1], '') node.raws[prop] = { raw, value } } node[prop] = value } rule(tokens) { tokens.pop() let node = new Rule() this.init(node, tokens[0][2]) node.raws.between = this.spacesAndCommentsFromEnd(tokens) this.raw(node, 'selector', tokens) this.current = node } spacesAndCommentsFromEnd(tokens) { let lastTokenType let spaces = '' while (tokens.length) { lastTokenType = tokens[tokens.length - 1][0] if (lastTokenType !== 'space' && lastTokenType !== 'comment') break spaces = tokens.pop()[1] + spaces } return spaces } // Errors spacesAndCommentsFromStart(tokens) { let next let spaces = '' while (tokens.length) { next = tokens[0][0] if (next !== 'space' && next !== 'comment') break spaces += tokens.shift()[1] } return spaces } spacesFromEnd(tokens) { let lastTokenType let spaces = '' while (tokens.length) { lastTokenType = tokens[tokens.length - 1][0] if (lastTokenType !== 'space') break spaces = tokens.pop()[1] + spaces } return spaces } stringFrom(tokens, from) { let result = '' for (let i = from; i < tokens.length; i++) { result += tokens[i][1] } tokens.splice(from, tokens.length - from) return result } unclosedBlock() { let pos = this.current.source.start throw this.input.error('Unclosed block', pos.line, pos.column) } unclosedBracket(bracket) { throw this.input.error( 'Unclosed bracket', { offset: bracket[2] }, { offset: bracket[2] + 1 } ) } unexpectedClose(token) { throw this.input.error( 'Unexpected }', { offset: token[2] }, { offset: token[2] + 1 } ) } unknownWord(tokens) { throw this.input.error( 'Unknown word', { offset: tokens[0][2] }, { offset: tokens[0][2] + tokens[0][1].length } ) } unnamedAtrule(node, token) { throw this.input.error( 'At-rule without name', { offset: token[2] }, { offset: token[2] + token[1].length } ) } } module.exports = Parser postcss-8.4.49/lib/postcss.d.mts000066400000000000000000000020311471446070100165310ustar00rootroot00000000000000export { // postcss function / namespace default, // Value exports from postcss.mjs stringify, fromJSON, // @ts-expect-error This value exists, but it’s untyped. plugin, parse, list, document, comment, atRule, rule, decl, root, CssSyntaxError, Declaration, Container, Processor, Document, Comment, Warning, AtRule, Result, Input, Rule, Root, Node, // Type-only exports AcceptedPlugin, AnyNode, AtRuleProps, Builder, ChildNode, ChildProps, CommentProps, ContainerProps, DeclarationProps, DocumentProps, FilePosition, Helpers, JSONHydrator, Message, NodeErrorOptions, NodeProps, OldPlugin, Parser, Plugin, PluginCreator, Position, Postcss, ProcessOptions, RootProps, RuleProps, Source, SourceMap, SourceMapOptions, Stringifier, Syntax, TransformCallback, Transformer, WarningOptions, // This is a class, but it’s not re-exported. That’s why it’s exported as type-only here. type LazyResult } from './postcss.js' postcss-8.4.49/lib/postcss.d.ts000066400000000000000000000260561471446070100163710ustar00rootroot00000000000000import { RawSourceMap, SourceMapGenerator } from 'source-map-js' import AtRule, { AtRuleProps } from './at-rule.js' import Comment, { CommentProps } from './comment.js' import Container, { ContainerProps, NewChild } from './container.js' import CssSyntaxError from './css-syntax-error.js' import Declaration, { DeclarationProps } from './declaration.js' import Document, { DocumentProps } from './document.js' import Input, { FilePosition } from './input.js' import LazyResult from './lazy-result.js' import list from './list.js' import Node, { AnyNode, ChildNode, ChildProps, NodeErrorOptions, NodeProps, Position, Source } from './node.js' import Processor from './processor.js' import Result, { Message } from './result.js' import Root, { RootProps } from './root.js' import Rule, { RuleProps } from './rule.js' import Warning, { WarningOptions } from './warning.js' type DocumentProcessor = ( document: Document, helper: postcss.Helpers ) => Promise | void type RootProcessor = ( root: Root, helper: postcss.Helpers ) => Promise | void type DeclarationProcessor = ( decl: Declaration, helper: postcss.Helpers ) => Promise | void type RuleProcessor = ( rule: Rule, helper: postcss.Helpers ) => Promise | void type AtRuleProcessor = ( atRule: AtRule, helper: postcss.Helpers ) => Promise | void type CommentProcessor = ( comment: Comment, helper: postcss.Helpers ) => Promise | void interface Processors { /** * Will be called on all`AtRule` nodes. * * Will be called again on node or children changes. */ AtRule?: { [name: string]: AtRuleProcessor } | AtRuleProcessor /** * Will be called on all `AtRule` nodes, when all children will be processed. * * Will be called again on node or children changes. */ AtRuleExit?: { [name: string]: AtRuleProcessor } | AtRuleProcessor /** * Will be called on all `Comment` nodes. * * Will be called again on node or children changes. */ Comment?: CommentProcessor /** * Will be called on all `Comment` nodes after listeners * for `Comment` event. * * Will be called again on node or children changes. */ CommentExit?: CommentProcessor /** * Will be called on all `Declaration` nodes after listeners * for `Declaration` event. * * Will be called again on node or children changes. */ Declaration?: { [prop: string]: DeclarationProcessor } | DeclarationProcessor /** * Will be called on all `Declaration` nodes. * * Will be called again on node or children changes. */ DeclarationExit?: | { [prop: string]: DeclarationProcessor } | DeclarationProcessor /** * Will be called on `Document` node. * * Will be called again on children changes. */ Document?: DocumentProcessor /** * Will be called on `Document` node, when all children will be processed. * * Will be called again on children changes. */ DocumentExit?: DocumentProcessor /** * Will be called on `Root` node once. */ Once?: RootProcessor /** * Will be called on `Root` node once, when all children will be processed. */ OnceExit?: RootProcessor /** * Will be called on `Root` node. * * Will be called again on children changes. */ Root?: RootProcessor /** * Will be called on `Root` node, when all children will be processed. * * Will be called again on children changes. */ RootExit?: RootProcessor /** * Will be called on all `Rule` nodes. * * Will be called again on node or children changes. */ Rule?: RuleProcessor /** * Will be called on all `Rule` nodes, when all children will be processed. * * Will be called again on node or children changes. */ RuleExit?: RuleProcessor } declare namespace postcss { export { AnyNode, AtRule, AtRuleProps, ChildNode, ChildProps, Comment, CommentProps, Container, ContainerProps, CssSyntaxError, Declaration, DeclarationProps, Document, DocumentProps, FilePosition, Input, LazyResult, list, Message, NewChild, Node, NodeErrorOptions, NodeProps, Position, Processor, Result, Root, RootProps, Rule, RuleProps, Source, Warning, WarningOptions } export type SourceMap = { toJSON(): RawSourceMap } & SourceMapGenerator export type Helpers = { postcss: Postcss; result: Result } & Postcss export interface Plugin extends Processors { postcssPlugin: string prepare?: (result: Result) => Processors } export interface PluginCreator { (opts?: PluginOptions): Plugin | Processor postcss: true } export interface Transformer extends TransformCallback { postcssPlugin: string postcssVersion: string } export interface TransformCallback { (root: Root, result: Result): Promise | void } export interface OldPlugin extends Transformer { (opts?: T): Transformer postcss: Transformer } export type AcceptedPlugin = | { postcss: Processor | TransformCallback } | OldPlugin | Plugin | PluginCreator | Processor | TransformCallback export interface Parser { ( css: { toString(): string } | string, opts?: Pick ): RootNode } export interface Builder { (part: string, node?: AnyNode, type?: 'end' | 'start'): void } export interface Stringifier { (node: AnyNode, builder: Builder): void } export interface JSONHydrator { (data: object): Node (data: object[]): Node[] } export interface Syntax { /** * Function to generate AST by string. */ parse?: Parser /** * Class to generate string by AST. */ stringify?: Stringifier } export interface SourceMapOptions { /** * Use absolute path in generated source map. */ absolute?: boolean /** * Indicates that PostCSS should add annotation comments to the CSS. * By default, PostCSS will always add a comment with a path * to the source map. PostCSS will not add annotations to CSS files * that do not contain any comments. * * By default, PostCSS presumes that you want to save the source map as * `opts.to + '.map'` and will use this path in the annotation comment. * A different path can be set by providing a string value for annotation. * * If you have set `inline: true`, annotation cannot be disabled. */ annotation?: ((file: string, root: Root) => string) | boolean | string /** * Override `from` in map’s sources. */ from?: string /** * Indicates that the source map should be embedded in the output CSS * as a Base64-encoded comment. By default, it is `true`. * But if all previous maps are external, not inline, PostCSS will not embed * the map even if you do not set this option. * * If you have an inline source map, the result.map property will be empty, * as the source map will be contained within the text of `result.css`. */ inline?: boolean /** * Source map content from a previous processing step (e.g., Sass). * * PostCSS will try to read the previous source map * automatically (based on comments within the source CSS), but you can use * this option to identify it manually. * * If desired, you can omit the previous map with prev: `false`. */ prev?: ((file: string) => string) | boolean | object | string /** * Indicates that PostCSS should set the origin content (e.g., Sass source) * of the source map. By default, it is true. But if all previous maps do not * contain sources content, PostCSS will also leave it out even if you * do not set this option. */ sourcesContent?: boolean } export interface ProcessOptions { /** * The path of the CSS source file. You should always set `from`, * because it is used in source map generation and syntax error messages. */ from?: string | undefined /** * Source map options */ map?: boolean | SourceMapOptions /** * Function to generate AST by string. */ parser?: Parser | Syntax /** * Class to generate string by AST. */ stringifier?: Stringifier | Syntax /** * Object with parse and stringify. */ syntax?: Syntax /** * The path where you'll put the output CSS file. You should always set `to` * to generate correct source maps. */ to?: string } export type Postcss = typeof postcss /** * Default function to convert a node tree into a CSS string. */ export let stringify: Stringifier /** * Parses source css and returns a new `Root` or `Document` node, * which contains the source CSS nodes. * * ```js * // Simple CSS concatenation with source map support * const root1 = postcss.parse(css1, { from: file1 }) * const root2 = postcss.parse(css2, { from: file2 }) * root1.append(root2).toResult().css * ``` */ export let parse: Parser /** * Rehydrate a JSON AST (from `Node#toJSON`) back into the AST classes. * * ```js * const json = root.toJSON() * // save to file, send by network, etc * const root2 = postcss.fromJSON(json) * ``` */ export let fromJSON: JSONHydrator /** * Creates a new `Comment` node. * * @param defaults Properties for the new node. * @return New comment node */ export function comment(defaults?: CommentProps): Comment /** * Creates a new `AtRule` node. * * @param defaults Properties for the new node. * @return New at-rule node. */ export function atRule(defaults?: AtRuleProps): AtRule /** * Creates a new `Declaration` node. * * @param defaults Properties for the new node. * @return New declaration node. */ export function decl(defaults?: DeclarationProps): Declaration /** * Creates a new `Rule` node. * * @param default Properties for the new node. * @return New rule node. */ export function rule(defaults?: RuleProps): Rule /** * Creates a new `Root` node. * * @param defaults Properties for the new node. * @return New root node. */ export function root(defaults?: RootProps): Root /** * Creates a new `Document` node. * * @param defaults Properties for the new node. * @return New document node. */ export function document(defaults?: DocumentProps): Document export { postcss as default } } /** * Create a new `Processor` instance that will apply `plugins` * as CSS processors. * * ```js * let postcss = require('postcss') * * postcss(plugins).process(css, { from, to }).then(result => { * console.log(result.css) * }) * ``` * * @param plugins PostCSS plugins. * @return Processor to process multiple CSS. */ declare function postcss( plugins?: readonly postcss.AcceptedPlugin[] ): Processor declare function postcss(...plugins: postcss.AcceptedPlugin[]): Processor export = postcss postcss-8.4.49/lib/postcss.js000066400000000000000000000055221471446070100161300ustar00rootroot00000000000000'use strict' let AtRule = require('./at-rule') let Comment = require('./comment') let Container = require('./container') let CssSyntaxError = require('./css-syntax-error') let Declaration = require('./declaration') let Document = require('./document') let fromJSON = require('./fromJSON') let Input = require('./input') let LazyResult = require('./lazy-result') let list = require('./list') let Node = require('./node') let parse = require('./parse') let Processor = require('./processor') let Result = require('./result.js') let Root = require('./root') let Rule = require('./rule') let stringify = require('./stringify') let Warning = require('./warning') function postcss(...plugins) { if (plugins.length === 1 && Array.isArray(plugins[0])) { plugins = plugins[0] } return new Processor(plugins) } postcss.plugin = function plugin(name, initializer) { let warningPrinted = false function creator(...args) { // eslint-disable-next-line no-console if (console && console.warn && !warningPrinted) { warningPrinted = true // eslint-disable-next-line no-console console.warn( name + ': postcss.plugin was deprecated. Migration guide:\n' + 'https://evilmartians.com/chronicles/postcss-8-plugin-migration' ) if (process.env.LANG && process.env.LANG.startsWith('cn')) { /* c8 ignore next 7 */ // eslint-disable-next-line no-console console.warn( name + ': 里面 postcss.plugin 被弃用. 迁移指南:\n' + 'https://www.w3ctech.com/topic/2226' ) } } let transformer = initializer(...args) transformer.postcssPlugin = name transformer.postcssVersion = new Processor().version return transformer } let cache Object.defineProperty(creator, 'postcss', { get() { if (!cache) cache = creator() return cache } }) creator.process = function (css, processOpts, pluginOpts) { return postcss([creator(pluginOpts)]).process(css, processOpts) } return creator } postcss.stringify = stringify postcss.parse = parse postcss.fromJSON = fromJSON postcss.list = list postcss.comment = defaults => new Comment(defaults) postcss.atRule = defaults => new AtRule(defaults) postcss.decl = defaults => new Declaration(defaults) postcss.rule = defaults => new Rule(defaults) postcss.root = defaults => new Root(defaults) postcss.document = defaults => new Document(defaults) postcss.CssSyntaxError = CssSyntaxError postcss.Declaration = Declaration postcss.Container = Container postcss.Processor = Processor postcss.Document = Document postcss.Comment = Comment postcss.Warning = Warning postcss.AtRule = AtRule postcss.Result = Result postcss.Input = Input postcss.Rule = Rule postcss.Root = Root postcss.Node = Node LazyResult.registerPostcss(postcss) module.exports = postcss postcss.default = postcss postcss-8.4.49/lib/postcss.mjs000066400000000000000000000017241471446070100163050ustar00rootroot00000000000000import postcss from './postcss.js' export default postcss export const stringify = postcss.stringify export const fromJSON = postcss.fromJSON export const plugin = postcss.plugin export const parse = postcss.parse export const list = postcss.list export const document = postcss.document export const comment = postcss.comment export const atRule = postcss.atRule export const rule = postcss.rule export const decl = postcss.decl export const root = postcss.root export const CssSyntaxError = postcss.CssSyntaxError export const Declaration = postcss.Declaration export const Container = postcss.Container export const Processor = postcss.Processor export const Document = postcss.Document export const Comment = postcss.Comment export const Warning = postcss.Warning export const AtRule = postcss.AtRule export const Result = postcss.Result export const Input = postcss.Input export const Rule = postcss.Rule export const Root = postcss.Root export const Node = postcss.Node postcss-8.4.49/lib/previous-map.d.ts000066400000000000000000000034431471446070100173150ustar00rootroot00000000000000import { SourceMapConsumer } from 'source-map-js' import { ProcessOptions } from './postcss.js' declare namespace PreviousMap { // eslint-disable-next-line @typescript-eslint/no-use-before-define export { PreviousMap_ as default } } /** * Source map information from input CSS. * For example, source map after Sass compiler. * * This class will automatically find source map in input CSS or in file system * near input file (according `from` option). * * ```js * const root = parse(css, { from: 'a.sass.css' }) * root.input.map //=> PreviousMap * ``` */ declare class PreviousMap_ { /** * `sourceMappingURL` content. */ annotation?: string /** * The CSS source identifier. Contains `Input#file` if the user * set the `from` option, or `Input#id` if they did not. */ file?: string /** * Was source map inlined by data-uri to input CSS. */ inline: boolean /** * Path to source map file. */ mapFile?: string /** * The directory with source map file, if source map is in separated file. */ root?: string /** * Source map file content. */ text?: string /** * @param css Input CSS source. * @param opts Process options. */ constructor(css: string, opts?: ProcessOptions) /** * Create a instance of `SourceMapGenerator` class * from the `source-map` library to work with source map information. * * It is lazy method, so it will create object only on first call * and then it will use cache. * * @return Object with source map information. */ consumer(): SourceMapConsumer /** * Does source map contains `sourcesContent` with input source text. * * @return Is `sourcesContent` present. */ withContent(): boolean } declare class PreviousMap extends PreviousMap_ {} export = PreviousMap postcss-8.4.49/lib/previous-map.js000066400000000000000000000076201471446070100170620ustar00rootroot00000000000000'use strict' let { existsSync, readFileSync } = require('fs') let { dirname, join } = require('path') let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') function fromBase64(str) { if (Buffer) { return Buffer.from(str, 'base64').toString() } else { /* c8 ignore next 2 */ return window.atob(str) } } class PreviousMap { constructor(css, opts) { if (opts.map === false) return this.loadAnnotation(css) this.inline = this.startWith(this.annotation, 'data:') let prev = opts.map ? opts.map.prev : undefined let text = this.loadMap(opts.from, prev) if (!this.mapFile && opts.from) { this.mapFile = opts.from } if (this.mapFile) this.root = dirname(this.mapFile) if (text) this.text = text } consumer() { if (!this.consumerCache) { this.consumerCache = new SourceMapConsumer(this.text) } return this.consumerCache } decodeInline(text) { let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/ let baseUri = /^data:application\/json;base64,/ let charsetUri = /^data:application\/json;charset=utf-?8,/ let uri = /^data:application\/json,/ let uriMatch = text.match(charsetUri) || text.match(uri) if (uriMatch) { return decodeURIComponent(text.substr(uriMatch[0].length)) } let baseUriMatch = text.match(baseCharsetUri) || text.match(baseUri) if (baseUriMatch) { return fromBase64(text.substr(baseUriMatch[0].length)) } let encoding = text.match(/data:application\/json;([^,]+),/)[1] throw new Error('Unsupported source map encoding ' + encoding) } getAnnotationURL(sourceMapString) { return sourceMapString.replace(/^\/\*\s*# sourceMappingURL=/, '').trim() } isMap(map) { if (typeof map !== 'object') return false return ( typeof map.mappings === 'string' || typeof map._mappings === 'string' || Array.isArray(map.sections) ) } loadAnnotation(css) { let comments = css.match(/\/\*\s*# sourceMappingURL=/g) if (!comments) return // sourceMappingURLs from comments, strings, etc. let start = css.lastIndexOf(comments.pop()) let end = css.indexOf('*/', start) if (start > -1 && end > -1) { // Locate the last sourceMappingURL to avoid pickin this.annotation = this.getAnnotationURL(css.substring(start, end)) } } loadFile(path) { this.root = dirname(path) if (existsSync(path)) { this.mapFile = path return readFileSync(path, 'utf-8').toString().trim() } } loadMap(file, prev) { if (prev === false) return false if (prev) { if (typeof prev === 'string') { return prev } else if (typeof prev === 'function') { let prevPath = prev(file) if (prevPath) { let map = this.loadFile(prevPath) if (!map) { throw new Error( 'Unable to load previous source map: ' + prevPath.toString() ) } return map } } else if (prev instanceof SourceMapConsumer) { return SourceMapGenerator.fromSourceMap(prev).toString() } else if (prev instanceof SourceMapGenerator) { return prev.toString() } else if (this.isMap(prev)) { return JSON.stringify(prev) } else { throw new Error( 'Unsupported previous source map format: ' + prev.toString() ) } } else if (this.inline) { return this.decodeInline(this.annotation) } else if (this.annotation) { let map = this.annotation if (file) map = join(dirname(file), map) return this.loadFile(map) } } startWith(string, start) { if (!string) return false return string.substr(0, start.length) === start } withContent() { return !!( this.consumer().sourcesContent && this.consumer().sourcesContent.length > 0 ) } } module.exports = PreviousMap PreviousMap.default = PreviousMap postcss-8.4.49/lib/processor.d.ts000066400000000000000000000065271471446070100167130ustar00rootroot00000000000000import Document from './document.js' import LazyResult from './lazy-result.js' import NoWorkResult from './no-work-result.js' import { AcceptedPlugin, Plugin, ProcessOptions, TransformCallback, Transformer } from './postcss.js' import Result from './result.js' import Root from './root.js' declare namespace Processor { // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Processor_ as default } } /** * Contains plugins to process CSS. Create one `Processor` instance, * initialize its plugins, and then use that instance on numerous CSS files. * * ```js * const processor = postcss([autoprefixer, postcssNested]) * processor.process(css1).then(result => console.log(result.css)) * processor.process(css2).then(result => console.log(result.css)) * ``` */ declare class Processor_ { /** * Plugins added to this processor. * * ```js * const processor = postcss([autoprefixer, postcssNested]) * processor.plugins.length //=> 2 * ``` */ plugins: (Plugin | TransformCallback | Transformer)[] /** * Current PostCSS version. * * ```js * if (result.processor.version.split('.')[0] !== '6') { * throw new Error('This plugin works only with PostCSS 6') * } * ``` */ version: string /** * @param plugins PostCSS plugins */ constructor(plugins?: readonly AcceptedPlugin[]) /** * Parses source CSS and returns a `LazyResult` Promise proxy. * Because some plugins can be asynchronous it doesn’t make * any transformations. Transformations will be applied * in the `LazyResult` methods. * * ```js * processor.process(css, { from: 'a.css', to: 'a.out.css' }) * .then(result => { * console.log(result.css) * }) * ``` * * @param css String with input CSS or any object with a `toString()` method, * like a Buffer. Optionally, send a `Result` instance * and the processor will take the `Root` from it. * @param opts Options. * @return Promise proxy. */ process( css: { toString(): string } | LazyResult | Result | Root | string ): LazyResult | NoWorkResult process( css: { toString(): string } | LazyResult | Result | Root | string, options: ProcessOptions ): LazyResult /** * Adds a plugin to be used as a CSS processor. * * PostCSS plugin can be in 4 formats: * * A plugin in `Plugin` format. * * A plugin creator function with `pluginCreator.postcss = true`. * PostCSS will call this function without argument to get plugin. * * A function. PostCSS will pass the function a {@link Root} * as the first argument and current `Result` instance * as the second. * * Another `Processor` instance. PostCSS will copy plugins * from that instance into this one. * * Plugins can also be added by passing them as arguments when creating * a `postcss` instance (see [`postcss(plugins)`]). * * Asynchronous plugins should return a `Promise` instance. * * ```js * const processor = postcss() * .use(autoprefixer) * .use(postcssNested) * ``` * * @param plugin PostCSS plugin or `Processor` with plugins. * @return Current processor to make methods chain. */ use(plugin: AcceptedPlugin): this } declare class Processor extends Processor_ {} export = Processor postcss-8.4.49/lib/processor.js000066400000000000000000000033131471446070100164450ustar00rootroot00000000000000'use strict' let Document = require('./document') let LazyResult = require('./lazy-result') let NoWorkResult = require('./no-work-result') let Root = require('./root') class Processor { constructor(plugins = []) { this.version = '8.4.49' this.plugins = this.normalize(plugins) } normalize(plugins) { let normalized = [] for (let i of plugins) { if (i.postcss === true) { i = i() } else if (i.postcss) { i = i.postcss } if (typeof i === 'object' && Array.isArray(i.plugins)) { normalized = normalized.concat(i.plugins) } else if (typeof i === 'object' && i.postcssPlugin) { normalized.push(i) } else if (typeof i === 'function') { normalized.push(i) } else if (typeof i === 'object' && (i.parse || i.stringify)) { if (process.env.NODE_ENV !== 'production') { throw new Error( 'PostCSS syntaxes cannot be used as plugins. Instead, please use ' + 'one of the syntax/parser/stringifier options as outlined ' + 'in your PostCSS runner documentation.' ) } } else { throw new Error(i + ' is not a PostCSS plugin') } } return normalized } process(css, opts = {}) { if ( !this.plugins.length && !opts.parser && !opts.stringifier && !opts.syntax ) { return new NoWorkResult(this, css, opts) } else { return new LazyResult(this, css, opts) } } use(plugin) { this.plugins = this.plugins.concat(this.normalize([plugin])) return this } } module.exports = Processor Processor.default = Processor Root.registerProcessor(Processor) Document.registerProcessor(Processor) postcss-8.4.49/lib/result.d.ts000066400000000000000000000105001471446070100161740ustar00rootroot00000000000000import { Document, Node, Plugin, ProcessOptions, Root, SourceMap, TransformCallback, Warning, WarningOptions } from './postcss.js' import Processor from './processor.js' declare namespace Result { export interface Message { [others: string]: any /** * Source PostCSS plugin name. */ plugin?: string /** * Message type. */ type: string } export interface ResultOptions extends ProcessOptions { /** * The CSS node that was the source of the warning. */ node?: Node /** * Name of plugin that created this warning. `Result#warn` will fill it * automatically with `Plugin#postcssPlugin` value. */ plugin?: string } // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Result_ as default } } /** * Provides the result of the PostCSS transformations. * * A Result instance is returned by `LazyResult#then` * or `Root#toResult` methods. * * ```js * postcss([autoprefixer]).process(css).then(result => { * console.log(result.css) * }) * ``` * * ```js * const result2 = postcss.parse(css).toResult() * ``` */ declare class Result_ { /** * A CSS string representing of `Result#root`. * * ```js * postcss.parse('a{}').toResult().css //=> "a{}" * ``` */ css: string /** * Last runned PostCSS plugin. */ lastPlugin: Plugin | TransformCallback /** * An instance of `SourceMapGenerator` class from the `source-map` library, * representing changes to the `Result#root` instance. * * ```js * result.map.toJSON() //=> { version: 3, file: 'a.css', … } * ``` * * ```js * if (result.map) { * fs.writeFileSync(result.opts.to + '.map', result.map.toString()) * } * ``` */ map: SourceMap /** * Contains messages from plugins (e.g., warnings or custom messages). * Each message should have type and plugin properties. * * ```js * AtRule: { * import: (atRule, { result }) { * const importedFile = parseImport(atRule) * result.messages.push({ * type: 'dependency', * plugin: 'postcss-import', * file: importedFile, * parent: result.opts.from * }) * } * } * ``` */ messages: Result.Message[] /** * Options from the `Processor#process` or `Root#toResult` call * that produced this Result instance.] * * ```js * root.toResult(opts).opts === opts * ``` */ opts: Result.ResultOptions /** * The Processor instance used for this transformation. * * ```js * for (const plugin of result.processor.plugins) { * if (plugin.postcssPlugin === 'postcss-bad') { * throw 'postcss-good is incompatible with postcss-bad' * } * }) * ``` */ processor: Processor /** * Root node after all transformations. * * ```js * root.toResult().root === root * ``` */ root: RootNode /** * @param processor Processor used for this transformation. * @param root Root node after all transformations. * @param opts Options from the `Processor#process` or `Root#toResult`. */ constructor(processor: Processor, root: RootNode, opts: Result.ResultOptions) /** * Returns for `Result#css` content. * * ```js * result + '' === result.css * ``` * * @return String representing of `Result#root`. */ toString(): string /** * Creates an instance of `Warning` and adds it to `Result#messages`. * * ```js * if (decl.important) { * result.warn('Avoid !important', { node: decl, word: '!important' }) * } * ``` * * @param text Warning message. * @param opts Warning options. * @return Created warning. */ warn(message: string, options?: WarningOptions): Warning /** * Returns warnings from plugins. Filters `Warning` instances * from `Result#messages`. * * ```js * result.warnings().forEach(warn => { * console.warn(warn.toString()) * }) * ``` * * @return Warnings from plugins. */ warnings(): Warning[] /** * An alias for the `Result#css` property. * Use it with syntaxes that generate non-CSS output. * * ```js * result.css === result.content * ``` */ get content(): string } declare class Result extends Result_ {} export = Result postcss-8.4.49/lib/result.js000066400000000000000000000013511471446070100157440ustar00rootroot00000000000000'use strict' let Warning = require('./warning') class Result { constructor(processor, root, opts) { this.processor = processor this.messages = [] this.root = root this.opts = opts this.css = undefined this.map = undefined } toString() { return this.css } warn(text, opts = {}) { if (!opts.plugin) { if (this.lastPlugin && this.lastPlugin.postcssPlugin) { opts.plugin = this.lastPlugin.postcssPlugin } } let warning = new Warning(text, opts) this.messages.push(warning) return warning } warnings() { return this.messages.filter(i => i.type === 'warning') } get content() { return this.css } } module.exports = Result Result.default = Result postcss-8.4.49/lib/root.d.ts000066400000000000000000000044231471446070100156500ustar00rootroot00000000000000import Container, { ContainerProps } from './container.js' import Document from './document.js' import { ProcessOptions } from './postcss.js' import Result from './result.js' declare namespace Root { export interface RootRaws extends Record { /** * The space symbols after the last child to the end of file. */ after?: string /** * Non-CSS code after `Root`, when `Root` is inside `Document`. * * **Experimental:** some aspects of this node could change within minor * or patch version releases. */ codeAfter?: string /** * Non-CSS code before `Root`, when `Root` is inside `Document`. * * **Experimental:** some aspects of this node could change within minor * or patch version releases. */ codeBefore?: string /** * Is the last child has an (optional) semicolon. */ semicolon?: boolean } export interface RootProps extends ContainerProps { /** * Information used to generate byte-to-byte equal node string * as it was in the origin input. * */ raws?: RootRaws } // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Root_ as default } } /** * Represents a CSS file and contains all its parsed nodes. * * ```js * const root = postcss.parse('a{color:black} b{z-index:2}') * root.type //=> 'root' * root.nodes.length //=> 2 * ``` */ declare class Root_ extends Container { nodes: NonNullable parent: Document | undefined raws: Root.RootRaws type: 'root' constructor(defaults?: Root.RootProps) assign(overrides: object | Root.RootProps): this clone(overrides?: Partial): this cloneAfter(overrides?: Partial): this cloneBefore(overrides?: Partial): this /** * Returns a `Result` instance representing the root’s CSS. * * ```js * const root1 = postcss.parse(css1, { from: 'a.css' }) * const root2 = postcss.parse(css2, { from: 'b.css' }) * root1.append(root2) * const result = root1.toResult({ to: 'all.css', map: true }) * ``` * * @param options Options. * @return Result with current root’s CSS. */ toResult(options?: ProcessOptions): Result } declare class Root extends Root_ {} export = Root postcss-8.4.49/lib/root.js000066400000000000000000000023271471446070100154150ustar00rootroot00000000000000'use strict' let Container = require('./container') let LazyResult, Processor class Root extends Container { constructor(defaults) { super(defaults) this.type = 'root' if (!this.nodes) this.nodes = [] } normalize(child, sample, type) { let nodes = super.normalize(child) if (sample) { if (type === 'prepend') { if (this.nodes.length > 1) { sample.raws.before = this.nodes[1].raws.before } else { delete sample.raws.before } } else if (this.first !== sample) { for (let node of nodes) { node.raws.before = sample.raws.before } } } return nodes } removeChild(child, ignore) { let index = this.index(child) if (!ignore && index === 0 && this.nodes.length > 1) { this.nodes[1].raws.before = this.nodes[index].raws.before } return super.removeChild(child) } toResult(opts = {}) { let lazy = new LazyResult(new Processor(), this, opts) return lazy.stringify() } } Root.registerLazyResult = dependant => { LazyResult = dependant } Root.registerProcessor = dependant => { Processor = dependant } module.exports = Root Root.default = Root Container.registerRoot(Root) postcss-8.4.49/lib/rule.d.ts000066400000000000000000000056251471446070100156410ustar00rootroot00000000000000import Container, { ContainerProps, ContainerWithChildren } from './container.js' declare namespace Rule { export interface RuleRaws extends Record { /** * The space symbols after the last child of the node to the end of the node. */ after?: string /** * The space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). */ before?: string /** * The symbols between the selector and `{` for rules. */ between?: string /** * Contains `true` if there is semicolon after rule. */ ownSemicolon?: string /** * The rule’s selector with comments. */ selector?: { raw: string value: string } /** * Contains `true` if the last child has an (optional) semicolon. */ semicolon?: boolean } export type RuleProps = { /** Information used to generate byte-to-byte equal node string as it was in the origin input. */ raws?: RuleRaws } & ( | { /** Selector or selectors of the rule. */ selector: string selectors?: never } | { selector?: never /** Selectors of the rule represented as an array of strings. */ selectors: readonly string[] } ) & ContainerProps // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Rule_ as default } } /** * Represents a CSS rule: a selector followed by a declaration block. * * ```js * Once (root, { Rule }) { * let a = new Rule({ selector: 'a' }) * a.append(…) * root.append(a) * } * ``` * * ```js * const root = postcss.parse('a{}') * const rule = root.first * rule.type //=> 'rule' * rule.toString() //=> 'a{}' * ``` */ declare class Rule_ extends Container { nodes: NonNullable parent: ContainerWithChildren | undefined raws: Rule.RuleRaws type: 'rule' constructor(defaults?: Rule.RuleProps) assign(overrides: object | Rule.RuleProps): this clone(overrides?: Partial): this cloneAfter(overrides?: Partial): this cloneBefore(overrides?: Partial): this /** * The rule’s full selector represented as a string. * * ```js * const root = postcss.parse('a, b { }') * const rule = root.first * rule.selector //=> 'a, b' * ``` */ get selector(): string set selector(value: string) /** * An array containing the rule’s individual selectors. * Groups of selectors are split at commas. * * ```js * const root = postcss.parse('a, b { }') * const rule = root.first * * rule.selector //=> 'a, b' * rule.selectors //=> ['a', 'b'] * * rule.selectors = ['a', 'strong'] * rule.selector //=> 'a, strong' * ``` */ get selectors(): string[] set selectors(values: string[]) } declare class Rule extends Rule_ {} export = Rule postcss-8.4.49/lib/rule.js000066400000000000000000000010711471446070100153740ustar00rootroot00000000000000'use strict' let Container = require('./container') let list = require('./list') class Rule extends Container { constructor(defaults) { super(defaults) this.type = 'rule' if (!this.nodes) this.nodes = [] } get selectors() { return list.comma(this.selector) } set selectors(values) { let match = this.selector ? this.selector.match(/,\s*/) : null let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen') this.selector = values.join(sep) } } module.exports = Rule Rule.default = Rule Container.registerRule(Rule) postcss-8.4.49/lib/stringifier.d.ts000066400000000000000000000026031471446070100172100ustar00rootroot00000000000000import { AnyNode, AtRule, Builder, Comment, Container, Declaration, Document, Root, Rule } from './postcss.js' declare namespace Stringifier { // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Stringifier_ as default } } declare class Stringifier_ { builder: Builder constructor(builder: Builder) atrule(node: AtRule, semicolon?: boolean): void beforeAfter(node: AnyNode, detect: 'after' | 'before'): string block(node: AnyNode, start: string): void body(node: Container): void comment(node: Comment): void decl(node: Declaration, semicolon?: boolean): void document(node: Document): void raw(node: AnyNode, own: null | string, detect?: string): string rawBeforeClose(root: Root): string | undefined rawBeforeComment(root: Root, node: Comment): string | undefined rawBeforeDecl(root: Root, node: Declaration): string | undefined rawBeforeOpen(root: Root): string | undefined rawBeforeRule(root: Root): string | undefined rawColon(root: Root): string | undefined rawEmptyBody(root: Root): string | undefined rawIndent(root: Root): string | undefined rawSemicolon(root: Root): boolean | undefined rawValue(node: AnyNode, prop: string): string root(node: Root): void rule(node: Rule): void stringify(node: AnyNode, semicolon?: boolean): void } declare class Stringifier extends Stringifier_ {} export = Stringifier postcss-8.4.49/lib/stringifier.js000066400000000000000000000200341471446070100167520ustar00rootroot00000000000000'use strict' const DEFAULT_RAW = { after: '\n', beforeClose: '\n', beforeComment: '\n', beforeDecl: '\n', beforeOpen: ' ', beforeRule: '\n', colon: ': ', commentLeft: ' ', commentRight: ' ', emptyBody: '', indent: ' ', semicolon: false } function capitalize(str) { return str[0].toUpperCase() + str.slice(1) } class Stringifier { constructor(builder) { this.builder = builder } atrule(node, semicolon) { let name = '@' + node.name let params = node.params ? this.rawValue(node, 'params') : '' if (typeof node.raws.afterName !== 'undefined') { name += node.raws.afterName } else if (params) { name += ' ' } if (node.nodes) { this.block(node, name + params) } else { let end = (node.raws.between || '') + (semicolon ? ';' : '') this.builder(name + params + end, node) } } beforeAfter(node, detect) { let value if (node.type === 'decl') { value = this.raw(node, null, 'beforeDecl') } else if (node.type === 'comment') { value = this.raw(node, null, 'beforeComment') } else if (detect === 'before') { value = this.raw(node, null, 'beforeRule') } else { value = this.raw(node, null, 'beforeClose') } let buf = node.parent let depth = 0 while (buf && buf.type !== 'root') { depth += 1 buf = buf.parent } if (value.includes('\n')) { let indent = this.raw(node, null, 'indent') if (indent.length) { for (let step = 0; step < depth; step++) value += indent } } return value } block(node, start) { let between = this.raw(node, 'between', 'beforeOpen') this.builder(start + between + '{', node, 'start') let after if (node.nodes && node.nodes.length) { this.body(node) after = this.raw(node, 'after') } else { after = this.raw(node, 'after', 'emptyBody') } if (after) this.builder(after) this.builder('}', node, 'end') } body(node) { let last = node.nodes.length - 1 while (last > 0) { if (node.nodes[last].type !== 'comment') break last -= 1 } let semicolon = this.raw(node, 'semicolon') for (let i = 0; i < node.nodes.length; i++) { let child = node.nodes[i] let before = this.raw(child, 'before') if (before) this.builder(before) this.stringify(child, last !== i || semicolon) } } comment(node) { let left = this.raw(node, 'left', 'commentLeft') let right = this.raw(node, 'right', 'commentRight') this.builder('/*' + left + node.text + right + '*/', node) } decl(node, semicolon) { let between = this.raw(node, 'between', 'colon') let string = node.prop + between + this.rawValue(node, 'value') if (node.important) { string += node.raws.important || ' !important' } if (semicolon) string += ';' this.builder(string, node) } document(node) { this.body(node) } raw(node, own, detect) { let value if (!detect) detect = own // Already had if (own) { value = node.raws[own] if (typeof value !== 'undefined') return value } let parent = node.parent if (detect === 'before') { // Hack for first rule in CSS if (!parent || (parent.type === 'root' && parent.first === node)) { return '' } // `root` nodes in `document` should use only their own raws if (parent && parent.type === 'document') { return '' } } // Floating child without parent if (!parent) return DEFAULT_RAW[detect] // Detect style by other nodes let root = node.root() if (!root.rawCache) root.rawCache = {} if (typeof root.rawCache[detect] !== 'undefined') { return root.rawCache[detect] } if (detect === 'before' || detect === 'after') { return this.beforeAfter(node, detect) } else { let method = 'raw' + capitalize(detect) if (this[method]) { value = this[method](root, node) } else { root.walk(i => { value = i.raws[own] if (typeof value !== 'undefined') return false }) } } if (typeof value === 'undefined') value = DEFAULT_RAW[detect] root.rawCache[detect] = value return value } rawBeforeClose(root) { let value root.walk(i => { if (i.nodes && i.nodes.length > 0) { if (typeof i.raws.after !== 'undefined') { value = i.raws.after if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false } } }) if (value) value = value.replace(/\S/g, '') return value } rawBeforeComment(root, node) { let value root.walkComments(i => { if (typeof i.raws.before !== 'undefined') { value = i.raws.before if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false } }) if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeDecl') } else if (value) { value = value.replace(/\S/g, '') } return value } rawBeforeDecl(root, node) { let value root.walkDecls(i => { if (typeof i.raws.before !== 'undefined') { value = i.raws.before if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false } }) if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeRule') } else if (value) { value = value.replace(/\S/g, '') } return value } rawBeforeOpen(root) { let value root.walk(i => { if (i.type !== 'decl') { value = i.raws.between if (typeof value !== 'undefined') return false } }) return value } rawBeforeRule(root) { let value root.walk(i => { if (i.nodes && (i.parent !== root || root.first !== i)) { if (typeof i.raws.before !== 'undefined') { value = i.raws.before if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false } } }) if (value) value = value.replace(/\S/g, '') return value } rawColon(root) { let value root.walkDecls(i => { if (typeof i.raws.between !== 'undefined') { value = i.raws.between.replace(/[^\s:]/g, '') return false } }) return value } rawEmptyBody(root) { let value root.walk(i => { if (i.nodes && i.nodes.length === 0) { value = i.raws.after if (typeof value !== 'undefined') return false } }) return value } rawIndent(root) { if (root.raws.indent) return root.raws.indent let value root.walk(i => { let p = i.parent if (p && p !== root && p.parent && p.parent === root) { if (typeof i.raws.before !== 'undefined') { let parts = i.raws.before.split('\n') value = parts[parts.length - 1] value = value.replace(/\S/g, '') return false } } }) return value } rawSemicolon(root) { let value root.walk(i => { if (i.nodes && i.nodes.length && i.last.type === 'decl') { value = i.raws.semicolon if (typeof value !== 'undefined') return false } }) return value } rawValue(node, prop) { let value = node[prop] let raw = node.raws[prop] if (raw && raw.value === value) { return raw.raw } return value } root(node) { this.body(node) if (node.raws.after) this.builder(node.raws.after) } rule(node) { this.block(node, this.rawValue(node, 'selector')) if (node.raws.ownSemicolon) { this.builder(node.raws.ownSemicolon, node, 'end') } } stringify(node, semicolon) { /* c8 ignore start */ if (!this[node.type]) { throw new Error( 'Unknown AST node type ' + node.type + '. ' + 'Maybe you need to change PostCSS stringifier.' ) } /* c8 ignore stop */ this[node.type](node, semicolon) } } module.exports = Stringifier Stringifier.default = Stringifier postcss-8.4.49/lib/stringify.d.ts000066400000000000000000000002451471446070100167010ustar00rootroot00000000000000import { Stringifier } from './postcss.js' interface Stringify extends Stringifier { default: Stringify } declare const stringify: Stringify export = stringify postcss-8.4.49/lib/stringify.js000066400000000000000000000003251471446070100164440ustar00rootroot00000000000000'use strict' let Stringifier = require('./stringifier') function stringify(node, builder) { let str = new Stringifier(builder) str.stringify(node) } module.exports = stringify stringify.default = stringify postcss-8.4.49/lib/symbols.js000066400000000000000000000001331471446070100161130ustar00rootroot00000000000000'use strict' module.exports.isClean = Symbol('isClean') module.exports.my = Symbol('my') postcss-8.4.49/lib/terminal-highlight.js000066400000000000000000000025671471446070100202200ustar00rootroot00000000000000'use strict' let pico = require('picocolors') let tokenizer = require('./tokenize') let Input function registerInput(dependant) { Input = dependant } const HIGHLIGHT_THEME = { ';': pico.yellow, ':': pico.yellow, '(': pico.cyan, ')': pico.cyan, '[': pico.yellow, ']': pico.yellow, '{': pico.yellow, '}': pico.yellow, 'at-word': pico.cyan, 'brackets': pico.cyan, 'call': pico.cyan, 'class': pico.yellow, 'comment': pico.gray, 'hash': pico.magenta, 'string': pico.green } function getTokenType([type, value], processor) { if (type === 'word') { if (value[0] === '.') { return 'class' } if (value[0] === '#') { return 'hash' } } if (!processor.endOfFile()) { let next = processor.nextToken() processor.back(next) if (next[0] === 'brackets' || next[0] === '(') return 'call' } return type } function terminalHighlight(css) { let processor = tokenizer(new Input(css), { ignoreErrors: true }) let result = '' while (!processor.endOfFile()) { let token = processor.nextToken() let color = HIGHLIGHT_THEME[getTokenType(token, processor)] if (color) { result += token[1] .split(/\r?\n/) .map(i => color(i)) .join('\n') } else { result += token[1] } } return result } terminalHighlight.registerInput = registerInput module.exports = terminalHighlight postcss-8.4.49/lib/tokenize.js000066400000000000000000000146121471446070100162620ustar00rootroot00000000000000'use strict' const SINGLE_QUOTE = "'".charCodeAt(0) const DOUBLE_QUOTE = '"'.charCodeAt(0) const BACKSLASH = '\\'.charCodeAt(0) const SLASH = '/'.charCodeAt(0) const NEWLINE = '\n'.charCodeAt(0) const SPACE = ' '.charCodeAt(0) const FEED = '\f'.charCodeAt(0) const TAB = '\t'.charCodeAt(0) const CR = '\r'.charCodeAt(0) const OPEN_SQUARE = '['.charCodeAt(0) const CLOSE_SQUARE = ']'.charCodeAt(0) const OPEN_PARENTHESES = '('.charCodeAt(0) const CLOSE_PARENTHESES = ')'.charCodeAt(0) const OPEN_CURLY = '{'.charCodeAt(0) const CLOSE_CURLY = '}'.charCodeAt(0) const SEMICOLON = ';'.charCodeAt(0) const ASTERISK = '*'.charCodeAt(0) const COLON = ':'.charCodeAt(0) const AT = '@'.charCodeAt(0) const RE_AT_END = /[\t\n\f\r "#'()/;[\\\]{}]/g const RE_WORD_END = /[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g const RE_BAD_BRACKET = /.[\r\n"'(/\\]/ const RE_HEX_ESCAPE = /[\da-f]/i module.exports = function tokenizer(input, options = {}) { let css = input.css.valueOf() let ignore = options.ignoreErrors let code, content, escape, next, quote let currentToken, escaped, escapePos, n, prev let length = css.length let pos = 0 let buffer = [] let returned = [] function position() { return pos } function unclosed(what) { throw input.error('Unclosed ' + what, pos) } function endOfFile() { return returned.length === 0 && pos >= length } function nextToken(opts) { if (returned.length) return returned.pop() if (pos >= length) return let ignoreUnclosed = opts ? opts.ignoreUnclosed : false code = css.charCodeAt(pos) switch (code) { case NEWLINE: case SPACE: case TAB: case CR: case FEED: { next = pos do { next += 1 code = css.charCodeAt(next) } while ( code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED ) currentToken = ['space', css.slice(pos, next)] pos = next - 1 break } case OPEN_SQUARE: case CLOSE_SQUARE: case OPEN_CURLY: case CLOSE_CURLY: case COLON: case SEMICOLON: case CLOSE_PARENTHESES: { let controlChar = String.fromCharCode(code) currentToken = [controlChar, controlChar, pos] break } case OPEN_PARENTHESES: { prev = buffer.length ? buffer.pop()[1] : '' n = css.charCodeAt(pos + 1) if ( prev === 'url' && n !== SINGLE_QUOTE && n !== DOUBLE_QUOTE && n !== SPACE && n !== NEWLINE && n !== TAB && n !== FEED && n !== CR ) { next = pos do { escaped = false next = css.indexOf(')', next + 1) if (next === -1) { if (ignore || ignoreUnclosed) { next = pos break } else { unclosed('bracket') } } escapePos = next while (css.charCodeAt(escapePos - 1) === BACKSLASH) { escapePos -= 1 escaped = !escaped } } while (escaped) currentToken = ['brackets', css.slice(pos, next + 1), pos, next] pos = next } else { next = css.indexOf(')', pos + 1) content = css.slice(pos, next + 1) if (next === -1 || RE_BAD_BRACKET.test(content)) { currentToken = ['(', '(', pos] } else { currentToken = ['brackets', content, pos, next] pos = next } } break } case SINGLE_QUOTE: case DOUBLE_QUOTE: { quote = code === SINGLE_QUOTE ? "'" : '"' next = pos do { escaped = false next = css.indexOf(quote, next + 1) if (next === -1) { if (ignore || ignoreUnclosed) { next = pos + 1 break } else { unclosed('string') } } escapePos = next while (css.charCodeAt(escapePos - 1) === BACKSLASH) { escapePos -= 1 escaped = !escaped } } while (escaped) currentToken = ['string', css.slice(pos, next + 1), pos, next] pos = next break } case AT: { RE_AT_END.lastIndex = pos + 1 RE_AT_END.test(css) if (RE_AT_END.lastIndex === 0) { next = css.length - 1 } else { next = RE_AT_END.lastIndex - 2 } currentToken = ['at-word', css.slice(pos, next + 1), pos, next] pos = next break } case BACKSLASH: { next = pos escape = true while (css.charCodeAt(next + 1) === BACKSLASH) { next += 1 escape = !escape } code = css.charCodeAt(next + 1) if ( escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED ) { next += 1 if (RE_HEX_ESCAPE.test(css.charAt(next))) { while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) { next += 1 } if (css.charCodeAt(next + 1) === SPACE) { next += 1 } } } currentToken = ['word', css.slice(pos, next + 1), pos, next] pos = next break } default: { if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { next = css.indexOf('*/', pos + 2) + 1 if (next === 0) { if (ignore || ignoreUnclosed) { next = css.length } else { unclosed('comment') } } currentToken = ['comment', css.slice(pos, next + 1), pos, next] pos = next } else { RE_WORD_END.lastIndex = pos + 1 RE_WORD_END.test(css) if (RE_WORD_END.lastIndex === 0) { next = css.length - 1 } else { next = RE_WORD_END.lastIndex - 2 } currentToken = ['word', css.slice(pos, next + 1), pos, next] buffer.push(currentToken) pos = next } break } } pos++ return currentToken } function back(token) { returned.push(token) } return { back, endOfFile, nextToken, position } } postcss-8.4.49/lib/warn-once.js000066400000000000000000000004001471446070100163110ustar00rootroot00000000000000/* eslint-disable no-console */ 'use strict' let printed = {} module.exports = function warnOnce(message) { if (printed[message]) return printed[message] = true if (typeof console !== 'undefined' && console.warn) { console.warn(message) } } postcss-8.4.49/lib/warning.d.ts000066400000000000000000000056621471446070100163400ustar00rootroot00000000000000import { RangePosition } from './css-syntax-error.js' import Node from './node.js' declare namespace Warning { export interface WarningOptions { /** * End position, exclusive, in CSS node string that caused the warning. */ end?: RangePosition /** * End index, exclusive, in CSS node string that caused the warning. */ endIndex?: number /** * Start index, inclusive, in CSS node string that caused the warning. */ index?: number /** * CSS node that caused the warning. */ node?: Node /** * Name of the plugin that created this warning. `Result#warn` fills * this property automatically. */ plugin?: string /** * Start position, inclusive, in CSS node string that caused the warning. */ start?: RangePosition /** * Word in CSS source that caused the warning. */ word?: string } // eslint-disable-next-line @typescript-eslint/no-use-before-define export { Warning_ as default } } /** * Represents a plugin’s warning. It can be created using `Node#warn`. * * ```js * if (decl.important) { * decl.warn(result, 'Avoid !important', { word: '!important' }) * } * ``` */ declare class Warning_ { /** * Column for inclusive start position in the input file with this warning’s source. * * ```js * warning.column //=> 6 * ``` */ column: number /** * Column for exclusive end position in the input file with this warning’s source. * * ```js * warning.endColumn //=> 4 * ``` */ endColumn?: number /** * Line for exclusive end position in the input file with this warning’s source. * * ```js * warning.endLine //=> 6 * ``` */ endLine?: number /** * Line for inclusive start position in the input file with this warning’s source. * * ```js * warning.line //=> 5 * ``` */ line: number /** * Contains the CSS node that caused the warning. * * ```js * warning.node.toString() //=> 'color: white !important' * ``` */ node: Node /** * The name of the plugin that created this warning. * When you call `Node#warn` it will fill this property automatically. * * ```js * warning.plugin //=> 'postcss-important' * ``` */ plugin: string /** * The warning message. * * ```js * warning.text //=> 'Try to avoid !important' * ``` */ text: string /** * Type to filter warnings from `Result#messages`. * Always equal to `"warning"`. */ type: 'warning' /** * @param text Warning message. * @param opts Warning options. */ constructor(text: string, opts?: Warning.WarningOptions) /** * Returns a warning position and message. * * ```js * warning.toString() //=> 'postcss-lint:a.css:10:14: Avoid !important' * ``` * * @return Warning position and message. */ toString(): string } declare class Warning extends Warning_ {} export = Warning postcss-8.4.49/lib/warning.js000066400000000000000000000013431471446070100160740ustar00rootroot00000000000000'use strict' class Warning { constructor(text, opts = {}) { this.type = 'warning' this.text = text if (opts.node && opts.node.source) { let range = opts.node.rangeBy(opts) this.line = range.start.line this.column = range.start.column this.endLine = range.end.line this.endColumn = range.end.column } for (let opt in opts) this[opt] = opts[opt] } toString() { if (this.node) { return this.node.error(this.text, { index: this.index, plugin: this.plugin, word: this.word }).message } if (this.plugin) { return this.plugin + ': ' + this.text } return this.text } } module.exports = Warning Warning.default = Warning postcss-8.4.49/package.json000077500000000000000000000077631471446070100156300ustar00rootroot00000000000000{ "name": "postcss", "version": "8.4.49", "description": "Tool for transforming styles with JS plugins", "engines": { "node": "^10 || ^12 || >=14" }, "exports": { ".": { "require": "./lib/postcss.js", "import": "./lib/postcss.mjs" }, "./lib/at-rule": "./lib/at-rule.js", "./lib/comment": "./lib/comment.js", "./lib/container": "./lib/container.js", "./lib/css-syntax-error": "./lib/css-syntax-error.js", "./lib/declaration": "./lib/declaration.js", "./lib/fromJSON": "./lib/fromJSON.js", "./lib/input": "./lib/input.js", "./lib/lazy-result": "./lib/lazy-result.js", "./lib/no-work-result": "./lib/no-work-result.js", "./lib/list": "./lib/list.js", "./lib/map-generator": "./lib/map-generator.js", "./lib/node": "./lib/node.js", "./lib/parse": "./lib/parse.js", "./lib/parser": "./lib/parser.js", "./lib/postcss": "./lib/postcss.js", "./lib/previous-map": "./lib/previous-map.js", "./lib/processor": "./lib/processor.js", "./lib/result": "./lib/result.js", "./lib/root": "./lib/root.js", "./lib/rule": "./lib/rule.js", "./lib/stringifier": "./lib/stringifier.js", "./lib/stringify": "./lib/stringify.js", "./lib/symbols": "./lib/symbols.js", "./lib/terminal-highlight": "./lib/terminal-highlight.js", "./lib/tokenize": "./lib/tokenize.js", "./lib/warn-once": "./lib/warn-once.js", "./lib/warning": "./lib/warning.js", "./package.json": "./package.json" }, "main": "./lib/postcss.js", "types": "./lib/postcss.d.ts", "keywords": [ "css", "postcss", "rework", "preprocessor", "parser", "source map", "transform", "manipulation", "transpiler" ], "scripts": { "test:lint": "eslint .", "test:types": "check-dts", "test:version": "node ./test/version.js", "test:coverage": "c8 pnpm unit", "test:integration": "node ./test/integration.js", "test:size": "size-limit", "test": "FORCE_COLOR=1 pnpm run /^test:/", "unit": "uvu -r ts-node/register/transpile-only test \"\\.test\\.(ts|js)$\"", "old": "uvu -r ../../../../../../../test/old-node.js -r ts-node/register/transpile-only test \"\\.test\\.(ts|js)$\"" }, "funding": [ { "type": "opencollective", "url": "https://opencollective.com/postcss/" }, { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" }, { "type": "github", "url": "https://github.com/sponsors/ai" } ], "author": "Andrey Sitnik ", "license": "MIT", "homepage": "https://postcss.org/", "repository": "postcss/postcss", "bugs": { "url": "https://github.com/postcss/postcss/issues" }, "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "devDependencies": { "@logux/eslint-config": "^53.4.2", "@size-limit/preset-small-lib": "^11.1.6", "@types/node": "^22.9.0", "c8": "^10.1.2", "check-dts": "^0.8.2", "clean-publish": "^5.1.0", "concat-with-sourcemaps": "^1.1.0", "eslint": "^9.14.0", "nanodelay": "^1.0.8", "nanospy": "^1.0.0", "postcss-parser-tests": "^8.8.0", "simple-git-hooks": "^2.11.1", "size-limit": "^11.1.6", "strip-ansi": "^6.0.1", "ts-node": "^10.9.2", "typescript": "^5.6.3", "uvu": "^0.5.6" }, "c8": { "exclude": [ "**/*.test.*", "lib/map-generator.js" ], "lines": 100, "reporter": "lcov", "check-coverage": true }, "simple-git-hooks": { "pre-commit": "./test/version.js" }, "prettier": { "arrowParens": "avoid", "jsxSingleQuote": false, "quoteProps": "consistent", "semi": false, "singleQuote": true, "trailingComma": "none" }, "browser": { "./lib/terminal-highlight": false, "source-map-js": false, "path": false, "url": false, "fs": false }, "size-limit": [ { "path": "lib/postcss.js", "limit": "15 KB" } ], "clean-publish": { "cleanDocs": true } } postcss-8.4.49/pnpm-lock.yaml000066400000000000000000003062541471446070100161200ustar00rootroot00000000000000lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false importers: .: dependencies: nanoid: specifier: ^3.3.7 version: 3.3.7 picocolors: specifier: ^1.1.1 version: 1.1.1 source-map-js: specifier: ^1.2.1 version: 1.2.1 devDependencies: '@logux/eslint-config': specifier: ^53.4.2 version: 53.4.2(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@size-limit/preset-small-lib': specifier: ^11.1.6 version: 11.1.6(size-limit@11.1.6) '@types/node': specifier: ^22.9.0 version: 22.9.0 c8: specifier: ^10.1.2 version: 10.1.2 check-dts: specifier: ^0.8.2 version: 0.8.2(typescript@5.6.3) clean-publish: specifier: ^5.1.0 version: 5.1.0 concat-with-sourcemaps: specifier: ^1.1.0 version: 1.1.0 eslint: specifier: ^9.14.0 version: 9.14.0(jiti@2.4.0) nanodelay: specifier: ^1.0.8 version: 1.0.8 nanospy: specifier: ^1.0.0 version: 1.0.0 postcss-parser-tests: specifier: ^8.8.0 version: 8.8.0 simple-git-hooks: specifier: ^2.11.1 version: 2.11.1 size-limit: specifier: ^11.1.6 version: 11.1.6 strip-ansi: specifier: ^6.0.1 version: 6.0.1 ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@22.9.0)(typescript@5.6.3) typescript: specifier: ^5.6.3 version: 5.6.3 uvu: specifier: ^0.5.6 version: 0.5.6 packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} '@esbuild/aix-ppc64@0.24.0': resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.24.0': resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==} engines: {node: '>=18'} cpu: [arm64] os: [android] '@esbuild/android-arm@0.24.0': resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==} engines: {node: '>=18'} cpu: [arm] os: [android] '@esbuild/android-x64@0.24.0': resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==} engines: {node: '>=18'} cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.24.0': resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.24.0': resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.24.0': resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.24.0': resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.24.0': resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.24.0': resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==} engines: {node: '>=18'} cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.24.0': resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.24.0': resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==} engines: {node: '>=18'} cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.24.0': resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.24.0': resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.24.0': resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.24.0': resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==} engines: {node: '>=18'} cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.24.0': resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==} engines: {node: '>=18'} cpu: [x64] os: [linux] '@esbuild/netbsd-x64@0.24.0': resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] '@esbuild/openbsd-arm64@0.24.0': resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.24.0': resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] '@esbuild/sunos-x64@0.24.0': resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.24.0': resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.24.0': resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.24.0': resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==} engines: {node: '>=18'} cpu: [x64] os: [win32] '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.18.0': resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.7.0': resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.1.0': resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/js@9.14.0': resolution: {integrity: sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/plugin-kit@0.2.2': resolution: {integrity: sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} '@humanfs/node@0.16.6': resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} '@humanwhocodes/retry@0.3.1': resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} '@humanwhocodes/retry@0.4.1': resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} engines: {node: '>=18.18'} '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} '@logux/eslint-config@53.4.2': resolution: {integrity: sha512-Z1hRrA6bbqcPX74Q/ff9O/wNqQdPoPVENaA77KlETzRlaj9VStuDGzOolBHSvwK+dIbGVZonCdd0bVt8hCAeFQ==} engines: {node: '>=18.0.0'} peerDependencies: eslint: ^8.57.0 || ^9.0.0 eslint-plugin-svelte: ^2.35.1 svelte: ^4.2.12 || ^5.0.0 peerDependenciesMeta: eslint-plugin-svelte: optional: true svelte: optional: true '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} '@size-limit/esbuild@11.1.6': resolution: {integrity: sha512-0nBKYSxeRjUVCVoCkWZbmGkGBwpm0HdwHedWgxksBGxTKU0PjOMSHc3XTjKOrXBKXQzw90Ue0mgOd4n6zct9SA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: size-limit: 11.1.6 '@size-limit/file@11.1.6': resolution: {integrity: sha512-ojzzJMrTfcSECRnaTjGy0wNIolTCRdyqZTSWG9sG5XEoXG6PNgHXDDS6gf6YNxnqb+rWfCfVe93u6aKi3wEocQ==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: size-limit: 11.1.6 '@size-limit/preset-small-lib@11.1.6': resolution: {integrity: sha512-hlmkBlOryJIsKlGpS61Ti7/EEZomygAzOabpo2htdxUbkCkvtVoUQpGWHUfWuxdhheDVF6rtZZ6lPGftMKlaQg==} peerDependencies: size-limit: 11.1.6 '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} '@tsconfig/node14@1.0.3': resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} '@types/node@22.9.0': resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} '@typescript-eslint/eslint-plugin@8.13.0': resolution: {integrity: sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true '@typescript-eslint/parser@8.13.0': resolution: {integrity: sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true '@typescript-eslint/scope-manager@8.13.0': resolution: {integrity: sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/type-utils@8.13.0': resolution: {integrity: sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true '@typescript-eslint/types@8.13.0': resolution: {integrity: sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.13.0': resolution: {integrity: sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true '@typescript-eslint/utils@8.13.0': resolution: {integrity: sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 '@typescript-eslint/visitor-keys@8.13.0': resolution: {integrity: sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn-walk@8.3.4: resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} acorn@8.14.0: resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} ansi-regex@6.1.0: resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} array-includes@3.1.8: resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} array.prototype.findlastindex@1.2.5: resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} engines: {node: '>= 0.4'} array.prototype.flat@1.3.2: resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} engines: {node: '>= 0.4'} array.prototype.flatmap@1.3.2: resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} engines: {node: '>= 0.4'} arraybuffer.prototype.slice@1.0.3: resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} bytes-iec@3.1.1: resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} engines: {node: '>= 0.8'} c8@10.1.2: resolution: {integrity: sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==} engines: {node: '>=18'} hasBin: true peerDependencies: monocart-coverage-reports: ^2 peerDependenciesMeta: monocart-coverage-reports: optional: true call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} check-dts@0.8.2: resolution: {integrity: sha512-+G9GREoEYIS/mLleQCIcsUdX6AyrURr8UENN3PzzBIe/mO2dKN/eNxsLu2atNrkjkY7ri1Gn5rjiy44IFgFxCw==} engines: {node: '>=18.0.0'} hasBin: true peerDependencies: typescript: '>=4.0.0' chokidar@4.0.1: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} clean-publish@5.1.0: resolution: {integrity: sha512-Gbz8x7sL/sn0j+2B+yYEumD17WmPT6pHLN+A5nhcd0Sdh86EYblQleU+dUIICXVFalFMFBdW2aGynrVJ6k1u4Q==} engines: {node: '>= 18.0.0'} hasBin: true cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} concat-with-sourcemaps@1.1.0: resolution: {integrity: sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} cross-spawn@7.0.5: resolution: {integrity: sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==} engines: {node: '>= 8'} data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} data-view-byte-length@1.0.1: resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} engines: {node: '>= 0.4'} data-view-byte-offset@1.0.0: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} enhanced-resolve@5.17.1: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} es-abstract@1.23.3: resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} es-define-property@1.0.0: resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} engines: {node: '>= 0.4'} es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} es-set-tostringtag@2.0.3: resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} engines: {node: '>= 0.4'} es-shim-unscopables@1.0.2: resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} esbuild@0.24.0: resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==} engines: {node: '>=18'} hasBin: true escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} eslint-compat-utils@0.5.1: resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} engines: {node: '>=12'} peerDependencies: eslint: '>=6.0.0' eslint-config-standard@17.1.0: resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==} engines: {node: '>=12.0.0'} peerDependencies: eslint: ^8.0.1 eslint-plugin-import: ^2.25.2 eslint-plugin-n: '^15.0.0 || ^16.0.0 ' eslint-plugin-promise: ^6.0.0 eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} eslint-module-utils@2.12.0: resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' eslint: '*' eslint-import-resolver-node: '*' eslint-import-resolver-typescript: '*' eslint-import-resolver-webpack: '*' peerDependenciesMeta: '@typescript-eslint/parser': optional: true eslint: optional: true eslint-import-resolver-node: optional: true eslint-import-resolver-typescript: optional: true eslint-import-resolver-webpack: optional: true eslint-plugin-es-x@7.8.0: resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '>=8' eslint-plugin-import@2.31.0: resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 peerDependenciesMeta: '@typescript-eslint/parser': optional: true eslint-plugin-n@17.13.1: resolution: {integrity: sha512-97qzhk1z3DdSJNCqT45EslwCu5+LB9GDadSyBItgKUfGsXAmN/aa7LRQ0ZxHffUxUzvgbTPJL27/pE9ZQWHy7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' eslint-plugin-perfectionist@3.9.1: resolution: {integrity: sha512-9WRzf6XaAxF4Oi5t/3TqKP5zUjERhasHmLFHin2Yw6ZAp/EP/EVA2dr3BhQrrHWCm5SzTMZf0FcjDnBkO2xFkA==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: astro-eslint-parser: ^1.0.2 eslint: '>=8.0.0' svelte: '>=3.0.0' svelte-eslint-parser: ^0.41.1 vue-eslint-parser: '>=9.0.0' peerDependenciesMeta: astro-eslint-parser: optional: true svelte: optional: true svelte-eslint-parser: optional: true vue-eslint-parser: optional: true eslint-plugin-prefer-let@4.0.0: resolution: {integrity: sha512-X4ep5PMO1320HKaNC9DM5+p6XvOhwv+RcqGjhv3aiw9iAtHhiFtdIUB5l0Zya0iM22ys2BGKzrNI9Xpw/ZHooQ==} engines: {node: '>=0.10.0'} eslint-plugin-promise@7.1.0: resolution: {integrity: sha512-8trNmPxdAy3W620WKDpaS65NlM5yAumod6XeC4LOb+jxlkG4IVcp68c6dXY2ev+uT4U1PtG57YDV6EGAXN0GbQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 eslint-scope@8.2.0: resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} eslint-visitor-keys@4.2.0: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint@9.14.0: resolution: {integrity: sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: jiti: '*' peerDependenciesMeta: jiti: optional: true espree@10.3.0: resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} fdir@6.4.2: resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: picomatch: optional: true file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} globals@15.12.0: resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} has-proto@1.0.3: resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} has-tostringtag@1.0.2: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} internal-slot@1.0.7: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} is-array-buffer@3.0.4: resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} engines: {node: '>= 0.4'} is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} is-core-module@2.15.1: resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} engines: {node: '>= 0.4'} is-data-view@1.0.1: resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} engines: {node: '>= 0.4'} is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} is-shared-array-buffer@1.0.3: resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} engines: {node: '>= 0.4'} is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} is-typed-array@1.1.13: resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} istanbul-reports@3.1.7: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} jiti@2.4.0: resolution: {integrity: sha512-H5UpaUI+aHOqZXlYOaFP/8AzKsg+guWu+Pr3Y8i7+Y3zr1aXAvCvTAQ1RxSc6oVD8R8c7brgNtTVP91E7upH/g==} hasBin: true js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} lilconfig@3.1.2: resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} engines: {node: '>=14'} locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} nanodelay@1.0.8: resolution: {integrity: sha512-mfVn7t26m4mVoUuWdUevZccq0saIh5T4Lu3cAzbZ6j03yc4sIDwM3Dof0LS70YwflPZtGJ92BGhNYV862wXRvg==} nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true nanoid@5.0.8: resolution: {integrity: sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==} engines: {node: ^18 || >=20} hasBin: true nanospinner@1.2.0: resolution: {integrity: sha512-dGxYcEj8YhuxjVO3PYmnj1nBhtwUkvuwYbLl/MduBPmQUPy3xBtG/ScJgqZgntQkX44UQaCSlFeW4rS5fUR/Sw==} nanospy@1.0.0: resolution: {integrity: sha512-wvmmALNstRRhLhy7RV11NCRY2k1zxstImiju4VyyKNNRIKDVjyBtmEd/Q4G82/3dN4VSTe+0PRR3DUAASSbEEQ==} engines: {node: ^8.0.0 || ^10.0.0 || ^12.0.0 || ^14.0.0 || ^16.0.0 || ^18.0.0 || >=20.0.0} natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} object.assign@4.1.5: resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} object.fromentries@2.0.8: resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} engines: {node: '>= 0.4'} object.groupby@1.0.3: resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} engines: {node: '>= 0.4'} object.values@1.2.0: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} picomatch@4.0.2: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} postcss-parser-tests@8.8.0: resolution: {integrity: sha512-vAyVrBzp7YmfpmjCG3RGhilE9+oydj6oTZYWMBwkp/3FVOdUURerTRD0w/NVegOreAj51tCPqgCwbb4AW5f5SA==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} readdirp@4.0.2: resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} engines: {node: '>= 14.16.0'} regexp.prototype.flags@1.5.3: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} requireindex@1.2.0: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} safe-array-concat@1.1.2: resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} engines: {node: '>=0.4'} safe-regex-test@1.0.3: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} set-function-name@2.0.2: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} simple-git-hooks@2.11.1: resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} hasBin: true size-limit@11.1.6: resolution: {integrity: sha512-S5ux2IB8rU26xwVgMskmknGMFkieaIAqDLuwgKiypk6oa4lFsie8yFPrzRFV+yrLDY2GddjXuCaVk5PveVOHiQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} string-width@5.1.2: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} string.prototype.trim@1.2.9: resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} string.prototype.trimend@1.0.8: resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} string.prototype.trimstart@1.0.8: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} strip-ansi@7.1.0: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} test-exclude@7.0.1: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} tinyglobby@0.2.10: resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} engines: {node: '>=12.0.0'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} ts-api-utils@1.4.0: resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' ts-node@10.9.2: resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' '@swc/wasm': '>=1.2.50' '@types/node': '*' typescript: '>=2.7' peerDependenciesMeta: '@swc/core': optional: true '@swc/wasm': optional: true tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} typed-array-byte-length@1.0.1: resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} engines: {node: '>= 0.4'} typed-array-byte-offset@1.0.2: resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} engines: {node: '>= 0.4'} typed-array-length@1.0.6: resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} engines: {node: '>= 0.4'} typescript-eslint@8.13.0: resolution: {integrity: sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} hasBin: true unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} uvu@0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} hasBin: true v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} v8-to-istanbul@9.3.0: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} which-typed-array@1.1.15: resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} wrap-ansi@8.1.0: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} snapshots: '@bcoe/v8-coverage@0.2.3': {} '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 '@esbuild/aix-ppc64@0.24.0': optional: true '@esbuild/android-arm64@0.24.0': optional: true '@esbuild/android-arm@0.24.0': optional: true '@esbuild/android-x64@0.24.0': optional: true '@esbuild/darwin-arm64@0.24.0': optional: true '@esbuild/darwin-x64@0.24.0': optional: true '@esbuild/freebsd-arm64@0.24.0': optional: true '@esbuild/freebsd-x64@0.24.0': optional: true '@esbuild/linux-arm64@0.24.0': optional: true '@esbuild/linux-arm@0.24.0': optional: true '@esbuild/linux-ia32@0.24.0': optional: true '@esbuild/linux-loong64@0.24.0': optional: true '@esbuild/linux-mips64el@0.24.0': optional: true '@esbuild/linux-ppc64@0.24.0': optional: true '@esbuild/linux-riscv64@0.24.0': optional: true '@esbuild/linux-s390x@0.24.0': optional: true '@esbuild/linux-x64@0.24.0': optional: true '@esbuild/netbsd-x64@0.24.0': optional: true '@esbuild/openbsd-arm64@0.24.0': optional: true '@esbuild/openbsd-x64@0.24.0': optional: true '@esbuild/sunos-x64@0.24.0': optional: true '@esbuild/win32-arm64@0.24.0': optional: true '@esbuild/win32-ia32@0.24.0': optional: true '@esbuild/win32-x64@0.24.0': optional: true '@eslint-community/eslint-utils@4.4.1(eslint@9.14.0(jiti@2.4.0))': dependencies: eslint: 9.14.0(jiti@2.4.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.18.0': dependencies: '@eslint/object-schema': 2.1.4 debug: 4.3.7 minimatch: 3.1.2 transitivePeerDependencies: - supports-color '@eslint/core@0.7.0': {} '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 debug: 4.3.7 espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color '@eslint/js@9.14.0': {} '@eslint/object-schema@2.1.4': {} '@eslint/plugin-kit@0.2.2': dependencies: levn: 0.4.1 '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': dependencies: '@humanfs/core': 0.19.1 '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.3.1': {} '@humanwhocodes/retry@0.4.1': {} '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 strip-ansi: 7.1.0 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 '@istanbuljs/schema@0.1.3': {} '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 '@logux/eslint-config@53.4.2(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)': dependencies: '@eslint/eslintrc': 3.1.0 eslint: 9.14.0(jiti@2.4.0) eslint-config-standard: 17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0)))(eslint-plugin-n@17.13.1(eslint@9.14.0(jiti@2.4.0)))(eslint-plugin-promise@7.1.0(eslint@9.14.0(jiti@2.4.0)))(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-n: 17.13.1(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-perfectionist: 3.9.1(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) eslint-plugin-prefer-let: 4.0.0 eslint-plugin-promise: 7.1.0(eslint@9.14.0(jiti@2.4.0)) typescript-eslint: 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) transitivePeerDependencies: - '@typescript-eslint/parser' - astro-eslint-parser - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - svelte-eslint-parser - typescript - vue-eslint-parser '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 '@nodelib/fs.stat@2.0.5': {} '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 '@pkgjs/parseargs@0.11.0': optional: true '@rtsao/scc@1.1.0': {} '@size-limit/esbuild@11.1.6(size-limit@11.1.6)': dependencies: esbuild: 0.24.0 nanoid: 5.0.8 size-limit: 11.1.6 '@size-limit/file@11.1.6(size-limit@11.1.6)': dependencies: size-limit: 11.1.6 '@size-limit/preset-small-lib@11.1.6(size-limit@11.1.6)': dependencies: '@size-limit/esbuild': 11.1.6(size-limit@11.1.6) '@size-limit/file': 11.1.6(size-limit@11.1.6) size-limit: 11.1.6 '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} '@tsconfig/node14@1.0.3': {} '@tsconfig/node16@1.0.4': {} '@types/estree@1.0.6': {} '@types/istanbul-lib-coverage@2.0.6': {} '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} '@types/node@22.9.0': dependencies: undici-types: 6.19.8 '@types/unist@3.0.3': {} '@typescript-eslint/eslint-plugin@8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.12.1 '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@typescript-eslint/scope-manager': 8.13.0 '@typescript-eslint/type-utils': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.13.0 eslint: 9.14.0(jiti@2.4.0) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color '@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 8.13.0 '@typescript-eslint/types': 8.13.0 '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7 eslint: 9.14.0(jiti@2.4.0) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color '@typescript-eslint/scope-manager@8.13.0': dependencies: '@typescript-eslint/types': 8.13.0 '@typescript-eslint/visitor-keys': 8.13.0 '@typescript-eslint/type-utils@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)': dependencies: '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) debug: 4.3.7 ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - eslint - supports-color '@typescript-eslint/types@8.13.0': {} '@typescript-eslint/typescript-estree@8.13.0(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 8.13.0 '@typescript-eslint/visitor-keys': 8.13.0 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 ts-api-utils: 1.4.0(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - supports-color '@typescript-eslint/utils@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@2.4.0)) '@typescript-eslint/scope-manager': 8.13.0 '@typescript-eslint/types': 8.13.0 '@typescript-eslint/typescript-estree': 8.13.0(typescript@5.6.3) eslint: 9.14.0(jiti@2.4.0) transitivePeerDependencies: - supports-color - typescript '@typescript-eslint/visitor-keys@8.13.0': dependencies: '@typescript-eslint/types': 8.13.0 eslint-visitor-keys: 3.4.3 acorn-jsx@5.3.2(acorn@8.14.0): dependencies: acorn: 8.14.0 acorn-walk@8.3.4: dependencies: acorn: 8.14.0 acorn@8.14.0: {} ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 fast-json-stable-stringify: 2.1.0 json-schema-traverse: 0.4.1 uri-js: 4.4.1 ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 ansi-styles@6.2.1: {} arg@4.1.3: {} argparse@2.0.1: {} array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 is-array-buffer: 3.0.4 array-includes@3.1.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 is-string: 1.0.7 array.prototype.findlastindex@1.2.5: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 array.prototype.flat@1.3.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 array.prototype.flatmap@1.3.2: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 arraybuffer.prototype.slice@1.0.3: dependencies: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-errors: 1.3.0 get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 balanced-match@1.0.2: {} brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 braces@3.0.3: dependencies: fill-range: 7.1.1 bytes-iec@3.1.1: {} c8@10.1.2: dependencies: '@bcoe/v8-coverage': 0.2.3 '@istanbuljs/schema': 0.1.3 find-up: 5.0.0 foreground-child: 3.3.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.1.7 test-exclude: 7.0.1 v8-to-istanbul: 9.3.0 yargs: 17.7.2 yargs-parser: 21.1.1 call-bind@1.0.7: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 set-function-length: 1.2.2 callsites@3.1.0: {} chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 check-dts@0.8.2(typescript@5.6.3): dependencies: fast-glob: 3.3.2 nanospinner: 1.2.0 picocolors: 1.1.1 typescript: 5.6.3 vfile-location: 5.0.3 chokidar@4.0.1: dependencies: readdirp: 4.0.2 clean-publish@5.1.0: dependencies: cross-spawn: 7.0.5 fast-glob: 3.3.2 lilconfig: 3.1.2 micromatch: 4.0.8 cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} concat-map@0.0.1: {} concat-with-sourcemaps@1.1.0: dependencies: source-map: 0.6.1 convert-source-map@2.0.0: {} create-require@1.1.1: {} cross-spawn@7.0.5: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 data-view-byte-length@1.0.1: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 data-view-byte-offset@1.0.0: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-data-view: 1.0.1 debug@3.2.7: dependencies: ms: 2.1.3 debug@4.3.7: dependencies: ms: 2.1.3 deep-is@0.1.4: {} define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 gopd: 1.0.1 define-properties@1.2.1: dependencies: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 dequal@2.0.3: {} diff@4.0.2: {} diff@5.2.0: {} doctrine@2.1.0: dependencies: esutils: 2.0.3 eastasianwidth@0.2.0: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} enhanced-resolve@5.17.1: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 es-abstract@1.23.3: dependencies: array-buffer-byte-length: 1.0.1 arraybuffer.prototype.slice: 1.0.3 available-typed-arrays: 1.0.7 call-bind: 1.0.7 data-view-buffer: 1.0.1 data-view-byte-length: 1.0.1 data-view-byte-offset: 1.0.0 es-define-property: 1.0.0 es-errors: 1.3.0 es-object-atoms: 1.0.0 es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 get-intrinsic: 1.2.4 get-symbol-description: 1.0.2 globalthis: 1.0.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 has-proto: 1.0.3 has-symbols: 1.0.3 hasown: 2.0.2 internal-slot: 1.0.7 is-array-buffer: 3.0.4 is-callable: 1.2.7 is-data-view: 1.0.1 is-negative-zero: 2.0.3 is-regex: 1.1.4 is-shared-array-buffer: 1.0.3 is-string: 1.0.7 is-typed-array: 1.1.13 is-weakref: 1.0.2 object-inspect: 1.13.3 object-keys: 1.1.1 object.assign: 4.1.5 regexp.prototype.flags: 1.5.3 safe-array-concat: 1.1.2 safe-regex-test: 1.0.3 string.prototype.trim: 1.2.9 string.prototype.trimend: 1.0.8 string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.2 typed-array-byte-length: 1.0.1 typed-array-byte-offset: 1.0.2 typed-array-length: 1.0.6 unbox-primitive: 1.0.2 which-typed-array: 1.1.15 es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 es-errors@1.3.0: {} es-object-atoms@1.0.0: dependencies: es-errors: 1.3.0 es-set-tostringtag@2.0.3: dependencies: get-intrinsic: 1.2.4 has-tostringtag: 1.0.2 hasown: 2.0.2 es-shim-unscopables@1.0.2: dependencies: hasown: 2.0.2 es-to-primitive@1.2.1: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 esbuild@0.24.0: optionalDependencies: '@esbuild/aix-ppc64': 0.24.0 '@esbuild/android-arm': 0.24.0 '@esbuild/android-arm64': 0.24.0 '@esbuild/android-x64': 0.24.0 '@esbuild/darwin-arm64': 0.24.0 '@esbuild/darwin-x64': 0.24.0 '@esbuild/freebsd-arm64': 0.24.0 '@esbuild/freebsd-x64': 0.24.0 '@esbuild/linux-arm': 0.24.0 '@esbuild/linux-arm64': 0.24.0 '@esbuild/linux-ia32': 0.24.0 '@esbuild/linux-loong64': 0.24.0 '@esbuild/linux-mips64el': 0.24.0 '@esbuild/linux-ppc64': 0.24.0 '@esbuild/linux-riscv64': 0.24.0 '@esbuild/linux-s390x': 0.24.0 '@esbuild/linux-x64': 0.24.0 '@esbuild/netbsd-x64': 0.24.0 '@esbuild/openbsd-arm64': 0.24.0 '@esbuild/openbsd-x64': 0.24.0 '@esbuild/sunos-x64': 0.24.0 '@esbuild/win32-arm64': 0.24.0 '@esbuild/win32-ia32': 0.24.0 '@esbuild/win32-x64': 0.24.0 escalade@3.2.0: {} escape-string-regexp@4.0.0: {} eslint-compat-utils@0.5.1(eslint@9.14.0(jiti@2.4.0)): dependencies: eslint: 9.14.0(jiti@2.4.0) semver: 7.6.3 eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0)))(eslint-plugin-n@17.13.1(eslint@9.14.0(jiti@2.4.0)))(eslint-plugin-promise@7.1.0(eslint@9.14.0(jiti@2.4.0)))(eslint@9.14.0(jiti@2.4.0)): dependencies: eslint: 9.14.0(jiti@2.4.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-n: 17.13.1(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-promise: 7.1.0(eslint@9.14.0(jiti@2.4.0)) eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 is-core-module: 2.15.1 resolve: 1.22.8 transitivePeerDependencies: - supports-color eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.14.0(jiti@2.4.0)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) eslint: 9.14.0(jiti@2.4.0) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color eslint-plugin-es-x@7.8.0(eslint@9.14.0(jiti@2.4.0)): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@2.4.0)) '@eslint-community/regexpp': 4.12.1 eslint: 9.14.0(jiti@2.4.0) eslint-compat-utils: 0.5.1(eslint@9.14.0(jiti@2.4.0)) eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 eslint: 9.14.0(jiti@2.4.0) eslint-import-resolver-node: 0.3.9 eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@9.14.0(jiti@2.4.0)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 minimatch: 3.1.2 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.0 semver: 6.3.1 string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color eslint-plugin-n@17.13.1(eslint@9.14.0(jiti@2.4.0)): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@2.4.0)) enhanced-resolve: 5.17.1 eslint: 9.14.0(jiti@2.4.0) eslint-plugin-es-x: 7.8.0(eslint@9.14.0(jiti@2.4.0)) get-tsconfig: 4.8.1 globals: 15.12.0 ignore: 5.3.2 minimatch: 9.0.5 semver: 7.6.3 eslint-plugin-perfectionist@3.9.1(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3): dependencies: '@typescript-eslint/types': 8.13.0 '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) eslint: 9.14.0(jiti@2.4.0) minimatch: 9.0.5 natural-compare-lite: 1.4.0 transitivePeerDependencies: - supports-color - typescript eslint-plugin-prefer-let@4.0.0: dependencies: requireindex: 1.2.0 eslint-plugin-promise@7.1.0(eslint@9.14.0(jiti@2.4.0)): dependencies: eslint: 9.14.0(jiti@2.4.0) eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.0: {} eslint@9.14.0(jiti@2.4.0): dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@2.4.0)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.18.0 '@eslint/core': 0.7.0 '@eslint/eslintrc': 3.1.0 '@eslint/js': 9.14.0 '@eslint/plugin-kit': 0.2.2 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.1 '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.5 debug: 4.3.7 escape-string-regexp: 4.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 text-table: 0.2.0 optionalDependencies: jiti: 2.4.0 transitivePeerDependencies: - supports-color espree@10.3.0: dependencies: acorn: 8.14.0 acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 4.2.0 esquery@1.6.0: dependencies: estraverse: 5.3.0 esrecurse@4.3.0: dependencies: estraverse: 5.3.0 estraverse@5.3.0: {} esutils@2.0.3: {} fast-deep-equal@3.1.3: {} fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.8 fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} fastq@1.17.1: dependencies: reusify: 1.0.4 fdir@6.4.2(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 flat-cache@4.0.1: dependencies: flatted: 3.3.1 keyv: 4.5.4 flatted@3.3.1: {} for-each@0.3.3: dependencies: is-callable: 1.2.7 foreground-child@3.3.0: dependencies: cross-spawn: 7.0.5 signal-exit: 4.1.0 function-bind@1.1.2: {} function.prototype.name@1.1.6: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 functions-have-names: 1.2.3 functions-have-names@1.2.3: {} get-caller-file@2.0.5: {} get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 has-proto: 1.0.3 has-symbols: 1.0.3 hasown: 2.0.2 get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 glob-parent@5.1.2: dependencies: is-glob: 4.0.3 glob-parent@6.0.2: dependencies: is-glob: 4.0.3 glob@10.4.5: dependencies: foreground-child: 3.3.0 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 1.11.1 globals@14.0.0: {} globals@15.12.0: {} globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.0.1 gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 graceful-fs@4.2.11: {} graphemer@1.4.0: {} has-bigints@1.0.2: {} has-flag@4.0.0: {} has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 has-proto@1.0.3: {} has-symbols@1.0.3: {} has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 hasown@2.0.2: dependencies: function-bind: 1.1.2 html-escaper@2.0.2: {} ignore@5.3.2: {} import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 imurmurhash@0.1.4: {} internal-slot@1.0.7: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.0.6 is-array-buffer@3.0.4: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 is-boolean-object@1.1.2: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 is-callable@1.2.7: {} is-core-module@2.15.1: dependencies: hasown: 2.0.2 is-data-view@1.0.1: dependencies: is-typed-array: 1.1.13 is-date-object@1.0.5: dependencies: has-tostringtag: 1.0.2 is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 is-negative-zero@2.0.3: {} is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.2 is-number@7.0.0: {} is-regex@1.1.4: dependencies: call-bind: 1.0.7 has-tostringtag: 1.0.2 is-shared-array-buffer@1.0.3: dependencies: call-bind: 1.0.7 is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 is-symbol@1.0.4: dependencies: has-symbols: 1.0.3 is-typed-array@1.1.13: dependencies: which-typed-array: 1.1.15 is-weakref@1.0.2: dependencies: call-bind: 1.0.7 isarray@2.0.5: {} isexe@2.0.0: {} istanbul-lib-coverage@3.2.2: {} istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 jiti@2.4.0: {} js-yaml@4.1.0: dependencies: argparse: 2.0.1 json-buffer@3.0.1: {} json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json5@1.0.2: dependencies: minimist: 1.2.8 keyv@4.5.4: dependencies: json-buffer: 3.0.1 kleur@4.1.5: {} levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 lilconfig@3.1.2: {} locate-path@6.0.0: dependencies: p-locate: 5.0.0 lodash.merge@4.6.2: {} lru-cache@10.4.3: {} make-dir@4.0.0: dependencies: semver: 7.6.3 make-error@1.3.6: {} merge2@1.4.1: {} micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 minimist@1.2.8: {} minipass@7.1.2: {} mri@1.2.0: {} ms@2.1.3: {} nanodelay@1.0.8: {} nanoid@3.3.7: {} nanoid@5.0.8: {} nanospinner@1.2.0: dependencies: picocolors: 1.1.1 nanospy@1.0.0: {} natural-compare-lite@1.4.0: {} natural-compare@1.4.0: {} object-inspect@1.13.3: {} object-keys@1.1.1: {} object.assign@4.1.5: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 object.fromentries@2.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 object.groupby@1.0.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 object.values@1.2.0: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 optionator@0.9.4: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.5 p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 p-locate@5.0.0: dependencies: p-limit: 3.1.0 package-json-from-dist@1.0.1: {} parent-module@1.0.1: dependencies: callsites: 3.1.0 path-exists@4.0.0: {} path-key@3.1.1: {} path-parse@1.0.7: {} path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 minipass: 7.1.2 picocolors@1.1.1: {} picomatch@2.3.1: {} picomatch@4.0.2: {} possible-typed-array-names@1.0.0: {} postcss-parser-tests@8.8.0: dependencies: picocolors: 1.1.1 prelude-ls@1.2.1: {} punycode@2.3.1: {} queue-microtask@1.2.3: {} readdirp@4.0.2: {} regexp.prototype.flags@1.5.3: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-errors: 1.3.0 set-function-name: 2.0.2 require-directory@2.1.1: {} requireindex@1.2.0: {} resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} resolve@1.22.8: dependencies: is-core-module: 2.15.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 reusify@1.0.4: {} run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 sade@1.8.1: dependencies: mri: 1.2.0 safe-array-concat@1.1.2: dependencies: call-bind: 1.0.7 get-intrinsic: 1.2.4 has-symbols: 1.0.3 isarray: 2.0.5 safe-regex-test@1.0.3: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-regex: 1.1.4 semver@6.3.1: {} semver@7.6.3: {} set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 gopd: 1.0.1 has-property-descriptors: 1.0.2 set-function-name@2.0.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} side-channel@1.0.6: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 get-intrinsic: 1.2.4 object-inspect: 1.13.3 signal-exit@4.1.0: {} simple-git-hooks@2.11.1: {} size-limit@11.1.6: dependencies: bytes-iec: 3.1.1 chokidar: 4.0.1 jiti: 2.4.0 lilconfig: 3.1.2 nanospinner: 1.2.0 picocolors: 1.1.1 tinyglobby: 0.2.10 source-map-js@1.2.1: {} source-map@0.6.1: {} string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 string-width@5.1.2: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 string.prototype.trim@1.2.9: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-abstract: 1.23.3 es-object-atoms: 1.0.0 string.prototype.trimend@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 es-object-atoms: 1.0.0 strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 strip-ansi@7.1.0: dependencies: ansi-regex: 6.1.0 strip-bom@3.0.0: {} strip-json-comments@3.1.1: {} supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} tapable@2.2.1: {} test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 glob: 10.4.5 minimatch: 9.0.5 text-table@0.2.0: {} tinyglobby@0.2.10: dependencies: fdir: 6.4.2(picomatch@4.0.2) picomatch: 4.0.2 to-regex-range@5.0.1: dependencies: is-number: 7.0.0 ts-api-utils@1.4.0(typescript@5.6.3): dependencies: typescript: 5.6.3 ts-node@10.9.2(@types/node@22.9.0)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 22.9.0 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 typescript: 5.6.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 type-check@0.4.0: dependencies: prelude-ls: 1.2.1 typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 es-errors: 1.3.0 is-typed-array: 1.1.13 typed-array-byte-length@1.0.1: dependencies: call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 typed-array-byte-offset@1.0.2: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 typed-array-length@1.0.6: dependencies: call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-proto: 1.0.3 is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 typescript-eslint@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3): dependencies: '@typescript-eslint/eslint-plugin': 8.13.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3))(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@typescript-eslint/parser': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) '@typescript-eslint/utils': 8.13.0(eslint@9.14.0(jiti@2.4.0))(typescript@5.6.3) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: - eslint - supports-color typescript@5.6.3: {} unbox-primitive@1.0.2: dependencies: call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 undici-types@6.19.8: {} unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.3 uri-js@4.4.1: dependencies: punycode: 2.3.1 uvu@0.5.6: dependencies: dequal: 2.0.3 diff: 5.2.0 kleur: 4.1.5 sade: 1.8.1 v8-compile-cache-lib@3.0.1: {} v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 vfile: 6.0.3 vfile-message@4.0.2: dependencies: '@types/unist': 3.0.3 unist-util-stringify-position: 4.0.0 vfile@6.0.3: dependencies: '@types/unist': 3.0.3 vfile-message: 4.0.2 which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 is-boolean-object: 1.1.2 is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.4 which-typed-array@1.1.15: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 has-tostringtag: 1.0.2 which@2.0.2: dependencies: isexe: 2.0.0 word-wrap@1.2.5: {} wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi@8.1.0: dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 y18n@5.0.8: {} yargs-parser@21.1.1: {} yargs@17.7.2: dependencies: cliui: 8.0.1 escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 yn@3.1.1: {} yocto-queue@0.1.0: {} postcss-8.4.49/test/000077500000000000000000000000001471446070100143015ustar00rootroot00000000000000postcss-8.4.49/test/at-rule.test.ts000077500000000000000000000025221471446070100172040ustar00rootroot00000000000000import { test } from 'uvu' import { is, type } from 'uvu/assert' import { AtRule, parse } from '../lib/postcss.js' test('initializes with properties', () => { let rule = new AtRule({ name: 'encoding', params: '"utf-8"' }) is(rule.name, 'encoding') is(rule.params, '"utf-8"') is(rule.toString(), '@encoding "utf-8"') }) test('does not fall on childless at-rule', () => { let rule = new AtRule() rule.each(() => { throw new Error('AtRule has no children') }) }) test('creates nodes property on prepend()', () => { let rule = new AtRule() type(rule.nodes, 'undefined') rule.prepend('color: black') is(rule.nodes?.length, 1) }) test('creates nodes property on append()', () => { let rule = new AtRule() type(rule.nodes, 'undefined') rule.append('color: black') is(rule.nodes?.length, 1) }) test('inserts default spaces', () => { let rule = new AtRule({ name: 'page', nodes: [], params: 1 }) is(rule.toString(), '@page 1 {}') }) test('clone spaces from another at-rule', () => { let root = parse('@page{}a{}') let rule = new AtRule({ name: 'page', nodes: [], params: 1 }) root.append(rule) is(rule.toString(), '@page 1{}') }) test('at-rule without body has no nodes property', () => { let root = parse('@layer a, b, c;'); let layer = root.first as AtRule type(layer.nodes, 'undefined') }); test.run() postcss-8.4.49/test/comment.test.ts000077500000000000000000000007401471446070100172750ustar00rootroot00000000000000import { test } from 'uvu' import { is } from 'uvu/assert' import { Comment, parse } from '../lib/postcss.js' test('toString() inserts default spaces', () => { let comment = new Comment({ text: 'hi' }) is(comment.toString(), '/* hi */') }) test('toString() clones spaces from another comment', () => { let root = parse('a{} /*hello*/') let comment = new Comment({ text: 'world' }) root.append(comment) is(root.toString(), 'a{} /*hello*/ /*world*/') }) test.run() postcss-8.4.49/test/container.test.ts000077500000000000000000000540311471446070100176170ustar00rootroot00000000000000import { test } from 'uvu' import { equal, is, match, throws, type } from 'uvu/assert' import { AtRule, Declaration, parse, Root, Rule } from '../lib/postcss.js' let example = 'a { a: 1; b: 2 }' + '/* a */' + '@keyframes anim {' + '/* b */' + 'to { c: 3 }' + '}' + '@media all and (min-width: 100) {' + 'em { d: 4 }' + '@page {' + 'e: 5;' + '/* c */' + '}' + '}' test('throws error on declaration without value', () => { throws(() => { // @ts-expect-error new Rule().append({ prop: 'color', vlaue: 'black' }) }, /Value field is missed/) }) test('throws error on unknown node type', () => { throws(() => { // @ts-expect-error new Rule().append({ foo: 'bar' }) }, /Unknown node type/) }) test('push() adds child without checks', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.push(new Declaration({ prop: 'c', value: '3' })) is(rule.toString(), 'a { a: 1; b: 2; c: 3 }') is(rule.nodes.length, 3) type(rule.last?.raws.before, 'undefined') }) test('each() iterates', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let indexes: number[] = [] let result = rule.each((decl, i) => { indexes.push(i) is(decl, rule.nodes[i]) }) type(result, 'undefined') equal(indexes, [0, 1]) }) test('each() iterates with prepend', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each(() => { rule.prepend({ prop: 'color', value: 'aqua' }) size += 1 }) is(size, 2) }) test('each() iterates with prepend insertBefore', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each(decl => { if (decl.type === 'decl' && decl.prop === 'a') { rule.insertBefore(decl, { prop: 'c', value: '3' }) } size += 1 }) is(size, 2) }) test('each() iterates with append insertBefore', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each((decl, i) => { if (decl.type === 'decl' && decl.prop === 'a') { rule.insertBefore(i + 1, { prop: 'c', value: '3' }) } size += 1 }) is(size, 3) }) test('each() iterates with prepend insertAfter', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each((decl, i) => { rule.insertAfter(i - 1, { prop: 'c', value: '3' }) size += 1 }) is(size, 2) }) test('each() iterates with append insertAfter', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each((decl, i) => { if (decl.type === 'decl' && decl.prop === 'a') { rule.insertAfter(i, { prop: 'c', value: '3' }) } size += 1 }) is(size, 3) }) test('each() iterates with remove', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let size = 0 rule.each(() => { rule.removeChild(0) size += 1 }) is(size, 2) }) test('each() breaks iteration', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let indexes: number[] = [] let result = rule.each((decl, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [0]) }) test('each() allows to change children', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let props: string[] = [] rule.each(decl => { if (decl.type === 'decl') { props.push(decl.prop) rule.nodes = [rule.last as any, rule.first as any] } }) equal(props, ['a', 'a']) }) test('walk() iterates', () => { let types: string[] = [] let indexes: number[] = [] let result = parse(example).walk((node, i) => { types.push(node.type) indexes.push(i) }) type(result, 'undefined') equal(types, [ 'rule', 'decl', 'decl', 'comment', 'atrule', 'comment', 'rule', 'decl', 'atrule', 'rule', 'decl', 'atrule', 'decl', 'comment' ]) equal(indexes, [0, 0, 1, 1, 2, 0, 1, 0, 3, 0, 0, 1, 0, 1]) }) test('walk() breaks iteration', () => { let indexes: number[] = [] let result = parse(example).walk((decl, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [0]) }) test('walk() adds CSS position to error stack', () => { let error = new Error('T') error.stack = 'Error: T\n at b (b.js:2:4)\n at a (a.js:2:1)' let root = parse(example, { from: '/c.css' }) let catched: any try { root.walk(() => { throw error }) } catch (e) { catched = e } is(catched, error) is(catched.postcssNode.toString(), 'a { a: 1; b: 2 }') is( catched.stack.replace(/.:\\/i, '/'), 'Error: T\n at /c.css:1:1\n at b (b.js:2:4)\n at a (a.js:2:1)' ) }) test('walkDecls() iterates', () => { let props: string[] = [] let indexes: number[] = [] let result = parse(example).walkDecls((decl, i) => { props.push(decl.prop) indexes.push(i) }) type(result, 'undefined') equal(props, ['a', 'b', 'c', 'd', 'e']) equal(indexes, [0, 1, 0, 0, 0]) }) test('walkDecls() iterates with changes', () => { let size = 0 parse(example).walkDecls((decl, i) => { decl.parent?.removeChild(i) size += 1 }) is(size, 5) }) test('walkDecls() breaks iteration', () => { let indexes: number[] = [] let result = parse(example).walkDecls((decl, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [0]) }) test('walkDecls() filters declarations by property name', () => { let css = parse('@page{a{one:1}}b{one:1;two:2}') let size = 0 css.walkDecls('one', decl => { is(decl.prop, 'one') size += 1 }) is(size, 2) }) test('walkDecls() breaks declarations filter by name', () => { let css = parse('@page{a{one:1}}b{one:1;two:2}') let size = 0 css.walkDecls('one', () => { size += 1 return false }) is(size, 1) }) test('walkDecls() filters declarations by property regexp', () => { let css = parse('@page{a{one:1}}b{one-x:1;two:2}') let size = 0 css.walkDecls(/one(-x)?/, () => { size += 1 }) is(size, 2) }) test('walkDecls() breaks declarations filters by regexp', () => { let css = parse('@page{a{one:1}}b{one-x:1;two:2}') let size = 0 css.walkDecls(/one(-x)?/, () => { size += 1 return false }) is(size, 1) }) test('walkComments() iterates', () => { let texts: string[] = [] let indexes: number[] = [] let result = parse(example).walkComments((comment, i) => { texts.push(comment.text) indexes.push(i) }) type(result, 'undefined') equal(texts, ['a', 'b', 'c']) equal(indexes, [1, 0, 1]) }) test('walkComments() iterates with changes', () => { let size = 0 parse(example).walkComments((comment, i) => { comment.parent?.removeChild(i) size += 1 }) is(size, 3) }) test('walkComments() breaks iteration', () => { let indexes: number[] = [] let result = parse(example).walkComments((comment, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [1]) }) test('walkRules() iterates', () => { let selectors: string[] = [] let indexes: number[] = [] let result = parse(example).walkRules((rule, i) => { selectors.push(rule.selector) indexes.push(i) }) type(result, 'undefined') equal(selectors, ['a', 'to', 'em']) equal(indexes, [0, 1, 0]) }) test('walkRules() iterates with changes', () => { let size = 0 parse(example).walkRules((rule, i) => { rule.parent?.removeChild(i) size += 1 }) is(size, 3) }) test('walkRules() breaks iteration', () => { let indexes: number[] = [] let result = parse(example).walkRules((rule, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [0]) }) test('walkRules() filters by selector', () => { let size = 0 parse('a{}b{}a{}').walkRules('a', rule => { is(rule.selector, 'a') size += 1 }) is(size, 2) }) test('walkRules() breaks selector filters', () => { let size = 0 parse('a{}b{}a{}').walkRules('a', () => { size += 1 return false }) is(size, 1) }) test('walkRules() filters by regexp', () => { let size = 0 parse('a{}a b{}b a{}').walkRules(/^a/, rule => { match(rule.selector, /^a/) size += 1 }) is(size, 2) }) test('walkRules() breaks selector regexp', () => { let size = 0 parse('a{}b a{}b a{}').walkRules(/^a/, () => { size += 1 return false }) is(size, 1) }) test('walkAtRules() iterates', () => { let names: string[] = [] let indexes: number[] = [] let result = parse(example).walkAtRules((atrule, i) => { names.push(atrule.name) indexes.push(i) }) type(result, 'undefined') equal(names, ['keyframes', 'media', 'page']) equal(indexes, [2, 3, 1]) }) test('walkAtRules() iterates with changes', () => { let size = 0 parse(example).walkAtRules((atrule, i) => { atrule.parent?.removeChild(i) size += 1 }) is(size, 3) }) test('walkAtRules() breaks iteration', () => { let indexes: number[] = [] let result = parse(example).walkAtRules((atrule, i) => { indexes.push(i) return false }) is(result, false) equal(indexes, [2]) }) test('walkAtRules() filters at-rules by name', () => { let css = parse('@page{@page 2{}}@media print{@page{}}') let size = 0 css.walkAtRules('page', atrule => { is(atrule.name, 'page') size += 1 }) is(size, 3) }) test('walkAtRules() breaks name filter', () => { let size = 0 parse('@page{@page{@page{}}}').walkAtRules('page', () => { size += 1 return false }) is(size, 1) }) test('walkAtRules() filters at-rules by name regexp', () => { let css = parse('@page{@page 2{}}@media print{@pages{}}') let size = 0 css.walkAtRules(/page/, () => { size += 1 }) is(size, 3) }) test('walkAtRules() breaks regexp filter', () => { let size = 0 parse('@page{@pages{@page{}}}').walkAtRules(/page/, () => { size += 1 return false }) is(size, 1) }) test('append() appends child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.append({ prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; b: 2; c: 3 }') is(rule.last?.raws.before, ' ') }) test('append() appends multiple children', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.append({ prop: 'c', value: '3' }, { prop: 'd', value: '4' }) is(rule.toString(), 'a { a: 1; b: 2; c: 3; d: 4 }') is(rule.last?.raws.before, ' ') }) test('append() has declaration shortcut', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.append({ prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; b: 2; c: 3 }') }) test('append() has rule shortcut', () => { let root = new Root() root.append({ selector: 'a' }) is(root.first?.toString(), 'a {}') }) test('append() has at-rule shortcut', () => { let root = new Root() root.append({ name: 'encoding', params: '"utf-8"' }) is(root.first?.toString(), '@encoding "utf-8"') }) test('append() has comment shortcut', () => { let root = new Root() root.append({ text: 'ok' }) is(root.first?.toString(), '/* ok */') }) test('append() receives root', () => { let css = parse('a {}') css.append(parse('b {}')) is(css.toString(), 'a {}b {}') }) test('append() reveives string', () => { let root = new Root() root.append('a{}b{}') let a = root.first as Rule a.append('color:black') is(root.toString(), 'a{color:black}b{}') type(a.first?.source, 'undefined') }) test('append() receives array', () => { let a = parse('a{ z-index: 1 }') let b = parse('b{ width: 1px; height: 2px }') let aRule = a.first as Rule let bRule = b.first as Rule aRule.append(bRule.nodes) is(a.toString(), 'a{ z-index: 1; width: 1px; height: 2px }') is(b.toString(), 'b{ }') }) test('append() move node on insert', () => { let a = parse('a{}') let b = parse('b{}') b.append(a.first as Rule) let bLast = b.last as Rule bLast.selector = 'b a' is(a.toString(), '') is(b.toString(), 'b{}b a{}') }) test('prepend() prepends child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.prepend({ prop: 'c', value: '3' }) is(rule.toString(), 'a { c: 3; a: 1; b: 2 }') is(rule.first?.raws.before, ' ') }) test('prepend() prepends multiple children', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.prepend({ prop: 'c', value: '3' }, { prop: 'd', value: '4' }) is(rule.toString(), 'a { c: 3; d: 4; a: 1; b: 2 }') is(rule.first?.raws.before, ' ') }) test('prepend() receive hash instead of declaration', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.prepend({ prop: 'c', value: '3' }) is(rule.toString(), 'a { c: 3; a: 1; b: 2 }') }) test('prepend() receives root', () => { let css = parse('a {}') css.prepend(parse('b {}')) is(css.toString(), 'b {}\na {}') }) test('prepend() receives string', () => { let css = parse('a {}') css.prepend('b {}') is(css.toString(), 'b {}\na {}') }) test('prepend() receives array', () => { let a = parse('a{ z-index: 1 }') let b = parse('b{ width: 1px; height: 2px }') let aRule = a.first as Rule let bRule = b.first as Rule aRule.prepend(bRule.nodes) is(a.toString(), 'a{ width: 1px; height: 2px; z-index: 1 }') }) test('prepend() works on empty container', () => { let root = parse('') root.prepend(new Rule({ selector: 'a' })) is(root.toString(), 'a {}') }) test('insertBefore() inserts child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.insertBefore(1, { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') is(rule.nodes[1].raws.before, ' ') }) test('insertBefore() works with nodes too', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.insertBefore(rule.nodes[1], { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') }) test('insertBefore() receive hash instead of declaration', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.insertBefore(1, { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') }) test('insertBefore() receives array', () => { let a = parse('a{ color: red; z-index: 1 }') let b = parse('b{ width: 1; height: 2 }') let aRule = a.first as Rule let bRule = b.first as Rule aRule.insertBefore(1, bRule.nodes) is(a.toString(), 'a{ color: red; width: 1; height: 2; z-index: 1 }') }) test('insertBefore() receives pre-existing child node - a', () => { let a = parse('a{ align-items: start; color: red; z-index: 1 }') let declA = (a.first as Rule).nodes[0] let declC = (a.first as Rule).nodes[2] declC.before(declA) is(a.toString(), 'a{ color: red; align-items: start; z-index: 1 }') }) test('insertBefore() receives pre-existing child node - b', () => { let a = parse('a{ align-items: start; color: red; z-index: 1 }') let declA = (a.first as Rule).nodes[0] let declC = (a.first as Rule).nodes[2] declA.before(declC) is(a.toString(), 'a{ z-index: 1; align-items: start; color: red }') }) test('insertBefore() has defined way of adding newlines', () => { let root = parse('a {}') root.insertBefore(root.first as Rule, 'b {}') root.insertBefore(root.first as Rule, 'c {}') is(root.toString(), 'c {}\nb {}\na {}') root = parse('other {}a {}') root.insertBefore(root.first as Rule, 'b {}') root.insertBefore(root.first as Rule, 'c {}') is(root.toString(), 'c {}b {}other {}a {}') root = parse('other {}\na {}') root.insertBefore(root.nodes[1] as Rule, 'b {}') root.insertBefore(root.nodes[1] as Rule, 'c {}') is(root.toString(), 'other {}\nc {}\nb {}\na {}') root = parse('other {}a {}') root.insertBefore(root.nodes[1] as Rule, 'b {}') root.insertBefore(root.nodes[1] as Rule, 'c {}') is(root.toString(), 'other {}c {}b {}a {}') }) test('insertAfter() inserts child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.insertAfter(0, { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') is(rule.nodes[1].raws.before, ' ') }) test('insertAfter() works with nodes too', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let aDecl = rule.first as Declaration rule.insertAfter(aDecl, { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') }) test('insertAfter() receive hash instead of declaration', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.insertAfter(0, { prop: 'c', value: '3' }) is(rule.toString(), 'a { a: 1; c: 3; b: 2 }') }) test('insertAfter() receives array', () => { let a = parse('a{ color: red; z-index: 1 }') let b = parse('b{ width: 1; height: 2 }') let aRule = a.first as Rule let bRule = b.first as Rule aRule.insertAfter(0, bRule.nodes) is(a.toString(), 'a{ color: red; width: 1; height: 2; z-index: 1 }') }) test('insertAfter() receives pre-existing child node - a', () => { let a = parse('a{ align-items: start; color: red; z-index: 1 }') let declA = (a.first as Rule).nodes[0] let declC = (a.first as Rule).nodes[2] declC.after(declA) is(a.toString(), 'a{ color: red; z-index: 1; align-items: start }') }) test('insertAfter() receives pre-existing child node - b', () => { let a = parse('a{ align-items: start; color: red; z-index: 1 }') let declA = (a.first as Rule).nodes[0] let declC = (a.first as Rule).nodes[2] declA.after(declC) is(a.toString(), 'a{ align-items: start; z-index: 1; color: red }') }) test('removeChild() removes by index', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.removeChild(1) is(rule.toString(), 'a { a: 1 }') }) test('removeChild() removes by node', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let bDecl = rule.last as Declaration rule.removeChild(bDecl) is(rule.toString(), 'a { a: 1 }') }) test('removeChild() cleans parent in removed node', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let aDecl = rule.first as Declaration rule.removeChild(aDecl) type(aDecl.parent, 'undefined') }) test('removeAll() removes all children', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let decl = rule.first as Declaration rule.removeAll() type(decl.parent, 'undefined') is(rule.toString(), 'a { }') }) test('replaceValues() replaces strings', () => { let css = parse('a{one:1}b{two:1 2}') let result = css.replaceValues('1', 'A') equal(result, css) is(css.toString(), 'a{one:A}b{two:A 2}') }) test('replaceValues() replaces regpexp', () => { let css = parse('a{one:1}b{two:1 2}') css.replaceValues(/\d/g, i => i + 'A') is(css.toString(), 'a{one:1A}b{two:1A 2A}') }) test('replaceValues() filters properties', () => { let css = parse('a{one:1}b{two:1 2}') css.replaceValues('1', { props: ['one'] }, 'A') is(css.toString(), 'a{one:A}b{two:1 2}') }) test('replaceValues() uses fast check', () => { let css = parse('a{one:1}b{two:1 2}') css.replaceValues('1', { fast: '2' }, 'A') is(css.toString(), 'a{one:1}b{two:A 2}') }) test('any() return true if all children return true', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule is( rule.every(i => i.type === 'decl' && /a|b/.test(i.prop)), true ) is( rule.every(i => i.type === 'decl' && /b/.test(i.prop)), false ) }) test('some() return true if all children return true', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule is( rule.some(i => i.type === 'decl' && i.prop === 'b'), true ) is( rule.some(i => i.type === 'decl' && i.prop === 'c'), false ) }) test('index() returns child index', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule is(rule.index(rule.nodes[1]), 1) }) test('index() returns argument if it is number', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule is(rule.index(2), 2) }) test('first() works for children-less nodes', () => { let atRule = parse('@charset "UTF-*"').first as AtRule type(atRule.first, 'undefined') }) test('last() works for children-less nodes', () => { let atRule = parse('@charset "UTF-*"').first as AtRule type(atRule.last, 'undefined') }) test('returns first child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let aDecl = rule.first as Declaration is(aDecl.prop, 'a') }) test('returns last child', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule let bDecl = rule.last as Declaration is(bDecl.prop, 'b') }) test('normalize() does not normalize new children with exists before', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.append({ prop: 'c', raws: { before: '\n ' }, value: '3' }) is(rule.toString(), 'a { a: 1; b: 2;\n c: 3 }') }) test('forces Declaration#value to be string', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule // @ts-expect-error rule.append({ prop: 'c', value: 3 }) let aDecl = rule.first as Declaration let cDecl = rule.last as Declaration type(aDecl.value, 'string') type(cDecl.value, 'string') }) test('updates parent in overrides.nodes in constructor', () => { let root = new Root({ nodes: [{ selector: 'a' }] }) let a = root.first as Rule equal(a.parent, root) root.append({ nodes: [{ prop: 'color', value: 'black' }], selector: 'b' }) let b = root.last as Rule let color = b.first as Declaration equal(color.parent, root.last) }) test('allows to clone nodes', () => { let root1 = parse('a { color: black; z-index: 1 } b {}') let root2 = new Root({ nodes: root1.nodes }) is(root1.toString(), 'a { color: black; z-index: 1 } b {}') is(root2.toString(), 'a { color: black; z-index: 1 } b {}') }) test('container.nodes can be sorted', () => { let root = parse('@b; @c; @a;') let b = root.nodes[0] root.nodes.sort((x, y) => { return (x as AtRule).name.localeCompare((y as AtRule).name) }) // Sorted nodes are reflected in "toString". is(root.toString(), ' @a;@b; @c;') // Sorted nodes are reflected in "walk". let result: string[] = [] root.walkAtRules(atRule => { result.push(atRule.name.trim()) }) is(result.join(' '), 'a b c') // Sorted nodes have the corect "index". is(root.index(b), 1) // Inserting after a sorted node results in the correct order. b.after('@d;') is(root.toString(), ' @a;@b;@d; @c;') }) test('ignores undefined on adding', () => { let rule = parse('a { a: 1; b: 2 }').first as Rule rule.append({ prop: 'c', value: '3' }, undefined) rule.prepend(undefined) rule.insertAfter(0, undefined) rule.insertBefore(0, undefined) rule.after(undefined) rule.before(undefined) is(rule.parent!.toString(), 'a { a: 1; b: 2; c: 3 }') }) test.run() postcss-8.4.49/test/css-syntax-error.test.ts000077500000000000000000000236641471446070100211100ustar00rootroot00000000000000import Concat from 'concat-with-sourcemaps' import { join, resolve as pathResolve } from 'node:path' import { pathToFileURL } from 'node:url' import * as pico from 'picocolors' import stripAnsi = require('strip-ansi') import { test } from 'uvu' import { equal, is, match, type } from 'uvu/assert' import postcss, { CssSyntaxError, Plugin, ProcessOptions, Rule } from '../lib/postcss.js' function isSyntaxError(e: unknown): e is CssSyntaxError { return e instanceof Error && e.name === 'CssSyntaxError' } async function catchError(cb: () => Promise): Promise { try { await cb() } catch (e) { if (isSyntaxError(e)) { return e } else { throw e } } throw new Error('Error was not thrown') } function parseError( css: string, opts?: Pick ): CssSyntaxError { try { postcss.parse(css, opts) } catch (e) { if (isSyntaxError(e)) { return e } else { throw e } } throw new Error('Error was not thrown') } test('saves source', () => { let error = parseError('a {\n content: "\n}') is(error instanceof CssSyntaxError, true) is(error.name, 'CssSyntaxError') is(error.message, ':2:12: Unclosed string') is(error.reason, 'Unclosed string') is(error.line, 2) is(error.column, 12) is(error.source, 'a {\n content: "\n}') equal(error.input, { column: error.column, endColumn: error.endColumn, endLine: error.endLine, line: error.line, source: error.source }) }) test('saves source with ranges', () => { let error = parseError('badword') is(error instanceof CssSyntaxError, true) is(error.name, 'CssSyntaxError') is(error.message, ':1:1: Unknown word') is(error.reason, 'Unknown word') is(error.line, 1) is(error.column, 1) is(error.endLine, 1) is(error.endColumn, 8) is(error.source, 'badword') equal(error.input, { column: error.column, endColumn: error.endColumn, endLine: error.endLine, line: error.line, source: error.source }) }) test('has stack trace', () => { match(parseError('a {\n content: "\n}').stack, /css-syntax-error\.test\.ts/) }) test('saves source with ranges', () => { let error = parseError('badword') is(error instanceof CssSyntaxError, true) is(error.name, 'CssSyntaxError') is(error.message, ':1:1: Unknown word') is(error.reason, 'Unknown word') is(error.line, 1) is(error.column, 1) is(error.endLine, 1) is(error.endColumn, 8) is(error.source, 'badword') equal(error.input, { column: error.column, endColumn: error.endColumn, endLine: error.endLine, line: error.line, source: error.source }) }) test('saves source with ranges', () => { let error = parseError('badword') is(error instanceof CssSyntaxError, true) is(error.name, 'CssSyntaxError') is(error.message, ':1:1: Unknown word') is(error.reason, 'Unknown word') is(error.line, 1) is(error.column, 1) is(error.endLine, 1) is(error.endColumn, 8) is(error.source, 'badword') equal(error.input, { column: error.column, endColumn: error.endColumn, endLine: error.endLine, line: error.line, source: error.source }) }) test('highlights broken line with colors', () => { is( parseError('#a .b c() {').showSourceCode(true), pico.bold(pico.red('>')) + pico.gray(' 1 | ') + pico.magenta('#a') + ' ' + pico.yellow('.b') + ' ' + pico.cyan('c') + pico.cyan('()') + ' ' + pico.yellow('{') + '\n ' + pico.gray(' | ') + pico.bold(pico.red('^')) ) }) test('highlights broken line', () => { is( parseError('a {\n content: "\n}').showSourceCode(false), ' 1 | a {\n' + '> 2 | content: "\n' + ' | ^\n' + ' 3 | }' ) }) test('highlights broken line, when indented with tabs', () => { is( parseError('a {\n\t \t content:\t"\n}').showSourceCode(false), ' 1 | a {\n' + '> 2 | \t \t content:\t"\n' + ' | \t \t \t^\n' + ' 3 | }' ) }) test('highlights small code example', () => { is(parseError('a {').showSourceCode(false), '> 1 | a {\n' + ' | ^') }) test('add leading space for line numbers', () => { let css = '\n\n\n\n\n\n\na {\n content: "\n}\n\n\n' is( parseError(css).showSourceCode(false), ' 7 | \n' + ' 8 | a {\n' + '> 9 | content: "\n' + ' | ^\n' + ' 10 | }\n' + ' 11 | ' ) }) test('cut minified css', () => { let css = '.a{position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.b{border:0;background;text-decoration:none;font-size:100%;}' + '.c{position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.d{position:absolute!important;clip:rect(1px,1px,1px,1px);}' is( parseError(css).showSourceCode(false), '> 1 | ,1px);}.b{border:0;background;text-decoration:none\n' + ' | ^' ) }) test('correct mark position on cut minified css', () => { let css = '.a{background;position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.b{border:0;text-decoration:none;font-size:100%;}' + '.c{position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.d{position:absolute!important;clip:rect(1px,1px,1px,1px);}' is( parseError(css).showSourceCode(false), '> 1 | .a{background;position:absolute!im\n' + ' | ^' ) }) test('highlight cut minified css with colors', () => { let css = '.a{position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.b{border:0;background;text-decoration:none;font-size:100%;}' + '.c{position:absolute!important;clip:rect(1px,1px,1px,1px);}' + '.d{position:absolute!important;clip:rect(1px,1px,1px,1px);}' is( parseError(css).showSourceCode(true), pico.bold(pico.red('>')) + pico.gray(' 1 | ') + ',1px' + pico.cyan(')') + pico.yellow(';') + pico.yellow('}') + pico.yellow('.b') + pico.yellow('{') + 'border' + pico.yellow(':') + '0' + pico.yellow(';') + 'background' + pico.yellow(';') + '' + 'text-decoration' + pico.yellow(':') + 'none' + '\n ' + pico.gray(' | ') + ' ' + pico.bold(pico.red('^')) ) }) test('prints with highlight', () => { is( stripAnsi(parseError('a {').toString()), 'CssSyntaxError: :1:1: Unclosed block\n' + '\n' + '> 1 | a {\n' + ' | ^\n' ) }) test('misses highlights without source content', () => { let error = parseError('a {') error.source = undefined is(error.toString(), 'CssSyntaxError: :1:1: Unclosed block') }) test('misses position without source', () => { let decl = postcss.decl({ prop: 'color', value: 'black' }) let error = decl.error('Test') is(error.toString(), 'CssSyntaxError: : Test') }) test('uses source map', () => { function urlOf(file: string): string { return pathToFileURL(join(__dirname, file)).toString() } let concat = new Concat(true, join(__dirname, 'build', 'all.css')) concat.add(urlOf('a.css'), 'a { }\n') concat.add(urlOf('b.css'), '\nb {\n') let error = parseError(concat.content.toString(), { from: join(__dirname, 'build', 'all.css'), map: { prev: concat.sourceMap } }) is(error.file, join(__dirname, 'b.css')) is(error.line, 2) type(error.source, 'undefined') equal(error.input, { column: 1, endColumn: error.endColumn, endLine: error.endLine, file: join(__dirname, 'build', 'all.css'), line: 3, source: 'a { }\n\nb {\n', url: urlOf(join('build', 'all.css')) }) }) test('works with path in sources', () => { function pathOf(file: string): string { return join(__dirname, file) } let concat = new Concat(true, join(__dirname, 'build', 'all.css')) concat.add(pathOf('a.css'), 'a { }\n') concat.add(pathOf('b.css'), '\nb {\n') let error = parseError(concat.content.toString(), { from: join(__dirname, 'build', 'all.css'), map: { prev: concat.sourceMap } }) is(error.file, join(__dirname, 'b.css')) is(error.line, 2) type(error.source, 'undefined') equal(error.input, { column: 1, endColumn: error.endColumn, endLine: error.endLine, file: join(__dirname, 'build', 'all.css'), line: 3, source: 'a { }\n\nb {\n', url: pathToFileURL(pathOf(join('build', 'all.css'))).toString() }) }) test('shows origin source', () => { let input = postcss([() => {}]).process('a{}', { from: '/a.css', map: { inline: false }, to: '/b.css' }) let error = parseError('a{', { from: '/b.css', map: { prev: input.map } }) is(error.source, 'a{}') }) test('does not uses wrong source map', () => { let error = parseError('a { }\nb {', { from: 'build/all.css', map: { prev: { file: 'build/all.css', mappings: 'A', sources: ['a.css', 'b.css'], version: 3 } } }) is(error.file, pathResolve('build/all.css')) }) test('set source plugin', () => { let a = postcss.parse('a{}').first as Rule let error = a.error('Error', { plugin: 'PL' }) is(error.plugin, 'PL') match(error.toString(), /^CssSyntaxError: PL: :1:1: Error/) }) test('set source plugin automatically', async () => { let plugin: Plugin = { Once(css) { if (css.first) { throw css.first.error('Error') } }, postcssPlugin: 'test-plugin' } let error = await catchError(() => postcss([plugin]).process('a{}', { from: undefined }) ) is(error.plugin, 'test-plugin') match(error.toString(), /test-plugin/) }) test('set plugin automatically in async', async () => { let plugin: Plugin = { Once(css) { return new Promise((resolve, reject) => { if (css.first) { reject(css.first.error('Error')) } }) }, postcssPlugin: 'async-plugin' } let error = await catchError(() => postcss([plugin]).process('a{}', { from: undefined }) ) is(error.plugin, 'async-plugin') }) test.run() postcss-8.4.49/test/declaration.test.ts000077500000000000000000000026221471446070100201210ustar00rootroot00000000000000import { test } from 'uvu' import { is } from 'uvu/assert' import { Declaration, parse, Rule } from '../lib/postcss.js' test('initializes with properties', () => { let decl = new Declaration({ prop: 'color', value: 'black' }) is(decl.prop, 'color') is(decl.value, 'black') }) test('returns boolean important', () => { let decl = new Declaration({ prop: 'color', value: 'black' }) decl.important = true is(decl.toString(), 'color: black !important') }) test('inserts default spaces', () => { let decl = new Declaration({ prop: 'color', value: 'black' }) let rule = new Rule({ selector: 'a' }) rule.append(decl) is(rule.toString(), 'a {\n color: black\n}') }) test('clones spaces from another declaration', () => { let root = parse('a{color:black}') let rule = root.first as Rule let decl = new Declaration({ prop: 'margin', value: '0' }) rule.append(decl) is(root.toString(), 'a{color:black;margin:0}') }) test('converts value to string', () => { // @ts-expect-error let decl = new Declaration({ prop: 'color', value: 1 }) is(decl.value, '1') }) test('detects variable declarations', () => { let prop = new Declaration({ prop: '--color', value: 'black' }) is(prop.variable, true) let sass = new Declaration({ prop: '$color', value: 'black' }) is(sass.variable, true) let decl = new Declaration({ prop: 'color', value: 'black' }) is(decl.variable, false) }) test.run() postcss-8.4.49/test/document.test.ts000077500000000000000000000012411471446070100174460ustar00rootroot00000000000000import { test } from 'uvu' import { is, match } from 'uvu/assert' import Document from '../lib/document.js' import { parse, Result } from '../lib/postcss.js' test('generates result without map', () => { let root = parse('a {}') let document = new Document() document.append(root) let result = document.toResult() is(result instanceof Result, true) is(result.css, 'a {}') }) test('generates result with map', () => { let root = parse('a {}') let document = new Document() document.append(root) let result = document.toResult({ map: true }) is(result instanceof Result, true) match(result.css, /a {}\n\/\*# sourceMappingURL=/) }) test.run() postcss-8.4.49/test/errors.ts000066400000000000000000000012061471446070100161640ustar00rootroot00000000000000import { PluginCreator } from '../lib/postcss.js' const plugin: PluginCreator<{ a: number }> = opts => { // THROWS 'opts' is possibly 'undefined' console.log(opts.a) // THROWS Property 'b' does not exist on type '{ a: number; }' console.log(opts?.b) return { postcssPlugin: 'remover', // THROWS Property 'Decl' does not exist on type 'Helpers'. Comment(decl, { Decl }) { // THROWS Property 'prop' does not exist on type 'Comment_' console.log(decl.prop) // THROWS Property 'removeChild' does not exist on type 'Comment_' decl.removeChild(1) } } } plugin.postcss = true export default plugin postcss-8.4.49/test/fromJSON.test.ts000077500000000000000000000033751471446070100172770ustar00rootroot00000000000000import { test } from 'uvu' import { instance, is, throws } from 'uvu/assert' import * as v8 from 'v8' import postcss, { Declaration, Input, Root, Rule } from '../lib/postcss.js' test('rehydrates a JSON AST', () => { let cssWithMap = postcss().process( '.foo { color: red; font-size: 12pt; } /* abc */ @media (width: 60em) { }', { from: 'x.css', map: { inline: true }, stringifier: postcss.stringify } ).css let root = postcss.parse(cssWithMap) let json = root.toJSON() let serialized = v8.serialize(json) let deserialized = v8.deserialize(serialized) let rehydrated = postcss.fromJSON(deserialized as object) as Root rehydrated.nodes[0].remove() is(rehydrated.nodes.length, 3) is( postcss().process(rehydrated, { from: undefined, map: { inline: true }, stringifier: postcss.stringify }).css, `/* abc */ @media (width: 60em) { } /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInguY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFzQyxRQUFRLEVBQUUsdUJBQXVCIiwiZmlsZSI6InRvLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5mb28geyBjb2xvcjogcmVkOyBmb250LXNpemU6IDEycHQ7IH0gLyogYWJjICovIEBtZWRpYSAod2lkdGg6IDYwZW0pIHsgfSJdfQ== */` ) }) test('rehydrates an array of Nodes via JSON.stringify', () => { let root = postcss.parse('.cls { color: orange; }') let rule = root.first as Rule let json = JSON.stringify(rule.nodes) let rehydrated = postcss.fromJSON(JSON.parse(json)) as any instance(rehydrated[0], Declaration) instance(rehydrated[0].source?.input, Input) }) test('throws when rehydrating an invalid JSON AST', () => { throws(() => { postcss.fromJSON({ type: 'not-a-node-type' }) }, 'Unknown node type: not-a-node-type') }) test.run() postcss-8.4.49/test/integration.js000077500000000000000000000002621471446070100171650ustar00rootroot00000000000000#!/usr/bin/env node let { testOnReal } = require('postcss-parser-tests') let { parse } = require('../') testOnReal(css => parse(css).toResult({ map: { annotation: false } })) postcss-8.4.49/test/lazy-result.test.ts000077500000000000000000000035731471446070100201350ustar00rootroot00000000000000import { SourceMapGenerator } from 'source-map-js' import { test } from 'uvu' import { equal, is, type } from 'uvu/assert' import LazyResult from '../lib/lazy-result.js' import Processor from '../lib/processor.js' let processor = new Processor() test('contains AST', () => { let result = new LazyResult(processor, 'a {}', {}) is(result.root.type, 'root') }) test('will stringify css', () => { let result = new LazyResult(processor, 'a {}', {}) is(result.css, 'a {}') }) test('stringifies css', () => { let result = new LazyResult(processor, 'a {}', {}) is(`${result}`, result.css) }) test('has content alias for css', () => { let result = new LazyResult(processor, 'a {}', {}) is(result.content, 'a {}') }) test('has map only if necessary', () => { let result1 = new LazyResult(processor, '', {}) type(result1.map, 'undefined') let result2 = new LazyResult(processor, '', {}) type(result2.map, 'undefined') let result3 = new LazyResult(processor, '', { map: { inline: false } }) is(result3.map instanceof SourceMapGenerator, true) }) test('contains options', () => { let result = new LazyResult(processor, 'a {}', { to: 'a.css' }) equal(result.opts, { to: 'a.css' }) }) test('contains warnings', () => { let result = new LazyResult(processor, 'a {}', {}) equal(result.warnings(), []) }) test('contains messages', () => { let result = new LazyResult(processor, 'a {}', {}) equal(result.messages, []) }) test('executes on finally callback', () => { let callbackHaveBeenCalled = 0 let mockCallback = (): void => { callbackHaveBeenCalled++ } return new LazyResult(processor, 'a {}', {}) .finally(mockCallback) .then(() => { is(callbackHaveBeenCalled, 1) }) }) test('prints its object type', () => { let result = new LazyResult(processor, 'a {}', {}) is(Object.prototype.toString.call(result), '[object LazyResult]') }) test.run() postcss-8.4.49/test/list.test.ts000077500000000000000000000024161471446070100166100ustar00rootroot00000000000000import { test } from 'uvu' import { equal } from 'uvu/assert' import { list } from '../lib/postcss.js' test('space() splits list by spaces', () => { equal(list.space('a b'), ['a', 'b']) }) test('space() trims values', () => { equal(list.space(' a b '), ['a', 'b']) }) test('space() checks quotes', () => { equal(list.space('"a b\\"" \'\''), ['"a b\\""', "''"]) }) test('space() checks functions', () => { equal(list.space('f( )) a( () )'), ['f( ))', 'a( () )']) }) test('space() does not split on escaped spaces', () => { equal(list.space('a\\ b'), ['a\\ b']) }) test('space() works from variable', () => { let space = list.space equal(space('a b'), ['a', 'b']) }) test('comma() splits list by spaces', () => { equal(list.comma('a, b'), ['a', 'b']) }) test('comma() adds last empty', () => { equal(list.comma('a, b,'), ['a', 'b', '']) }) test('comma() checks quotes', () => { equal(list.comma('"a,b\\"", \'\''), ['"a,b\\""', "''"]) }) test('comma() checks functions', () => { equal(list.comma('f(,)), a(,(),)'), ['f(,))', 'a(,(),)']) }) test('comma() does not split on escaped commas', () => { equal(list.comma('a\\, b'), ['a\\, b']) }) test('comma() works from variable', () => { let comma = list.comma equal(comma('a, b'), ['a', 'b']) }) test.run() postcss-8.4.49/test/location.test.ts000066400000000000000000000124661471446070100174500ustar00rootroot00000000000000import { test } from 'uvu' import { equal } from 'uvu/assert' import { AtRule, Comment, Declaration, Node, parse, Rule } from '../lib/postcss.js' function checkOffset(source: string, node: Node, expected: string): void { let start = node.source!.start!.offset let end = node.source!.end!.offset equal(source.slice(start, end), expected) } test('rule', () => { let source = '.a{}' let css = parse(source) let rule = css.first as Rule checkOffset(source, rule, '.a{}') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 4, line: 1, offset: 4 }) }) test('single decl (no semicolon)', () => { let source = '.a{b:c}' let css = parse(source) let rule = css.first as Rule let decl = rule.first as Declaration checkOffset(source, rule, '.a{b:c}') checkOffset(source, decl, 'b:c') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 7, line: 1, offset: 7 }) equal(decl.source!.start, { column: 4, line: 1, offset: 3 }) equal(decl.source!.end, { column: 6, line: 1, offset: 6 }) }) test('single decl (with semicolon)', () => { let source = '.a{b:c;}' let css = parse(source) let rule = css.first as Rule let decl = rule.first as Declaration checkOffset(source, rule, '.a{b:c;}') checkOffset(source, decl, 'b:c;') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 8, line: 1, offset: 8 }) equal(decl.source!.start, { column: 4, line: 1, offset: 3 }) equal(decl.source!.end, { column: 7, line: 1, offset: 7 }) }) test('two decls', () => { let source = '.a{b:c;d:e}' let css = parse(source) let rule = css.first as Rule let decl1 = rule.first as Declaration let decl2 = decl1.next() as Declaration checkOffset(source, decl1, 'b:c;') checkOffset(source, decl2, 'd:e') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 11, line: 1, offset: 11 }) equal(decl1.source!.start, { column: 4, line: 1, offset: 3 }) equal(decl1.source!.end, { column: 7, line: 1, offset: 7 }) equal(decl2.source!.start, { column: 8, line: 1, offset: 7 }) equal(decl2.source!.end, { column: 10, line: 1, offset: 10 }) }) test('...rule nested in rule', () => { let source = '.a{.b{}}' let css = parse(source) let rule = css.first as Rule let rule2 = rule.first as Rule checkOffset(source, rule, '.a{.b{}}') checkOffset(source, rule2, '.b{}') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 8, line: 1, offset: 8 }) equal(rule2.source!.start, { column: 4, line: 1, offset: 3 }) equal(rule2.source!.end, { column: 7, line: 1, offset: 7 }) }) test('at-rule with semicolon', () => { let source = '@a b;' let css = parse(source) let atrule = css.first as AtRule checkOffset(source, atrule, '@a b;') equal(atrule.source!.start, { column: 1, line: 1, offset: 0 }) equal(atrule.source!.end, { column: 5, line: 1, offset: 5 }) }) test('unclosed at-rule', () => { let source = '@a b' let css = parse(source) let atrule = css.first as AtRule checkOffset(source, atrule, '@a b') equal(atrule.source!.start, { column: 1, line: 1, offset: 0 }) equal(atrule.source!.end, { column: 4, line: 1, offset: 4 }) }) test('unclosed at-rule in at-rule', () => { let source = '@a{@b c}' let css = parse(source) let atrule = css.first as AtRule let atrule2 = atrule.first as AtRule checkOffset(source, atrule, '@a{@b c}') checkOffset(source, atrule2, '@b c') equal(atrule.source!.start, { column: 1, line: 1, offset: 0 }) equal(atrule.source!.end, { column: 8, line: 1, offset: 8 }) equal(atrule2.source!.start, { column: 4, line: 1, offset: 3 }) equal(atrule2.source!.end, { column: 7, line: 1, offset: 7 }) }) test('at-rule with body', () => { let source = '@a{}' let css = parse(source) let atrule = css.first as AtRule checkOffset(source, atrule, '@a{}') equal(atrule.source!.start, { column: 1, line: 1, offset: 0 }) equal(atrule.source!.end, { column: 4, line: 1, offset: 4 }) }) test('at-rule nested in atrule', () => { let source = '@a{@b{}}' let css = parse(source) let atrule = css.first as Rule let atrule2 = atrule.first as Rule checkOffset(source, atrule, '@a{@b{}}') checkOffset(source, atrule2, '@b{}') equal(atrule.source!.start, { column: 1, line: 1, offset: 0 }) equal(atrule.source!.end, { column: 8, line: 1, offset: 8 }) equal(atrule2.source!.start, { column: 4, line: 1, offset: 3 }) equal(atrule2.source!.end, { column: 7, line: 1, offset: 7 }) }) test('comment', () => { let source = '/*a*/' let css = parse(source) let rule = css.first as Comment checkOffset(source, rule, '/*a*/') equal(rule.source!.start, { column: 1, line: 1, offset: 0 }) equal(rule.source!.end, { column: 5, line: 1, offset: 5 }) }) test.run() postcss-8.4.49/test/map.test.ts000077500000000000000000000437511471446070100164210ustar00rootroot00000000000000import { existsSync, lstatSync, mkdirSync, readdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs' import { join, parse, resolve } from 'path' import { SourceMapConsumer, SourceMapGenerator } from 'source-map-js' import { pathToFileURL } from 'url' import { test } from 'uvu' import { equal, is, match, type } from 'uvu/assert' import postcss, { Root, Rule, SourceMap } from '../lib/postcss.js' import PreviousMap from '../lib/previous-map.js' function consumer(map: SourceMap): any { return (SourceMapConsumer as any).fromSourceMap(map) } function read(result: { css: string }): any { let prev = new PreviousMap(result.css, {}) return prev.consumer() } let dir = join(__dirname, 'map-fixtures') let doubler = postcss((css: Root) => { css.walkDecls(decl => { decl.parent?.prepend(decl.clone()) }) }) let lighter = postcss((css: Root) => { css.walkDecls(decl => { decl.value = 'white' }) }) function deleteDir(path: string): void { if (existsSync(path)) { readdirSync(path).forEach(i => { let file = join(path, i) if (lstatSync(file).isDirectory()) { deleteDir(file) } else { unlinkSync(file) } }) rmdirSync(path) } } test.after.each(() => { deleteDir(dir) }) test('adds map field only on request', () => { type(postcss([() => {}]).process('a {}').map, 'undefined') }) test('return map generator', () => { let map = postcss([() => {}]).process('a {}', { map: { inline: false } }).map is(map instanceof SourceMapGenerator, true) }) test('generate right source map', () => { let css = 'a {\n color: black;\n }' let processor = postcss((root: Root) => { root.walkRules(rule => { rule.selector = 'strong' }) root.walkDecls(decl => { decl.parent?.prepend(decl.clone({ prop: 'background', value: 'black' })) }) }) let result = processor.process(css, { from: 'a.css', map: true, to: 'b.css' }) let map = read(result) is(map.file, 'b.css') equal(map.originalPositionFor({ column: 0, line: 1 }), { column: 0, line: 1, name: null, source: 'a.css' }) equal(map.originalPositionFor({ column: 2, line: 1 }), { column: 0, line: 1, name: null, source: 'a.css' }) equal(map.originalPositionFor({ column: 2, line: 2 }), { column: 2, line: 2, name: null, source: 'a.css' }) equal(map.originalPositionFor({ column: 2, line: 3 }), { column: 2, line: 2, name: null, source: 'a.css' }) equal(map.originalPositionFor({ column: 14, line: 3 }), { column: 14, line: 2, name: null, source: 'a.css' }) equal(map.originalPositionFor({ column: 2, line: 4 }), { column: 2, line: 3, name: null, source: 'a.css' }) }) test('generates right source map for @layer', () => { let css = '@layer extensions {\n @layer one, two\n}' let processor = postcss(() => { /* noop */ }) let result = processor.process(css, { from: 'a.css', map: true, to: 'b.css' }) read(result) }) test('changes previous source map', () => { let css = 'a { color: black }' let doubled = doubler.process(css, { from: 'a.css', map: { inline: false }, to: 'b.css' }) let lighted = lighter.process(doubled.css, { from: 'b.css', map: { prev: doubled.map }, to: 'c.css' }) let map = consumer(lighted.map) equal(map.originalPositionFor({ column: 18, line: 1 }), { column: 4, line: 1, name: null, source: 'a.css' }) }) test('adds source map annotation', () => { let css = 'a { }/*# sourceMappingURL=a.css.map */' let result = postcss([() => {}]).process(css, { from: 'a.css', map: { inline: false }, to: 'b.css' }) is(result.css, 'a { }\n/*# sourceMappingURL=b.css.map */') }) test('misses source map annotation, if user ask', () => { let css = 'a { }' let result = postcss([() => {}]).process(css, { from: 'a.css', map: { annotation: false }, to: 'b.css' }) is(result.css, css) }) test('misses source map annotation, if previous map missed it', () => { let css = 'a { }' let step1 = postcss([() => {}]).process(css, { from: 'a.css', map: { annotation: false }, to: 'b.css' }) let step2 = postcss([() => {}]).process(step1.css, { from: 'b.css', map: { prev: step1.map }, to: 'c.css' }) is(step2.css, css) }) test('uses user path in annotation, relative to options.to', () => { let result = postcss([() => {}]).process('a { }', { from: 'source/a.css', map: { annotation: 'maps/b.map' }, to: 'build/b.css' }) is(result.css, 'a { }\n/*# sourceMappingURL=maps/b.map */') let map = consumer(result.map) is(map.file, join('..', 'b.css')) is( map.originalPositionFor({ column: 0, line: 1 }).source, '../../source/a.css' ) }) test('generates inline map', () => { let css = 'a { }' let inline = postcss([() => {}]).process(css, { from: 'a.css', map: { inline: true }, to: 'b.css' }) type(inline.map, 'undefined') match(inline.css, /# sourceMappingURL=data:/) let separated = postcss([() => {}]).process(css, { from: 'a.css', map: { inline: false }, to: 'b.css' }) let base64 = Buffer.from(separated.map.toString()).toString('base64') let end = inline.css.slice(-base64.length - 3) is(end, base64 + ' */') }) test('generates inline map by default', () => { let inline = postcss([() => {}]).process('a { }', { from: 'a.css', map: true, to: 'b.css' }) match(inline.css, /# sourceMappingURL=data:/) }) test('generates separated map if previous map was not inlined', () => { let step1 = doubler.process('a { color: black }', { from: 'a.css', map: { inline: false }, to: 'b.css' }) let step2 = lighter.process(step1.css, { from: 'b.css', map: { prev: step1.map }, to: 'c.css' }) type(step2.map, 'object') }) test('generates separated map on annotation option', () => { let result = postcss([() => {}]).process('a { }', { from: 'a.css', map: { annotation: false }, to: 'b.css' }) type(result.map, 'object') }) test('allows change map type', () => { let step1 = postcss([() => {}]).process('a { }', { from: 'a.css', map: { inline: true }, to: 'b.css' }) let step2 = postcss([() => {}]).process(step1.css, { from: 'b.css', map: { inline: false }, to: 'c.css' }) type(step2.map, 'object') match(step2.css, /# sourceMappingURL=c\.css\.map/) }) test('misses check files on requires', () => { mkdirSync(dir) let file = join(dir, 'a.css') let step1 = doubler.process('a { }', { from: 'a.css', map: { inline: false }, to: file }) writeFileSync(file + '.map', step1.map.toString()) let step2 = lighter.process(step1.css, { from: file, map: false, to: 'b.css' }) type(step2.map, 'undefined') }) test('works in subdirs', () => { let result = doubler.process('a { }', { from: 'from/a.css', map: { inline: false }, to: 'out/b.css' }) match(result.css, /sourceMappingURL=b.css.map/) let map = consumer(result.map) is(map.file, 'b.css') equal(map.sources, ['../from/a.css']) }) test('uses map from subdir', () => { let step1 = doubler.process('a { }', { from: 'a.css', map: { inline: false }, to: 'out/b.css' }) let step2 = doubler.process(step1.css, { from: 'out/b.css', map: { prev: step1.map }, to: 'out/two/c.css' }) let source = consumer(step2.map).originalPositionFor({ column: 0, line: 1 }).source is(source, '../../a.css') let step3 = doubler.process(step2.css, { from: 'c.css', map: { prev: step2.map }, to: 'd.css' }) source = consumer(step3.map).originalPositionFor({ column: 0, line: 1 }).source is(source, '../../a.css') }) test('uses map from subdir if it inlined', () => { let step1 = doubler.process('a { }', { from: 'a.css', map: true, to: 'out/b.css' }) let step2 = doubler.process(step1.css, { from: 'out/b.css', map: { inline: false }, to: 'out/two/c.css' }) let source = consumer(step2.map).originalPositionFor({ column: 0, line: 1 }).source is(source, '../../a.css') }) test('uses map from subdir if it written as a file', () => { let step1 = doubler.process('a { }', { from: 'source/a.css', map: { annotation: 'maps/b.css.map', inline: false }, to: 'one/b.css' }) let source = consumer(step1.map).originalPositionFor({ column: 0, line: 1 }).source is(source, '../../source/a.css') let file = join(dir, 'one', 'maps', 'b.css.map') mkdirSync(dir) mkdirSync(join(dir, 'one')) mkdirSync(join(dir, 'one', 'maps')) writeFileSync(file, step1.map.toString()) let step2 = doubler.process(step1.css, { from: join(dir, 'one', 'b.css'), map: true, to: join(dir, 'two', 'c.css') }) source = consumer(step2.map).originalPositionFor({ column: 0, line: 1 }).source is(source, '../source/a.css') }) test('works with different types of maps', () => { let step1 = doubler.process('a { }', { from: 'a.css', map: { inline: false }, to: 'b.css' }) let map = step1.map let maps = [map, consumer(map), map.toJSON(), map.toString()] for (let i of maps) { let step2 = doubler.process(step1.css, { from: 'b.css', map: { prev: i }, to: 'c.css' }) let source = consumer(step2.map).originalPositionFor({ column: 0, line: 1 }).source is(source, 'a.css') } }) test('sets source content by default', () => { let result = doubler.process('a { }', { from: 'a.css', map: true, to: 'out/b.css' }) is(read(result).sourceContentFor('../a.css'), 'a { }') }) test('misses source content on request', () => { let result = doubler.process('a { }', { from: 'a.css', map: { sourcesContent: false }, to: 'out/b.css' }) is(read(result).sourceContentFor('../a.css'), null) }) test('misses source content if previous not have', () => { let step1 = doubler.process('a { }', { from: 'a.css', map: { sourcesContent: false }, to: 'out/a.css' }) let file1 = postcss.parse(step1.css, { from: 'a.css', map: { prev: step1.map } }) let file2 = postcss.parse('b { }', { from: 'b.css', map: true }) if (file1.first) file2.append(file1.first.clone()) let step2 = file2.toResult({ map: true, to: 'c.css' }) is(read(step2).sourceContentFor('b.css'), null) }) test('misses source content on request in multiple steps', () => { let step1 = doubler.process('a { }', { from: 'a.css', map: { sourcesContent: true }, to: 'out/a.css' }) let file1 = postcss.parse(step1.css, { from: 'a.css', map: { prev: step1.map } }) let file2 = postcss.parse('b { }', { from: 'b.css', map: true }) if (file1.first) file2.append(file1.first.clone()) let step2 = file2.toResult({ map: { sourcesContent: false }, to: 'c.css' }) let map = read(step2) is(map.sourceContentFor('b.css'), null) is(map.sourceContentFor('../a.css'), null) }) test('detects input file name from map', () => { let one = doubler.process('a { }', { map: true, to: 'a.css' }) let two = doubler.process(one.css, { map: { prev: one.map } }) is(two.root.first?.source?.input.file, resolve('a.css')) }) test('works without file names', () => { let step1 = doubler.process('a { }', { map: true }) let step2 = doubler.process(step1.css) match(step2.css, /a { }\n\/\*/) }) test('supports UTF-8', () => { let step1 = doubler.process('a { }', { from: 'вход.css', map: true, to: 'шаг1.css' }) let step2 = doubler.process(step1.css, { from: 'шаг1.css', to: 'выход.css' }) is(read(step2).file, 'выход.css') }) test('generates map for node created manually', () => { let contenter = postcss((css: Root) => { if (css.first && css.first.type === 'rule') { css.first.prepend({ selector: 'b' }) } }) let result = contenter.process('a:after{\n}', { map: true }) let map = read(result) equal(map.originalPositionFor({ column: 5, line: 2 }), { column: 0, line: 1, name: null, source: '' }) }) test('uses input file name as output file name', () => { let result = doubler.process('a{}', { from: 'a.css', map: { inline: false } }) is(result.map.toJSON().file, 'a.css') }) test('uses to.css as default output name', () => { let result = doubler.process('a{}', { map: { inline: false } }) is(result.map.toJSON().file, 'to.css') }) test('supports annotation comment in any place', () => { let css = '/*# sourceMappingURL=a.css.map */a { }' let result = postcss([() => {}]).process(css, { from: 'a.css', map: { inline: false }, to: 'b.css' }) is(result.css, 'a { }\n/*# sourceMappingURL=b.css.map */') }) test('does not update annotation on request', () => { let css = 'a { }/*# sourceMappingURL=a.css.map */' let result = postcss([() => {}]).process(css, { from: 'a.css', map: { annotation: false, inline: false }, to: 'b.css' }) is(result.css, 'a { }/*# sourceMappingURL=a.css.map */') }) test('clears source map', () => { let css1 = postcss.root().toResult({ map: true }).css let css2 = postcss.root().toResult({ map: true }).css let root = postcss.root() root.append(css1) root.append(css2) let css = root.toResult({ map: true }).css is(css.match(/sourceMappingURL/g)?.length, 1) }) test('uses Windows line separation too', () => { let result = postcss([() => {}]).process('a {\r\n}', { map: true }) match(result.css, /a {\r\n}\r\n\/\*# sourceMappingURL=/) }) test('`map.from` should override the source map sources', () => { let result = postcss([() => {}]).process('a{}', { map: { from: 'file:///dir/a.css', inline: false } }) equal(result.map.toJSON().sources, ['file:///dir/a.css']) }) test('preserves absolute urls in `to`', () => { let result = postcss([() => {}]).process('a{}', { from: '/dir/to/a.css', map: { inline: false }, to: 'http://example.com/a.css' }) is(result.map.toJSON().file, 'http://example.com/a.css') }) test('preserves absolute urls in sources', () => { let result = postcss([() => {}]).process('a{}', { from: 'file:///dir/a.css', map: { inline: false }, to: 'http://example.com/a.css' }) equal(result.map.toJSON().sources, ['file:///dir/a.css']) }) test('uses absolute path on request', () => { let result = postcss([() => {}]).process('a{}', { from: '/dir/a.css', map: { absolute: true, inline: false }, to: '/dir/b.css' }) let root = '/' if (process.platform === 'win32') { root = '/' + parse(process.cwd()).root.replace(/\\/g, '/') } equal(result.map.toJSON().sources, [`file://${root}dir/a.css`]) }) test('preserves absolute urls in sources from previous map', () => { let result1 = postcss([() => {}]).process('a{}', { from: 'http://example.com/a.css', map: true, to: 'http://example.com/b.css' }) let result2 = postcss([() => {}]).process(result1.css, { map: { inline: false }, to: 'http://example.com/c.css' }) is(result2.root.source?.input.file, 'http://example.com/b.css') equal(result2.map.toJSON().sources, ['http://example.com/a.css']) }) test('allows dynamic annotations', () => { let result = postcss([() => {}]).process('a{}', { map: { annotation(to, root) { let rule = root.first as Rule return to + '-' + rule.selector + '.map' } }, to: 'out.css' }) is(result.css, 'a{}\n/*# sourceMappingURL=out.css-a.map */') }) test('uses URLs in sources', () => { let result = postcss([() => {}]).process('a{}', { from: 'a b.css', map: { inline: false }, to: 'dir/b.css' }) equal(result.map.toJSON().sources, ['../a%20b.css']) }) test('generates correct inline map with empty processor', () => { let result = postcss().process('a {} /*hello world*/', { map: true }) match(result.css, /a {} \/\*hello world\*\/\n\/\*# sourceMappingURL=/) }) test('generates correct inline map and multiple comments', () => { let css = 'a {}/*# sourceMappingURL=a.css.map */\n' + '/*# sourceMappingURL=b.css.map */\n' + 'b {}\n/*# sourceMappingURL=c.css.map */' let result = postcss().process(css, { map: true }) match(result.css, /a {}\nb {}\n\/\*# sourceMappingURL=/) }) test('generates correct sources with empty processor', () => { let result = postcss().process('a {} /*hello world*/', { from: 'a.css', map: { inline: false }, to: 'b.css' }) equal(result.map.toJSON().sources, ['a.css']) }) test('generates map object with empty processor', () => { let result = postcss().process('a {} /*hello world*/', { from: 'a.css', map: true, to: 'b.css' }) let map = read(result) equal(map.originalPositionFor({ column: 0, line: 1 }), { column: 0, line: 1, name: null, source: 'a.css' }) }) test('supports previous map with empty processor', () => { let result1 = postcss().process('a{}', { from: '/a.css', map: { inline: false, sourcesContent: true }, to: '/b.css' }) equal(result1.map.toJSON(), { file: 'b.css', mappings: 'AAAA', names: [], sources: ['a.css'], sourcesContent: ['a{}'], version: 3 }) let result2 = postcss().process(result1.css, { from: '/b.css', map: { prev: result1.map }, to: '/c.css' }) equal(result2.map.toJSON().sources, ['a.css']) equal(result2.map.toJSON().sourcesContent, ['a{}']) }) test('supports previous inline map with empty processor', () => { let result1 = postcss().process('a{}', { from: '/a.css', map: true, to: '/b.css' }) let result2 = postcss().process(result1.css, { from: '/b.css', to: '/c.css' }) let root3 = postcss.parse(result2.css, { from: '/c.css' }) match((root3.source?.input.origin(1, 0) as any).file, 'a.css') }) test('absolute sourcemaps have source contents', () => { let result = postcss([() => {}]).process('a{}', { from: '/dir/to/a.css', map: { absolute: true, inline: false } }) equal(result.map.toJSON().sources, [ pathToFileURL('/dir/to/a.css').toString() ]) equal(result.map.toJSON().sourcesContent, ['a{}']) }) test.run() postcss-8.4.49/test/no-work-result.test.ts000066400000000000000000000127011471446070100205400ustar00rootroot00000000000000import postcss = require('../lib/postcss.js') import stringify = require('../lib/stringify.js') import { spy } from 'nanospy' import { SourceMapGenerator } from 'source-map-js' import { test } from 'uvu' import { equal, instance, is, not, throws, type } from 'uvu/assert' import NoWorkResult from '../lib/no-work-result.js' import parse from '../lib/parse.js' import Processor from '../lib/processor.js' let processor = new Processor() test('contains AST on root access', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) is(result.root.nodes.length, 1) }) test('has async() method', async () => { let noWorkResult = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) let result1 = await noWorkResult let result2 = await noWorkResult equal(result1, result2) }) test('has sync() method', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }).sync() is(result.root.nodes.length, 1) }) test('throws error on sync()', () => { let noWorkResult = new NoWorkResult(processor, 'a {', { from: '/a.css' }) try { noWorkResult.root } catch {} throws(() => noWorkResult.sync(), 'AAA') }) test('returns cached root on second access', async () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) result.root is(result.root.nodes.length, 1) not.throws(() => result.sync()) }) test('contains css', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) is(result.css, 'a {}') }) test('stringifies css', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) equal(`${result}`, result.css) }) test('has content alias for css', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) is(result.content, 'a {}') }) test('has map only if necessary', () => { let result1 = new NoWorkResult(processor, '', { from: '/a.css' }) type(result1.map, 'undefined') let result2 = new NoWorkResult(processor, '', { from: '/a.css' }) type(result2.map, 'undefined') let result3 = new NoWorkResult(processor, '', { from: '/a.css', map: { inline: false } }) is(result3.map instanceof SourceMapGenerator, true) }) test('contains simple properties', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css', to: 'a.css' }) instance(result.processor, Processor) equal(result.opts, { from: '/a.css', to: 'a.css' }) equal(result.messages, []) equal(result.warnings(), []) }) test('executes on finally callback', () => { let cb = spy() return new NoWorkResult(processor, 'a {}', { from: '/a.css' }) .finally(cb) .then(() => { equal(cb.callCount, 1) }) }) test('prints its object type', () => { let result = new NoWorkResult(processor, 'a {}', { from: '/a.css' }) is(Object.prototype.toString.call(result), '[object NoWorkResult]') }) test('no work result matches lazy result', async () => { let source = '.foo { color: red }\n'; let noWorkResult = await postcss([]).process(source, { from: 'foo.css', map: false }); let lazyResult = await postcss([]).process(source, { from: 'foo.css', map: false, syntax: { parse, stringify } }); equal(noWorkResult.css, lazyResult.css); }) // https://github.com/postcss/postcss/issues/1911 test('no work result matches lazy result when map is true', async () => { let source = '.foo { color: red }\n'; let noWorkResult = await postcss([]).process(source, { from: 'foo.css', map: true }); equal(noWorkResult.css, '.foo { color: red }\n\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEiLCJmaWxlIjoiZm9vLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5mb28geyBjb2xvcjogcmVkIH1cbiJdfQ== */'); let lazyResult = await postcss([]).process(source, { from: 'foo.css', map: true, syntax: { parse, stringify } }); equal(lazyResult.css, '.foo { color: red }\n\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxXQUFXIiwiZmlsZSI6ImZvby5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuZm9vIHsgY29sb3I6IHJlZCB9XG4iXX0= */'); }) test('no work result matches lazy result when the source contains an inline source map', async () => { let source = '.foo { color: red }\n\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxXQUFXIiwiZmlsZSI6ImZvby5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuZm9vIHsgY29sb3I6IHJlZCB9XG4iXX0= */\n'; let noWorkResult = await postcss([]).process(source, { from: 'foo.css', map: false }); let lazyResult = await postcss([]).process(source, { from: 'foo.css', map: false, syntax: { parse, stringify } }); equal(noWorkResult.css, lazyResult.css); }) test('no work result matches lazy result when map is true and the source contains an inline source map', async () => { let source = '.foo { color: red }\n\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxXQUFXIiwiZmlsZSI6ImZvby5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuZm9vIHsgY29sb3I6IHJlZCB9XG4iXX0= */\n'; let lazyResult = await postcss([]).process(source, { from: 'bar.css', map: true, syntax: { parse, stringify } }); let noWorkResult = await postcss([]).process(source, { from: 'bar.css', map: true }); equal(noWorkResult.css, lazyResult.css); }) test.run() postcss-8.4.49/test/node.test.ts000077500000000000000000000415351471446070100165670ustar00rootroot00000000000000import { resolve } from 'path' import { test } from 'uvu' import { equal, is, not, type } from 'uvu/assert' import postcss, { AnyNode, AtRule, CssSyntaxError, Declaration, Document, parse, Plugin, Result, Root, Rule } from '../lib/postcss.js' function stringify(node: AnyNode, builder: (str: string) => void): void { if (node.type === 'rule') { builder(node.selector) } } test('error() generates custom error', () => { let file = resolve('a.css') let css = parse('a{}', { from: file }) let a = css.first as Rule let error = a.error('Test') is(error instanceof CssSyntaxError, true) is(error.message, file + ':1:1: Test') }) test('error() generates custom error for nodes without source', () => { let rule = new Rule({ selector: 'a' }) let error = rule.error('Test') is(error.message, ': Test') }) test('error() highlights index', () => { let root = parse('a { b: c }') let a = root.first as Rule let b = a.first as Declaration let error = b.error('Bad semicolon', { index: 1 }) is(error.showSourceCode(false), '> 1 | a { b: c }\n' + ' | ^') }) test('error() highlights word', () => { let root = parse('a { color: x red }') let a = root.first as Rule let color = a.first as Declaration let error = color.error('Wrong color', { word: 'x' }) is( error.showSourceCode(false), '> 1 | a { color: x red }\n' + ' | ^' ) }) test('error() highlights word in multiline string', () => { let root = parse('a { color: red\n x }') let a = root.first as Rule let color = a.first as Declaration let error = color.error('Wrong color', { word: 'x' }) is( error.showSourceCode(false), ' 1 | a { color: red\n' + '> 2 | x }\n' + ' | ^' ) }) test('warn() attaches a warning to the result object', async () => { let warning: any let warner: Plugin = { Once(css, { result }) { warning = css.first?.warn(result, 'FIRST!') }, postcssPlugin: 'warner' } let result = await postcss([warner]).process('a{}', { from: undefined }) is(warning.type, 'warning') is(warning.text, 'FIRST!') is(warning.plugin, 'warner') equal(result.warnings(), [warning]) }) test('warn() accepts options', () => { let warner = (css: Root, result: Result): void => { css.first?.warn(result, 'FIRST!', { index: 1 }) } let result = postcss([warner]).process('a{}') is(result.warnings().length, 1) let warning = result.warnings()[0] as any is(warning.index, 1) }) test('remove() removes node from parent', () => { let rule = new Rule({ selector: 'a' }) let decl = new Declaration({ prop: 'color', value: 'black' }) rule.append(decl) decl.remove() is(rule.nodes.length, 0) type(decl.parent, 'undefined') }) test('replaceWith() inserts new node', () => { let rule = new Rule({ selector: 'a' }) rule.append({ prop: 'color', value: 'black' }) rule.append({ prop: 'width', value: '1px' }) rule.append({ prop: 'height', value: '1px' }) let node = new Declaration({ prop: 'min-width', value: '1px' }) let width = rule.nodes[1] let result = width.replaceWith(node) equal(result, width) is( rule.toString(), 'a {\n' + ' color: black;\n' + ' min-width: 1px;\n' + ' height: 1px\n' + '}' ) }) test('replaceWith() inserts new root', () => { let root = new Root() root.append(new AtRule({ name: 'import', params: '"a.css"' })) let a = new Root() a.append(new Rule({ selector: 'a' })) a.append(new Rule({ selector: 'b' })) root.first?.replaceWith(a) is(root.toString(), 'a {}\nb {}') }) test('replaceWith() replaces node', () => { let css = parse('a{one:1;two:2}') let a = css.first as Rule let one = a.first as Declaration let result = one.replaceWith({ prop: 'fix', value: 'fixed' }) is(result.prop, 'one') type(result.parent, 'undefined') is(css.toString(), 'a{fix:fixed;two:2}') }) test('replaceWith() can include itself', () => { let css = parse('a{one:1;two:2}') let a = css.first as Rule let one = a.first as Declaration let beforeDecl = { prop: 'fix1', value: 'fixedOne' } let afterDecl = { prop: 'fix2', value: 'fixedTwo' } one.replaceWith(beforeDecl, one, afterDecl) is(css.toString(), 'a{fix1:fixedOne;one:1;fix2:fixedTwo;two:2}') }) test('toString() accepts custom stringifier', () => { is(new Rule({ selector: 'a' }).toString(stringify), 'a') }) test('toString() accepts custom syntax', () => { is(new Rule({ selector: 'a' }).toString({ stringify }), 'a') }) test('assign() assigns to node', () => { let decl = new Declaration({ prop: 'white-space', value: 'overflow-wrap' }) is(decl.prop, 'white-space') is(decl.value, 'overflow-wrap') decl.assign({ prop: 'word-wrap', value: 'break-word' }) is(decl.prop, 'word-wrap') is(decl.value, 'break-word') }) test('clone() clones nodes', () => { let rule = new Rule({ selector: 'a' }) rule.append({ prop: 'color', value: '/**/black' }) let clone = rule.clone() type(clone.parent, 'undefined') equal(rule.first?.parent, rule) equal(clone.first?.parent, clone) clone.append({ prop: 'z-index', value: '1' }) is(rule.nodes.length, 1) }) test('clone() overrides properties', () => { let rule = new Rule({ selector: 'a' }) let clone = rule.clone({ selector: 'b' }) is(clone.selector, 'b') }) test('clone() keeps code style', () => { let css = parse('@page 1{a{color:black;}}') is(css.clone().toString(), '@page 1{a{color:black;}}') }) test('clone() works with null in raws', () => { let decl = new Declaration({ prop: 'color', // @ts-expect-error raws: { value: null }, value: 'black' }) let clone = decl.clone() equal(Object.keys(clone.raws), ['value']) }) test('cloneBefore() clones and insert before current node', () => { let rule = new Rule({ raws: { after: '' }, selector: 'a' }) rule.append({ prop: 'z-index', raws: { before: '' }, value: '1' }) let result = rule.first?.cloneBefore({ value: '2' }) equal(result, rule.first) is(rule.toString(), 'a {z-index: 2;z-index: 1}') }) test('cloneAfter() clones and insert after current node', () => { let rule = new Rule({ raws: { after: '' }, selector: 'a' }) rule.append({ prop: 'z-index', raws: { before: '' }, value: '1' }) let result = rule.first?.cloneAfter({ value: '2' }) equal(result, rule.last) is(rule.toString(), 'a {z-index: 1;z-index: 2}') }) test('before() insert before current node', () => { let rule = new Rule({ raws: { after: '' }, selector: 'a' }) rule.append({ prop: 'z-index', raws: { before: '' }, value: '1' }) let result = rule.first?.before('color: black') equal(result, rule.last) is(rule.toString(), 'a {color: black;z-index: 1}') }) test('after() insert after current node', () => { let rule = new Rule({ raws: { after: '' }, selector: 'a' }) rule.append({ prop: 'z-index', raws: { before: '' }, value: '1' }) let result = rule.first?.after('color: black') equal(result, rule.first) is(rule.toString(), 'a {z-index: 1;color: black}') }) test('next() returns next node', () => { let css = parse('a{one:1;two:2}') let a = css.first as Rule equal(a.first?.next(), a.last) type(a.last?.next(), 'undefined') }) test('next() returns undefined on no parent', () => { let css = parse('') type(css.next(), 'undefined') }) test('prev() returns previous node', () => { let css = parse('a{one:1;two:2}') let a = css.first as Rule equal(a.last?.prev(), a.first) type(a.first?.prev(), 'undefined') }) test('prev() returns undefined on no parent', () => { let css = parse('') type(css.prev(), 'undefined') }) test('toJSON() cleans parents inside', () => { let rule = new Rule({ selector: 'a' }) rule.append({ prop: 'color', value: 'b' }) let json = rule.toJSON() as any type(json.parent, 'undefined') type(json.nodes[0].parent, 'undefined') is( JSON.stringify(rule), '{"raws":{},"selector":"a","type":"rule","nodes":[' + '{"raws":{},"prop":"color","value":"b","type":"decl"}' + '],"inputs":[]}' ) }) test('toJSON() converts custom properties', () => { let root = new Root() as any root._cache = [1] root._hack = { toJSON() { return 'hack' } } equal(root.toJSON(), { _cache: [1], _hack: 'hack', inputs: [], nodes: [], raws: {}, type: 'root' }) }) test('raw() has shortcut to stringifier', () => { let rule = new Rule({ selector: 'a' }) is(rule.raw('before'), '') }) test('root() returns root', () => { let css = parse('@page{a{color:black}}') let page = css.first as AtRule let a = page.first as Rule let color = a.first as Declaration equal(color.root(), css) }) test('root() returns parent of parents', () => { let rule = new Rule({ selector: 'a' }) rule.append({ prop: 'color', value: 'black' }) equal(rule.first?.root(), rule) }) test('root() returns self on root', () => { let rule = new Rule({ selector: 'a' }) equal(rule.root(), rule) }) test('root() returns root in document', () => { let css = new Document({ nodes: [parse('@page{a{color:black}}')] }) let root = css.first as Root let page = root.first as AtRule let a = page.first as Rule let color = a.first as Declaration equal(color.root(), root) }) test('root() on root in document returns same root', () => { let document = new Document() let root = new Root() document.append(root) equal(document.first?.root(), root) }) test('root() returns self on document', () => { let document = new Document() equal(document.root(), document) }) test('cleanRaws() cleans style recursivelly', () => { let css = parse('@page{a{color:black}}') css.cleanRaws() is(css.toString(), '@page {\n a {\n color: black\n }\n}') let page = css.first as AtRule let a = page.first as Rule let color = a.first as Declaration type(page.raws.before, 'undefined') type(color.raws.before, 'undefined') type(page.raws.between, 'undefined') type(color.raws.between, 'undefined') type(page.raws.after, 'undefined') }) test('cleanRaws() keeps between on request', () => { let css = parse('@page{a{color:black}}') css.cleanRaws(true) is(css.toString(), '@page{\n a{\n color:black\n }\n}') let page = css.first as AtRule let a = page.first as Rule let color = a.first as Declaration not.type(page.raws.between, 'undefined') not.type(color.raws.between, 'undefined') type(page.raws.before, 'undefined') type(color.raws.before, 'undefined') type(page.raws.after, 'undefined') }) test('positionInside() returns position when node starts mid-line', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration equal(one.positionInside(6), { column: 12, line: 1 }) }) test('positionInside() returns position when before contains newline', () => { let css = parse('a {\n one: X}') let a = css.first as Rule let one = a.first as Declaration equal(one.positionInside(6), { column: 9, line: 2 }) }) test('positionInside() returns position when node contains newlines', () => { let css = parse('a {\n\tone: 1\n\t\tX\n3}') let a = css.first as Rule let one = a.first as Declaration equal(one.positionInside(10), { column: 4, line: 3 }) }) test('positionInside() returns position after AST mutations', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration equal(a.positionInside(15), { column: 3, line: 3 }) equal(two.positionInside(1), { column: 3, line: 3 }) one.remove() equal(a.positionInside(15), { column: 3, line: 3 }) equal(two.positionInside(1), { column: 3, line: 3 }) }) test('positionBy() returns position for word', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration equal(one.positionBy({ word: 'one' }), { column: 6, line: 1 }) equal(one.positionBy({ word: 'X' }), { column: 11, line: 1 }) equal(a.positionBy({ word: '}' }), { column: 14, line: 1 }) }) test('positionBy() returns position for word after AST mutations', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration equal(a.positionBy({ word: 'two' }), { column: 2, line: 3 }) equal(two.positionBy({ word: 'two' }), { column: 2, line: 3 }) one.remove() equal(a.positionBy({ word: 'two' }), { column: 2, line: 3 }) equal(two.positionBy({ word: 'two' }), { column: 2, line: 3 }) }) test('positionBy() returns position for index', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration equal(one.positionBy({ index: 1 }), { column: 7, line: 1 }) }) test('positionBy() returns position for index after AST mutations', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration equal(a.positionBy({ index: 15 }), { column: 3, line: 3 }) equal(two.positionBy({ index: 1 }), { column: 3, line: 3 }) one.remove() equal(a.positionBy({ index: 15 }), { column: 3, line: 3 }) equal(two.positionBy({ index: 1 }), { column: 3, line: 3 }) }) test('rangeBy() returns range for word', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration equal(one.rangeBy({ word: 'one' }), { end: { column: 9, line: 1 }, start: { column: 6, line: 1 } }) }) test('rangeBy() returns range for word when offsets are missing', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration // @ts-expect-error if (one.source?.start) delete one.source.start.offset; // @ts-expect-error if (one.source?.end) delete one.source.end.offset; equal(one.rangeBy({ word: 'one' }), { end: { column: 9, line: 1 }, start: { column: 6, line: 1 } }) }) test('rangeBy() returns range for word even after AST mutations', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration equal(a.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) equal(two.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) one.remove() equal(a.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) equal(two.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) }) test('rangeBy() returns range for word even after AST mutations when offsets are missing', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration // @ts-expect-error if (a.source?.start) delete a.source.start.offset; // @ts-expect-error if (a.source?.end) delete a.source.end.offset; // @ts-expect-error if (two.source?.start) delete two.source.start.offset; // @ts-expect-error if (two.source?.end) delete two.source.end.offset; equal(a.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) equal(two.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) one.remove() equal(a.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) equal(two.rangeBy({ word: 'two' }), { end: { column: 5, line: 3 }, start: { column: 2, line: 3 } }) }) test('rangeBy() returns range for index and endIndex', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration equal(one.rangeBy({ endIndex: 3, index: 1 }), { end: { column: 9, line: 1 }, start: { column: 7, line: 1 } }) }) test('rangeBy() returns range for index and endIndex when offsets are missing', () => { let css = parse('a { one: X }') let a = css.first as Rule let one = a.first as Declaration // @ts-expect-error if (one.source?.start) delete one.source.start.offset; // @ts-expect-error if (one.source?.end) delete one.source.end.offset; equal(one.rangeBy({ endIndex: 3, index: 1 }), { end: { column: 9, line: 1 }, start: { column: 7, line: 1 } }) }) test('rangeBy() returns range for index and endIndex after AST mutations', () => { let css = parse('a {\n\tone: 1;\n\ttwo: 2;}') let a = css.first as Rule let one = a.first as Declaration let two = one.next() as Declaration equal(a.rangeBy({ endIndex: 17, index: 15 }), { end: { column: 5, line: 3 }, start: { column: 3, line: 3 } }) equal(two.rangeBy({ endIndex: 3, index: 1 }), { end: { column: 5, line: 3 }, start: { column: 3, line: 3 } }) one.remove() equal(a.rangeBy({ endIndex: 17, index: 15 }), { end: { column: 5, line: 3 }, start: { column: 3, line: 3 } }) equal(two.rangeBy({ endIndex: 3, index: 1 }), { end: { column: 5, line: 3 }, start: { column: 3, line: 3 } }) }) test.run() postcss-8.4.49/test/old-node.js000066400000000000000000000004721471446070100163430ustar00rootroot00000000000000// eslint-disable-next-line globalThis = Function('return this')() let Module = require('module') let originalRequire = Module.prototype.require Module.prototype.require = function (request) { if (request.startsWith('node:')) { request = request.slice(5) } return originalRequire.call(this, request) } postcss-8.4.49/test/parse.test.ts000077500000000000000000000144051471446070100167500ustar00rootroot00000000000000import { readFileSync } from 'fs' import { resolve } from 'path' import { eachTest, jsonify, testPath } from 'postcss-parser-tests' import { test } from 'uvu' import { equal, is, match, not, throws } from 'uvu/assert' import { AtRule, Declaration, parse, Root, Rule } from '../lib/postcss.js' test('works with file reads', () => { let stream = readFileSync(testPath('atrule-empty.css')) is(parse(stream) instanceof Root, true) }) eachTest((name, css, json) => { test(`parses ${name}`, () => { css = css.replace(/\r\n/g, '\n') let parsed = jsonify(parse(css, { from: name })) equal(parsed, json) }) }) test('parses UTF-8 BOM', () => { let css = parse('\uFEFF@host { a {\f} }') equal(css.nodes[0].raws.before, '') }) test('should has true at hasBOM property', () => { let css = parse('\uFEFF@host { a {\f} }') is(css.first?.source?.input.hasBOM, true) }) test('should has false at hasBOM property', () => { let css = parse('@host { a {\f} }') is(css.first?.source?.input.hasBOM, false) }) test('parses carrier return', () => { throws(() => { parse('@font-face{ font:(\r/*);} body { a: "a*/)} a{}"}') }, /:1:46: Unclosed string/) }) test('saves source file', () => { let css = parse('a {}', { from: 'a.css' }) is(css.first?.source?.input.css, 'a {}') is(css.first?.source?.input.file, resolve('a.css')) is(css.first?.source?.input.from, resolve('a.css')) }) test('keeps absolute path in source', () => { let css = parse('a {}', { from: 'http://example.com/a.css' }) is(css.first?.source?.input.file, 'http://example.com/a.css') is(css.first?.source?.input.from, 'http://example.com/a.css') }) test('saves source file on previous map', () => { let root1 = parse('a {}', { map: { inline: true } }) let css = root1.toResult({ map: { inline: true } }).css let root2 = parse(css) is(root2.first?.source?.input.file, resolve('to.css')) }) test('sets unique ID for file without name', () => { let css1 = parse('a {}') let css2 = parse('a {}') match(String(css1.first?.source?.input.id), /^$/) match(String(css1.first?.source?.input.from), /^$/) is.not(css2.first?.source?.input.id, css1.first?.source?.input.id) }) test('sets parent node', () => { let file = testPath('atrule-rules.css') let css = parse(readFileSync(file)) let support = css.first as AtRule let keyframes = support.first as AtRule let from = keyframes.first as Rule let decl = from.first as Declaration is(decl.parent, from) is(from.parent, keyframes) is(support.parent, css) is(keyframes.parent, support) }) test('ignores wrong close bracket', () => { let root = parse('a { p: ()) }') let a = root.first as Rule let decl = a.first as Declaration is(decl.value, '())') }) test('parses unofficial --mixins', () => { let root = parse(':root { --x { color: pink; }; }') let rule = root.first as Rule let prop = rule.first as Rule is(prop.selector, '--x') }) test('ignores symbols before declaration', () => { let root = parse('a { :one: 1 }') let a = root.first as Rule let prop = a.first as Declaration is(prop.raws.before, ' :') }) test('parses double semicolon after rule', () => { is(parse('a { };;').toString(), 'a { };;') }) test('parses a functional property', () => { let root = parse('a { b(c): d }') let a = root.first as Rule let b = a.first as Declaration is(b.prop, 'b(c)') }) test('parses a functional tagname', () => { let root = parse('a { b(c): d {} }') let a = root.first as Rule let b = a.first as Rule is(b.selector, 'b(c): d') }) test('throws on unclosed blocks', () => { throws(() => { parse('\na {\n') }, /:2:1: Unclosed block/) }) test('throws on unnecessary block close', () => { throws(() => { parse('a {\n} }') }, /:2:3: Unexpected }/) }) test('throws on unclosed comment', () => { throws(() => { parse('\n/*\n ') }, /:2:1: Unclosed comment/) }) test('throws on unclosed quote', () => { throws(() => { parse('\n"\n\na ') }, /:2:1: Unclosed string/) }) test('throws on unclosed bracket', () => { throws(() => { parse(':not(one() { }') }, /:1:5: Unclosed bracket/) }) test('throws on property without value', () => { throws(() => { parse('a { b;}') }, /:1:5: Unknown word/) throws(() => { parse('a { b b }') }, /:1:5: Unknown word/) throws(() => { parse('a { b(); }') }, /:1:5: Unknown word/) }) test('throws on nameless at-rule', () => { throws(() => { parse('@') }, /:1:1: At-rule without name/) }) test('throws on property without semicolon', () => { throws(() => { parse('a { one: filter(a:"") two: 2 }') }, /:1:21: Missed semicolon/) }) test('throws on double colon', () => { throws(() => { parse('a { one:: 1 }') }, /:1:9: Double colon/) }) test('do not throws on comment in between', () => { parse('a { b/* c */: 1 }') }) test('throws on two words in between', () => { throws(() => { parse('a { b c: 1 }') }, /:1:7: Unknown word/) }) test('throws on just colon', () => { throws(() => { parse(':') }, /:1:1: Unknown word/) throws(() => { parse(' : ') }, /:1:2: Unknown word/) }) test('does not suggest different parsers for CSS', () => { let error: any try { parse('a { one:: 1 }', { from: 'app.css' }) } catch (e) { error = e } not.match(error.message, /postcss-less|postcss-scss/) }) test('suggests postcss-scss for SCSS sources', () => { throws(() => { parse('a { #{var}: 1 }', { from: 'app.scss' }) }, /postcss-scss/) }) test('suggests postcss-sass for Sass sources', () => { throws(() => { parse('a\n #{var}: 1', { from: 'app.sass' }) }, /postcss-sass/) }) test('suggests postcss-less for Less sources', () => { throws(() => { parse('.@{my-selector} { }', { from: 'app.less' }) }, /postcss-less/) }) test('should give the correct column of missed semicolon with !important', () => { let error: any try { parse('a { \n color: red !important\n background-color: black;\n}') } catch (e) { error = e } match(error.message, /2:26: Missed semicolon/) }) test('should give the correct column of missed semicolon without !important', () => { let error: any try { parse('a { \n color: red\n background-color: black;\n}') } catch (e) { error = e } match(error.message, /2:15: Missed semicolon/) }) test.run() postcss-8.4.49/test/postcss.test.ts000077500000000000000000000114121471446070100173270ustar00rootroot00000000000000import postcss = require('../lib/postcss.js') import { restoreAll, spyOn } from 'nanospy' import { test } from 'uvu' import { equal, is, match, throws, type } from 'uvu/assert' import postcssDefault, { PluginCreator, Root } from '../lib/postcss.js' import Processor from '../lib/processor.js' test.after.each(() => { restoreAll() }) test('default matches module.exports', () => { is(postcss, postcssDefault) }) test('creates plugins list', () => { let processor = postcss() is(processor instanceof Processor, true) equal(processor.plugins, []) }) test('saves plugins list', () => { let a = (): void => {} let b = (): void => {} equal(postcss(a, b).plugins, [a, b]) }) test('saves plugins list as array', () => { let a = (): void => {} let b = (): void => {} equal(postcss([a, b]).plugins, [a, b]) }) test('takes plugin from other processor', () => { let a = (): void => {} let b = (): void => {} let c = (): void => {} let other = postcss([a, b]) equal(postcss([other, c]).plugins, [a, b, c]) }) test('takes plugins from a a plugin returning a processor', () => { let a = (): void => {} let b = (): void => {} let c = (): void => {} let other = postcss([a, b]) let meta = (() => other) as PluginCreator meta.postcss = true equal(postcss([other, c]).plugins, [a, b, c]) }) test('contains parser', () => { is(postcss.parse('').type, 'root') }) test('contains stringifier', () => { type(postcss.stringify, 'function') }) test('allows to build own CSS', () => { let root = postcss.root({ raws: { after: '\n' } }) let comment = postcss.comment({ text: 'Example' }) let media = postcss.atRule({ name: 'media', params: 'screen' }) let rule = postcss.rule({ selector: 'a' }) let decl = postcss.decl({ prop: 'color', value: 'black' }) root.append(comment) rule.append(decl) media.append(rule) root.append(media) is( root.toString(), '/* Example */\n' + '@media screen {\n' + ' a {\n' + ' color: black\n' + ' }\n' + '}\n' ) }) test('allows to build own CSS with Document', () => { let document = postcss.document() let root = postcss.root({ raws: { after: '\n' } }) let comment = postcss.comment({ text: 'Example' }) let media = postcss.atRule({ name: 'media', params: 'screen' }) let rule = postcss.rule({ selector: 'a' }) let decl = postcss.decl({ prop: 'color', value: 'black' }) root.append(comment) rule.append(decl) media.append(rule) root.append(media) document.append(root) is( document.toString(), '/* Example */\n' + '@media screen {\n' + ' a {\n' + ' color: black\n' + ' }\n' + '}\n' ) }) test('contains list module', () => { equal(postcss.list.space('a b'), ['a', 'b']) }) test('works with null', () => { throws(() => { // @ts-expect-error postcss([() => {}]).process(null).css }, /PostCSS received null instead of CSS string/) }) test('has deprecated method to create plugins', () => { let warn = spyOn(console, 'warn', () => {}) let plugin = (postcss as any).plugin('test', (filter?: string) => { return (root: Root) => { root.walkDecls(filter ?? 'two', i => { i.remove() }) } }) equal(warn.callCount, 0) let func1: any = postcss(plugin).plugins[0] is(func1.postcssPlugin, 'test') match(func1.postcssVersion, /\d+.\d+.\d+/) equal(warn.callCount, 1) let func2: any = postcss(plugin()).plugins[0] equal(func2.postcssPlugin, func1.postcssPlugin) equal(func2.postcssVersion, func1.postcssVersion) let result1 = postcss(plugin('one')).process('a{ one: 1; two: 2 }') is(result1.css, 'a{ two: 2 }') let result2 = postcss(plugin).process('a{ one: 1; two: 2 }') is(result2.css, 'a{ one: 1 }') equal(warn.callCount, 1) match(warn.calls[0][0], /postcss\.plugin was deprecated/) }) test('creates a shortcut to process css', async () => { let warn = spyOn(console, 'warn', () => {}) let plugin = (postcss as any).plugin('test', (str?: string) => { return (root: Root) => { root.walkDecls(i => { i.value = str ?? 'bar' }) } }) let result1 = plugin.process('a{value:foo}') is(result1.css, 'a{value:bar}') let result2 = plugin.process('a{value:foo}', {}, 'baz') is(result2.css, 'a{value:baz}') let result = await plugin.process('a{value:foo}', { from: 'a' }, 'baz') equal(result.opts, { from: 'a' }) is(result.css, 'a{value:baz}') equal(warn.callCount, 1) }) test('does not call plugin constructor', () => { let warn = spyOn(console, 'warn', () => {}) let calls = 0 let plugin = (postcss as any).plugin('test', () => { calls += 1 return () => {} }) is(calls, 0) postcss(plugin).process('a{}') is(calls, 1) postcss(plugin()).process('a{}') is(calls, 2) equal(warn.callCount, 1) }) test.run() postcss-8.4.49/test/previous-map.test.ts000077500000000000000000000210151471446070100202600ustar00rootroot00000000000000import { existsSync, lstatSync, mkdirSync, readdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs' import { join } from 'path' import { SourceMapConsumer } from 'source-map-js' import { pathToFileURL } from 'url' import { test } from 'uvu' import { equal, is, match, not, throws, type } from 'uvu/assert' import { parse } from '../lib/postcss.js' let dir = join(__dirname, 'prevmap-fixtures') let mapObj = { file: null, mappings: '', names: [], sources: [], version: 3 } let map = JSON.stringify(mapObj) function deleteDir(path: string): void { if (existsSync(path)) { readdirSync(path).forEach(i => { let file = join(path, i) if (lstatSync(file).isDirectory()) { deleteDir(file) } else { unlinkSync(file) } }) rmdirSync(path) } } test.after.each(() => { deleteDir(dir) }) test('misses property if no map', () => { type(parse('a{}').source?.input.map, 'undefined') }) test('creates property if map present', () => { let root = parse('a{}', { map: { prev: map } }) is(root.source?.input.map.text, map) }) test('returns consumer', () => { let obj = parse('a{}', { map: { prev: map } }).source?.input.map.consumer() is(obj instanceof SourceMapConsumer, true) }) test('sets annotation property', () => { let mapOpts = { map: { prev: map } } let root1 = parse('a{}', mapOpts) type(root1.source?.input.map.annotation, 'undefined') let root2 = parse('a{}/*# sourceMappingURL=a.css.map */', mapOpts) is(root2.source?.input.map.annotation, 'a.css.map') }) test('checks previous sources content', () => { let map2: any = { file: 'b', mappings: '', names: [], sources: ['a'], version: 3 } let opts = { map: { prev: map2 } } is(parse('a{}', opts).source?.input.map.withContent(), false) map2.sourcesContent = ['a{}'] is(parse('a{}', opts).source?.input.map.withContent(), true) }) test('decodes base64 maps', () => { let b64 = Buffer.from(map).toString('base64') let css = 'a{}\n' + `/*# sourceMappingURL=data:application/json;base64,${b64} */` is(parse(css).source?.input.map.text, map) }) test('decodes base64 UTF-8 maps', () => { let b64 = Buffer.from(map).toString('base64') let css = 'a{}\n/*# sourceMappingURL=data:application/json;' + 'charset=utf-8;base64,' + b64 + ' */' is(parse(css).source?.input.map.text, map) }) test('accepts different name for base64 maps with UTF-8 encoding', () => { let b64 = Buffer.from(map).toString('base64') let css = 'a{}\n/*# sourceMappingURL=data:application/json;' + 'charset=utf8;base64,' + b64 + ' */' is(parse(css).source?.input.map.text, map) }) test('decodes URI maps', () => { let uri = 'data:application/json,' + decodeURI(map) let css = `a{}\n/*# sourceMappingURL=${uri} */` is(parse(css).source?.input.map.text, map) }) test('decodes URI UTF-8 maps', () => { let uri = decodeURI(map) let css = 'a{}\n/*# sourceMappingURL=data:application/json;' + 'charset=utf-8,' + uri + ' */' is(parse(css).source?.input.map.text, map) }) test('accepts different name for URI maps with UTF-8 encoding', () => { let uri = decodeURI(map) let css = 'a{}\n/*# sourceMappingURL=data:application/json;' + 'charset=utf8,' + uri + ' */' is(parse(css).source?.input.map.text, map) }) test('removes map on request', () => { let uri = 'data:application/json,' + decodeURI(map) let css = `a{}\n/*# sourceMappingURL=${uri} */` let input = parse(css, { map: { prev: false } }).source?.input type(input?.map, 'undefined') }) test('raises on unknown inline encoding', () => { let css = 'a { }\n/*# sourceMappingURL=data:application/json;' + 'md5,68b329da9893e34099c7d8ad5cb9c940*/' throws(() => { parse(css) }, 'Unsupported source map encoding md5') }) test('raises on unknown map format', () => { throws(() => { // @ts-expect-error parse('a{}', { map: { prev: 1 } }) }, 'Unsupported previous source map format: 1') }) test('reads map from annotation', () => { let file = join(dir, 'a.map') mkdirSync(dir) writeFileSync(file, map) let root = parse('a{}\n/*# sourceMappingURL=a.map */', { from: file }) is(root.source?.input.map.text, map) is(root.source?.input.map.root, dir) }) test('reads only the last map from annotation', () => { let file = join(dir, 'c.map') mkdirSync(dir) writeFileSync(file, map) let root = parse( 'a{}' + '\n/*# sourceMappingURL=a.map */' + '\n/*# sourceMappingURL=b.map */' + '\n/*# sourceMappingURL=c.map */', { from: file } ) is(root.source?.input.map.text, map) is(root.source?.input.map.root, dir) }) test('sets unique name for inline map', () => { let map2 = { mappings: '', names: [], sources: ['a'], version: 3 } let opts = { map: { prev: map2 } } let file1 = parse('a{}', opts).source?.input.map.file let file2 = parse('a{}', opts).source?.input.map.file match(String(file1), /^$/) is.not(file1, file2) }) test('accepts an empty mappings string', () => { not.throws(() => { let emptyMap = { mappings: '', names: [], sources: [], version: 3 } parse('body{}', { map: { prev: emptyMap } }) }) }) test('accepts a function', () => { let css = 'body{}\n/*# sourceMappingURL=a.map */' let file = join(dir, 'previous-sourcemap-function.map') mkdirSync(dir) writeFileSync(file, map) let opts = { map: { prev: () => file } } let root = parse(css, opts) is(root.source?.input.map.text, map) is(root.source?.input.map.annotation, 'a.map') }) test('calls function with opts.from', () => { let css = 'body{}\n/*# sourceMappingURL=a.map */' let file = join(dir, 'previous-sourcemap-function.map') mkdirSync(dir) writeFileSync(file, map) parse(css, { from: 'a.css', map: { prev: from => { is(from, 'a.css') return file } } }) }) test('raises when function returns invalid path', () => { let css = 'body{}\n/*# sourceMappingURL=a.map */' let fakeMap = Number.MAX_SAFE_INTEGER.toString() + '.map' let fakePath = join(dir, fakeMap) let opts = { map: { prev: () => fakePath } } throws(() => { parse(css, opts) }, 'Unable to load previous source map: ' + fakePath) }) test('uses source map path as a root', () => { let from = join(dir, 'a.css') mkdirSync(dir) mkdirSync(join(dir, 'maps')) writeFileSync( join(dir, 'maps', 'a.map'), JSON.stringify({ file: 'test.css', mappings: 'AACA,CAAC,CACG,GAAG,CAAC;EACF,KAAK,EAAE,GAAI;CACZ', names: [], sources: ['../../test.scss'], version: 3 }) ) let root = parse( '* div {\n color: red;\n }\n/*# sourceMappingURL=maps/a.map */', { from } ) equal(root.source?.input.origin(1, 3, 1, 5), { column: 4, endColumn: 7, endLine: 3, file: join(dir, '..', 'test.scss'), line: 3, url: pathToFileURL(join(dir, '..', 'test.scss')).href }) }) test('uses current file path for source map', () => { let root = parse('a{b:1}', { from: join(__dirname, 'dir', 'subdir', 'a.css'), map: { prev: { file: 'test.css', mappings: 'AAAA,CAAC;EAAC,CAAC,EAAC,CAAC', names: [], sources: ['../test.scss'], version: 3 } } }) equal(root.source?.input.origin(1, 1), { column: 1, endColumn: undefined, endLine: undefined, file: join(__dirname, 'dir', 'test.scss'), line: 1, url: pathToFileURL(join(__dirname, 'dir', 'test.scss')).href }) }) test('works with non-file sources', () => { let root = parse('a{b:1}', { from: join(__dirname, 'dir', 'subdir', 'a.css'), map: { prev: { file: 'test.css', mappings: 'AAAA,CAAC;EAAC,CAAC,EAAC,CAAC', names: [], sources: ['http://example.com/test.scss'], version: 3 } } }) equal(root.source?.input.origin(1, 1), { column: 1, endColumn: undefined, endLine: undefined, line: 1, url: 'http://example.com/test.scss' }) }) test('works with index map', () => { let root = parse('body {\nwidth:100%;\n}', { from: join(__dirname, 'a.css'), map: { prev: { sections: [ { map: { mappings: 'AAAA;AACA;AACA;', sources: ['b.css'], sourcesContent: ['body {\nwidth:100%;\n}'], version: 3 }, offset: { column: 0, line: 0 } } ], version: 3 } } }) is((root as any).source.input.origin(1, 1).file, join(__dirname, 'b.css')) }) test.run() postcss-8.4.49/test/processor.test.ts000077500000000000000000000361141471446070100176560ustar00rootroot00000000000000// @ts-ignore type definitions for nanodelay@1 are wrong. import { delay } from 'nanodelay' import { restoreAll, spyOn } from 'nanospy' import { resolve as pathResolve } from 'path' import { test } from 'uvu' import { equal, instance, is, match, not, throws, type } from 'uvu/assert' import CssSyntaxError from '../lib/css-syntax-error.js' import LazyResult from '../lib/lazy-result.js' import NoWorkResult from '../lib/no-work-result.js' import postcss, { Document, Node, parse, Parser, Plugin, PluginCreator, Result, Root, Stringifier } from '../lib/postcss.js' import Processor from '../lib/processor.js' import Rule from '../lib/rule.js' test.after.each(() => { restoreAll() }) function prs(): Root { return new Root({ raws: { after: 'ok' } }) } function str(node: Node, builder: (s: string) => void): void { builder(`${node.raws.after}!`) } async function catchError(cb: () => Promise): Promise { try { await cb() } catch (e) { if (e instanceof Error) return e } throw new Error('Error was not thrown') } let beforeFix = new Processor([ (root: Root) => { root.walkRules(rule => { if (!rule.selector.match(/::(before|after)/)) return if (!rule.some(i => i.type === 'decl' && i.prop === 'content')) { rule.prepend({ prop: 'content', value: '""' }) } }) } ]) test('adds new plugins', () => { let a = (): void => {} let processor = new Processor() processor.use(a) equal(processor.plugins, [a]) }) test('adds new plugin by object', () => { let a = (): void => {} let processor = new Processor() processor.use({ postcss: a }) equal(processor.plugins, [a]) }) test('adds new plugin by object-function', () => { let a = (): void => {} let obj: any = () => {} obj.postcss = a let processor = new Processor() processor.use(obj) equal(processor.plugins, [a]) }) test('adds new processors of another postcss instance', () => { let a = (): void => {} let processor = new Processor() let other = new Processor([a]) processor.use(other) equal(processor.plugins, [a]) }) test('adds new processors from object', () => { let a = (): void => {} let processor = new Processor() let other = new Processor([a]) processor.use({ postcss: other }) equal(processor.plugins, [a]) }) test('returns itself', () => { let a = (): void => {} let b = (): void => {} let processor = new Processor() equal(processor.use(a).use(b).plugins, [a, b]) }) test('throws on wrong format', () => { let pr = new Processor() throws(() => { // @ts-expect-error pr.use(1) }, /1 is not a PostCSS plugin/) }) test('processes CSS', () => { let result = beforeFix.process('a::before{top:0}') is(result.css, 'a::before{content:"";top:0}') }) test('processes parsed AST', () => { let root = parse('a::before{top:0}') let result = beforeFix.process(root) is(result.css, 'a::before{content:"";top:0}') }) test('processes previous result', () => { let result = new Processor([() => {}]).process('a::before{top:0}') result = beforeFix.process(result) is(result.css, 'a::before{content:"";top:0}') }) test('takes maps from previous result', () => { let one = new Processor([() => {}]).process('a{}', { from: 'a.css', map: { inline: false }, to: 'b.css' }) let two = new Processor([() => {}]).process(one, { to: 'c.css' }) equal(two.map.toJSON().sources, ['a.css']) }) test('inlines maps from previous result', () => { let one = new Processor([() => {}]).process('a{}', { from: 'a.css', map: { inline: false }, to: 'b.css' }) let two = new Processor([() => {}]).process(one, { map: { inline: true }, to: 'c.css' }) type(two.map, 'undefined') }) test('throws with file name', () => { let error: CssSyntaxError | undefined try { new Processor([() => {}]).process('a {', { from: 'a.css' }).css } catch (e) { if (e instanceof CssSyntaxError) { error = e } else { throw e } } is(error?.file, pathResolve('a.css')) match(String(error?.message), /a.css:1:1: Unclosed block$/) }) test('allows to replace Root', () => { let processor = new Processor([ (css, result) => { result.root = new Root() } ]) is(processor.process('a {}').css, '') }) test('returns LazyResult object', () => { let result = new Processor([() => {}]).process('a{}') is(result instanceof LazyResult, true) is(result.css, 'a{}') is(result.toString(), 'a{}') }) test('calls all plugins once', async () => { let calls = '' let a = (): void => { calls += 'a' } let b = (): void => { calls += 'b' } let result = new Processor([a, b]).process('', { from: undefined }) result.css result.map result.root await result is(calls, 'ab') }) test('parses, converts and stringifies CSS', () => { is( typeof new Processor([ (css: Root) => { equal(css instanceof Root, true) } ]).process('a {}').css, 'string' ) }) test('send result to plugins', () => { let processor = new Processor([() => {}]) processor .use((css, result) => { is(result instanceof Result, true) equal(result.processor, processor) equal(result.opts, { map: true }) equal(result.root, css) }) .process('a {}', { from: undefined, map: true }) }) test('accepts source map from PostCSS', () => { let one = new Processor([() => {}]).process('a{}', { from: 'a.css', map: { inline: false }, to: 'b.css' }) let two = new Processor([() => {}]).process(one.css, { from: 'b.css', map: { inline: false, prev: one.map }, to: 'c.css' }) equal(two.map.toJSON().sources, ['a.css']) }) test('supports async plugins', async () => { let starts = 0 let finish = 0 let async1 = (css: Root): Promise => new Promise(resolve => { starts += 1 setTimeout(() => { equal(starts, 1) css.append('a {}') finish += 1 resolve() }, 1) }) let async2 = (css: Root): Promise => new Promise(resolve => { equal(starts, 1) equal(finish, 1) starts += 1 setTimeout(() => { css.append('b {}') finish += 1 resolve() }, 1) }) let r = await new Processor([async1, async2]).process('', { from: 'a' }) is(starts, 2) is(finish, 2) is(r.css, 'a {}b {}') }) test('works async without plugins', async () => { let r = await new Processor([() => {}]).process('a {}', { from: 'a' }) is(r.css, 'a {}') }) test('runs async plugin only once', async () => { let calls = 0 let async = (): Promise => { return new Promise(resolve => { setTimeout(() => { calls += 1 resolve() }, 1) }) } let result = new Processor([async]).process('a {}', { from: undefined }) result.then(() => {}) await result await result is(calls, 1) }) test('supports async errors', async () => { let error = new Error('Async') let async = (): Promise => { return new Promise((resolve, reject) => { reject(error) }) } let result = new Processor([async]).process('', { from: undefined }) let err1 = await catchError(async () => await result) equal(err1, error) let err2: Error | undefined result.catch(catched => { err2 = catched }) await delay(10) equal(err2, error) }) test('supports sync errors in async mode', async () => { let error = new Error('Async') let async = (): void => { throw error } let err = await catchError(() => new Processor([async]).process('', { from: undefined }) ) equal(err, error) }) test('throws parse error in async', async () => { let err = await catchError(() => new Processor([() => {}]).process('a{', { from: undefined }) ) is(err.message, ':1:1: Unclosed block') }) test('throws error on sync method to async plugin', () => { let async = (): Promise => { return new Promise(resolve => { resolve() }) } throws(() => { new Processor([async]).process('a{}').css }, /async/) }) test('throws a sync call in async running', async () => { let async = (): Promise => new Promise(resolve => setTimeout(resolve, 1)) let processor = new Processor([async]).process('a{}', { from: 'a.css' }) processor.async() throws(() => { processor.sync() }, /then/) }) test('remembers errors', async () => { let calls = 0 let plugin: Plugin = { Once() { calls += 1 throw new Error('test') }, postcssPlugin: 'plugin' } let processing = postcss([plugin]).process('a{}', { from: undefined }) throws(() => { processing.css }, 'test') throws(() => { processing.css }, 'test') throws(() => { processing.root }, 'test') let asyncError: any try { await processing } catch (e) { asyncError = e } is(asyncError.message, 'test') is(calls, 1) }) test('checks plugin compatibility', () => { let error = spyOn(console, 'error', () => {}) let warn = spyOn(console, 'warn', () => {}) let plugin = (postcss as any).plugin('test', () => { return () => { throw new Error('Er') } }) let func = plugin() equal(warn.callCount, 1) func.postcssVersion = '2.1.5' function processBy(version: string): void { let processor = new Processor([func]) processor.version = version processor.process('a{}').css } throws(() => { processBy('1.0.0') }, 'Er') equal(error.callCount, 1) equal(error.calls, [ [ 'Unknown error from PostCSS plugin. ' + 'Your current PostCSS version is 1.0.0, but test uses 2.1.5. ' + 'Perhaps this is the source of the error below.' ] ]) throws(() => { processBy('3.0.0') }, 'Er') equal(error.callCount, 2) throws(() => { processBy('2.0.0') }, 'Er') equal(error.callCount, 3) throws(() => { processBy('2.1.0') }, 'Er') equal(error.callCount, 3) }) test('sets last plugin to result', async () => { let plugin1 = (css: Root, result: Result): void => { equal(result.lastPlugin, plugin1) } let plugin2 = (css: Root, result: Result): void => { equal(result.lastPlugin, plugin2) } let processor = new Processor([plugin1, plugin2]) let result = await processor.process('a{}', { from: undefined }) equal(result.lastPlugin, plugin2) }) test('uses custom parsers', async () => { let processor = new Processor([]) let result = await processor.process('a{}', { from: undefined, parser: prs }) is(result.css, 'ok') }) test('uses custom parsers from object', async () => { let processor = new Processor([]) let syntax = { parse: prs, stringify: str } let result = await processor.process('a{}', { from: 'a', parser: syntax }) equal(result.css, 'ok') }) test('uses custom stringifier', async () => { let processor = new Processor([]) let result = await processor.process('a{}', { from: 'a', stringifier: str }) is(result.css, '!') }) test('uses custom stringifier from object', async () => { let processor = new Processor([]) let syntax = { parse: prs, stringify: str } let result = await processor.process('', { from: 'a', stringifier: syntax }) is(result.css, '!') }) test('uses custom stringifier with source maps', async () => { let processor = new Processor([]) let result = await processor.process('a{}', { from: undefined, map: true, stringifier: str }) match(result.css, /!\n\/\*# sourceMap/) }) test('uses custom syntax', async () => { let processor = new Processor([() => {}]) let result = await processor.process('a{}', { from: undefined, syntax: { parse: prs, stringify: str } }) is(result.css, 'ok!') }) test('contains PostCSS version', () => { match(new Processor().version, /\d+.\d+.\d+/) }) test('throws on syntax as plugin', () => { let processor = new Processor([() => {}]) throws(() => { processor.use({ // @ts-expect-error parse() {} }) }, /syntax/) }) test('warns about missed from', async () => { let warn = spyOn(console, 'warn', () => {}) let processor = new Processor([() => {}]) processor.process('a{}').css equal(warn.calls, []) await processor.process('a{}') equal(warn.calls, [ [ 'Without `from` option PostCSS could generate wrong source map ' + 'and will not find Browserslist config. Set it to CSS file path ' + 'or to `undefined` to prevent this warning.' ] ]) }) test('returns NoWorkResult object', async () => { let result = new Processor().process('a{}') instance(result, NoWorkResult) }) test('without plugins parses CSS only on root access', async () => { let noWorkResult = new Processor().process('a{}') let result = await noWorkResult // @ts-expect-error type(noWorkResult._root, 'undefined') is(result.root.nodes.length, 1) // @ts-expect-error not.type(noWorkResult._root, 'undefined') is(noWorkResult.root.nodes.length, 1) }) test('catches error with empty processor', async () => { let noWorkResult = new Processor().process('a {') try { noWorkResult.root } catch {} let err = await catchError(async () => await noWorkResult) noWorkResult.catch(e => { instance(e, CssSyntaxError) }) instance(err, CssSyntaxError) }) test('throws an error on root access on no plugins mode', () => { throws(() => { postcss().process('// invalid', { from: 'a' }).root }, 'Unknown word') }) test('supports plugins returning processors', () => { let warn = spyOn(console, 'warn', () => {}) let a = (): void => {} let processor = new Processor() let other: any = (postcss as any).plugin('test', () => { return new Processor([a]) }) processor.use(other) equal(processor.plugins, [a]) equal(warn.callCount, 1) }) test('supports plugin creators returning processors', () => { let a = (): void => {} let processor = new Processor() let other = (() => { return new Processor([a]) }) as PluginCreator other.postcss = true processor.use(other) equal(processor.plugins, [a]) }) test('uses custom syntax for document', async () => { let customParser: Parser = () => { return new Document({ nodes: [ new Root({ nodes: [new Rule({ selector: 'a' })], raws: { after: '\n\n\n', codeBefore: '\n\n\n', codeBefore: '\n\n\n' ) }) test.run() postcss-8.4.49/test/result.test.ts000077500000000000000000000031351471446070100171520ustar00rootroot00000000000000import { test } from 'uvu' import { equal, is } from 'uvu/assert' import postcss, { Plugin, Result, Root, Warning } from '../lib/postcss.js' import Processor from '../lib/processor.js' let processor = new Processor() let root = new Root() test('stringifies', () => { let result = new Result(processor, root, {}) result.css = 'a{}' is(`${result}`, result.css) }) test('adds warning', () => { let warning let plugin: Plugin = { Once(css, { result }) { warning = result.warn('test', { node: css.first }) }, postcssPlugin: 'test-plugin' } let result = postcss([plugin]).process('a{}').sync() equal( warning, new Warning('test', { node: result.root.first, plugin: 'test-plugin' }) ) equal(result.messages, [warning]) }) test('allows to override plugin', () => { let plugin: Plugin = { Once(css, { result }) { result.warn('test', { plugin: 'test-plugin#one' }) }, postcssPlugin: 'test-plugin' } let result = postcss([plugin]).process('a{}').sync() is(result.messages[0].plugin, 'test-plugin#one') }) test('allows Root', () => { let css = postcss.parse('a{}') let result = new Result(processor, css, {}) result.warn('TT', { node: css.first }) is(result.messages[0].toString(), ':1:1: TT') }) test('returns only warnings', () => { let result = new Result(processor, root, {}) result.messages = [ { text: 'a', type: 'warning' }, { type: 'custom' }, { text: 'b', type: 'warning' } ] equal(result.warnings(), [ { text: 'a', type: 'warning' }, { text: 'b', type: 'warning' } ]) }) test.run() postcss-8.4.49/test/root.test.ts000077500000000000000000000034441471446070100166220ustar00rootroot00000000000000import { test } from 'uvu' import { is, match, type } from 'uvu/assert' import { parse, Result } from '../lib/postcss.js' test('prepend() fixes spaces on insert before first', () => { let css = parse('a {} b {}') css.prepend({ selector: 'em' }) is(css.toString(), 'em {} a {} b {}') }) test('prepend() fixes spaces on multiple inserts before first', () => { let css = parse('a {} b {}') css.prepend({ selector: 'em' }, { selector: 'strong' }) is(css.toString(), 'em {} strong {} a {} b {}') }) test('prepend() uses default spaces on only first', () => { let css = parse('a {}') css.prepend({ selector: 'em' }) is(css.toString(), 'em {}\na {}') }) test('append() sets new line between rules in multiline files', () => { let a = parse('a {}\n\na {}\n') let b = parse('b {}\n') is(a.append(b).toString(), 'a {}\n\na {}\n\nb {}\n') }) test('insertAfter() does not use before of first rule', () => { let css = parse('a{} b{}') css.insertAfter(0, { selector: '.a' }) css.insertAfter(2, { selector: '.b' }) type(css.nodes[1].raws.before, 'undefined') is(css.nodes[3].raws.before, ' ') is(css.toString(), 'a{} .a{} b{} .b{}') }) test('fixes spaces on removing first rule', () => { let css = parse('a{}\nb{}\n') if (!css.first) throw new Error('No nodes were parsed') css.first.remove() is(css.toString(), 'b{}\n') }) test('keeps spaces on moving root', () => { let css1 = parse('a{}\nb{}\n') let css2 = parse('') css2.append(css1) is(css2.toString(), 'a{}\nb{}') let css3 = parse('\n') css3.append(css2.nodes) is(css3.toString(), 'a{}\nb{}\n') }) test('generates result with map', () => { let root = parse('a {}') let result = root.toResult({ map: true }) is(result instanceof Result, true) match(result.css, /a {}\n\/\*# sourceMappingURL=/) }) test.run() postcss-8.4.49/test/rule.test.ts000077500000000000000000000043221471446070100166020ustar00rootroot00000000000000import { test } from 'uvu' import { equal, is } from 'uvu/assert' import { parse, Rule } from '../lib/postcss.js' test('initializes with properties', () => { let rule = new Rule({ selector: 'a' }) is(rule.selector, 'a') }) test('returns array in selectors', () => { let rule = new Rule({ selector: 'a,b' }) equal(rule.selectors, ['a', 'b']) }) test('trims selectors', () => { let rule = new Rule({ selector: '.a\n, .b , .c' }) equal(rule.selectors, ['.a', '.b', '.c']) }) test('is smart about selectors commas', () => { let rule = new Rule({ selector: "[foo='a, b'], a:-moz-any(:focus, [href*=','])" }) equal(rule.selectors, ["[foo='a, b']", "a:-moz-any(:focus, [href*=','])"]) }) test('receive array in selectors', () => { let rule = new Rule({ selector: 'i, b' }) rule.selectors = ['em', 'strong'] is(rule.selector, 'em, strong') }) test('saves separator in selectors', () => { let rule = new Rule({ selector: 'i,\nb' }) rule.selectors = ['em', 'strong'] is(rule.selector, 'em,\nstrong') }) test('uses between to detect separator in selectors', () => { let rule = new Rule({ raws: { between: '' }, selector: 'b' }) rule.selectors = ['b', 'strong'] is(rule.selector, 'b,strong') }) test('uses space in separator be default in selectors', () => { let rule = new Rule({ selector: 'b' }) rule.selectors = ['b', 'strong'] is(rule.selector, 'b, strong') }) test('selectors works in constructor', () => { let rule = new Rule({ selectors: ['a', 'b'] }) is(rule.selector, 'a, b') }) test('inserts default spaces', () => { let rule = new Rule({ selector: 'a' }) is(rule.toString(), 'a {}') rule.append({ prop: 'color', value: 'black' }) is(rule.toString(), 'a {\n color: black\n}') }) test('clones spaces from another rule', () => { let root = parse('b{\n }') let rule = new Rule({ selector: 'em' }) root.append(rule) is(root.toString(), 'b{\n }\nem{\n }') }) test('uses different spaces for empty rules', () => { let root = parse('a{}\nb{\n a:1\n}') let rule = new Rule({ selector: 'em' }) root.append(rule) is(root.toString(), 'a{}\nb{\n a:1\n}\nem{}') rule.append({ prop: 'top', value: '0' }) is(root.toString(), 'a{}\nb{\n a:1\n}\nem{\n top:0\n}') }) test.run() postcss-8.4.49/test/stringifier.test.js000077500000000000000000000164271471446070100201570ustar00rootroot00000000000000let { test } = require('uvu') let { is } = require('uvu/assert') let { AtRule, Declaration, Document, Node, parse, Root, Rule } = require('../lib/postcss') let Stringifier = require('../lib/stringifier') let str test.before.each(() => { str = new Stringifier() }) test('creates trimmed/raw property', () => { let b = new Node({ one: 'trim' }) b.raws.one = { raw: 'raw', value: 'trim' } is(str.rawValue(b, 'one'), 'raw') b.one = 'trim1' is(str.rawValue(b, 'one'), 'trim1') }) test('works without rawValue magic', () => { let b = new Node() b.one = '1' is(b.one, '1') is(str.rawValue(b, 'one'), '1') }) test('uses node raw', () => { let rule = new Rule({ raws: { between: '\n' }, selector: 'a' }) is(str.raw(rule, 'between', 'beforeOpen'), '\n') }) test('hacks before for nodes without parent', () => { let rule = new Rule({ selector: 'a' }) is(str.raw(rule, 'before'), '') }) test('hacks before for first node', () => { let root = new Root() root.append(new Rule({ selector: 'a' })) is(str.raw(root.first, 'before'), '') }) test('hacks before for first decl', () => { let decl = new Declaration({ prop: 'color', value: 'black' }) is(str.raw(decl, 'before'), '') let rule = new Rule({ selector: 'a' }) rule.append(decl) is(str.raw(decl, 'before'), '\n ') }) test('detects after raw', () => { let root = new Root() root.append({ raws: { after: ' ' }, selector: 'a' }) root.first.append({ prop: 'color', value: 'black' }) root.append({ selector: 'a' }) is(str.raw(root.last, 'after'), ' ') }) test('uses defaults without parent', () => { let rule = new Rule({ selector: 'a' }) is(str.raw(rule, 'between', 'beforeOpen'), ' ') }) test('uses defaults for unique node', () => { let root = new Root() root.append(new Rule({ selector: 'a' })) is(str.raw(root.first, 'between', 'beforeOpen'), ' ') }) test('clones raw from first node', () => { let root = new Root() root.append(new Rule({ raws: { between: '' }, selector: 'a' })) root.append(new Rule({ selector: 'b' })) is(str.raw(root.last, 'between', 'beforeOpen'), '') }) test('indents by default', () => { let root = new Root() root.append(new AtRule({ name: 'page' })) root.first.append(new Rule({ selector: 'a' })) root.first.first.append({ prop: 'color', value: 'black' }) is( root.toString(), '@page {\n' + ' a {\n' + ' color: black\n' + ' }\n' + '}' ) }) test('clones style', () => { let compress = parse('@page{ a{ } }') let spaces = parse('@page {\n a {\n }\n}') compress.first.first.append({ prop: 'color', value: 'black' }) is(compress.toString(), '@page{ a{ color: black } }') spaces.first.first.append({ prop: 'color', value: 'black' }) is(spaces.toString(), '@page {\n a {\n color: black\n }\n}') }) test('clones indent', () => { let root = parse('a{\n}') root.first.append({ text: 'a' }) root.first.append({ raws: { before: '\n\n ' }, text: 'b' }) is(root.toString(), 'a{\n\n /* a */\n\n /* b */\n}') }) test('clones declaration before for comment', () => { let root = parse('a{\n}') root.first.append({ text: 'a' }) root.first.append({ prop: 'a', raws: { before: '\n\n ' }, value: '1' }) is(root.toString(), 'a{\n\n /* a */\n\n a: 1\n}') }) test('clones indent by types', () => { let css = parse('a {\n *color: black\n}\n\nb {\n}') css.append(new Rule({ selector: 'em' })) css.last.append({ prop: 'z-index', value: '1' }) is(css.last.first.raw('before'), '\n ') }) test('ignores non-space symbols in indent cloning', () => { let css = parse('a {\n color: black\n}\n\nb {\n}') css.append(new Rule({ selector: 'em' })) css.last.append({ prop: 'z-index', value: '1' }) is(css.last.raw('before'), '\n\n') is(css.last.first.raw('before'), '\n ') }) test('clones indent by before and after', () => { let css = parse('@page{\n\n a{\n color: black}}') css.first.append(new Rule({ selector: 'b' })) css.first.last.append({ prop: 'z-index', value: '1' }) is(css.first.last.raw('before'), '\n\n ') is(css.first.last.raw('after'), '') }) test('clones semicolon only from rules with children', () => { let css = parse('a{}b{one:1;}') is(str.raw(css.first, 'semicolon'), true) }) test('clones only spaces in before', () => { let css = parse('a{*one:1}') css.first.append({ prop: 'two', value: '2' }) css.append({ name: 'keyframes', params: 'a' }) css.last.append({ selector: 'from' }) is(css.toString(), 'a{*one:1;two:2}\n@keyframes a{\nfrom{}}') }) test('clones only spaces in between', () => { let css = parse('a{one/**/:1}') css.first.append({ prop: 'two', value: '2' }) is(css.toString(), 'a{one/**/:1;two:2}') }) test('uses optional raws.indent', () => { let rule = new Rule({ raws: { indent: ' ' }, selector: 'a' }) rule.append({ prop: 'color', value: 'black' }) is(rule.toString(), 'a {\n color: black\n}') }) test('handles nested roots', () => { let root = new Root() let subRoot = new Root() subRoot.append(new AtRule({ name: 'foo' })) root.append(subRoot) is(root.toString(), '@foo') }) test('handles root', () => { let root = new Root() root.append(new AtRule({ name: 'foo' })) let s = root.toString() is(s, '@foo') }) test('handles root with after', () => { let root = new Root({ raws: { after: ' ' } }) root.append(new AtRule({ name: 'foo' })) let s = root.toString() is(s, '@foo ') }) test('pass nodes to document', () => { let root = new Root() let document = new Document({ nodes: [root] }) is(document.toString(), '') }) test('handles document with one root', () => { let root = new Root() root.append(new AtRule({ name: 'foo' })) let document = new Document() document.append(root) let s = document.toString() is(s, '@foo') }) test('handles document with one root and after raw', () => { let document = new Document() let root = new Root({ raws: { after: ' ' } }) root.append(new AtRule({ name: 'foo' })) document.append(root) let s = document.toString() is(s, '@foo ') }) test('handles document with one root and before and after', () => { let document = new Document() let root = new Root({ raws: { after: 'AFTER' } }) root.append(new AtRule({ name: 'foo' })) document.append(root) let s = document.toString() is(s, '@fooAFTER') }) test('handles document with three roots without raws', () => { let root1 = new Root() root1.append(new AtRule({ name: 'foo' })) let root2 = new Root() root2.append(new Rule({ selector: 'a' })) let root3 = new Root() root3.append(new Declaration({ prop: 'color', value: 'black' })) let document = new Document() document.append(root1) document.append(root2) document.append(root3) let s = document.toString() is(s, '@fooa {}color: black') }) test('handles document with three roots, with before and after raws', () => { let root1 = new Root({ raws: { after: 'AFTER_ONE' } }) root1.append(new Rule({ selector: 'a.one' })) let root2 = new Root({ raws: { after: 'AFTER_TWO' } }) root2.append(new Rule({ selector: 'a.two' })) let root3 = new Root({ raws: { after: 'AFTER_THREE' } }) root3.append(new Rule({ selector: 'a.three' })) let document = new Document() document.append(root1) document.append(root2) document.append(root3) let s = document.toString() is(s, 'a.one {}AFTER_ONEa.two {}AFTER_TWOa.three {}AFTER_THREE') }) test.run() postcss-8.4.49/test/stringify.test.ts000077500000000000000000000006161471446070100176530ustar00rootroot00000000000000import { eachTest } from 'postcss-parser-tests' import { test } from 'uvu' import { is } from 'uvu/assert' import { parse, stringify } from '../lib/postcss.js' eachTest((name, css) => { if (name === 'bom.css') return test(`stringifies ${name}`, () => { let root = parse(css) let result = '' stringify(root, i => { result += i }) is(result, css) }) }) test.run() postcss-8.4.49/test/tokenize.test.js000077500000000000000000000150101471446070100174450ustar00rootroot00000000000000let { test } = require('uvu') let { equal, is, throws } = require('uvu/assert') let { Input } = require('../lib/postcss') let tokenizer = require('../lib/tokenize') function tokenize(css, opts) { let processor = tokenizer(new Input(css), opts) let tokens = [] while (!processor.endOfFile()) { tokens.push(processor.nextToken()) } return tokens } function run(css, tokens, opts) { equal(tokenize(css, opts), tokens) } test('tokenizes empty file', () => { run('', []) }) test('tokenizes space', () => { run('\r\n \f\t', [['space', '\r\n \f\t']]) }) test('tokenizes word', () => { run('ab', [['word', 'ab', 0, 1]]) }) test('splits word by !', () => { run('aa!bb', [ ['word', 'aa', 0, 1], ['word', '!bb', 2, 4] ]) }) test('changes lines in spaces', () => { run('a \n b', [ ['word', 'a', 0, 0], ['space', ' \n '], ['word', 'b', 4, 4] ]) }) test('tokenizes control chars', () => { run('{:;}', [ ['{', '{', 0], [':', ':', 1], [';', ';', 2], ['}', '}', 3] ]) }) test('escapes control symbols', () => { run('\\(\\{\\"\\@\\\\""', [ ['word', '\\(', 0, 1], ['word', '\\{', 2, 3], ['word', '\\"', 4, 5], ['word', '\\@', 6, 7], ['word', '\\\\', 8, 9], ['string', '""', 10, 11] ]) }) test('escapes backslash', () => { run('\\\\\\\\{', [ ['word', '\\\\\\\\', 0, 3], ['{', '{', 4] ]) }) test('tokenizes simple brackets', () => { run('(ab)', [['brackets', '(ab)', 0, 3]]) }) test('tokenizes square brackets', () => { run('a[bc]', [ ['word', 'a', 0, 0], ['[', '[', 1], ['word', 'bc', 2, 3], [']', ']', 4] ]) }) test('tokenizes complicated brackets', () => { run('(())("")(/**/)(\\\\)(\n)(', [ ['(', '(', 0], ['brackets', '()', 1, 2], [')', ')', 3], ['(', '(', 4], ['string', '""', 5, 6], [')', ')', 7], ['(', '(', 8], ['comment', '/**/', 9, 12], [')', ')', 13], ['(', '(', 14], ['word', '\\\\', 15, 16], [')', ')', 17], ['(', '(', 18], ['space', '\n'], [')', ')', 20], ['(', '(', 21] ]) }) test('tokenizes string', () => { run('\'"\'"\\""', [ ['string', "'\"'", 0, 2], ['string', '"\\""', 3, 6] ]) }) test('tokenizes escaped string', () => { run('"\\\\"', [['string', '"\\\\"', 0, 3]]) }) test('changes lines in strings', () => { run('"\n\n""\n\n"', [ ['string', '"\n\n"', 0, 3], ['string', '"\n\n"', 4, 7] ]) }) test('tokenizes at-word', () => { run('@word ', [ ['at-word', '@word', 0, 4], ['space', ' '] ]) }) test('tokenizes at-word end', () => { run('@one{@two()@three""@four;', [ ['at-word', '@one', 0, 3], ['{', '{', 4], ['at-word', '@two', 5, 8], ['brackets', '()', 9, 10], ['at-word', '@three', 11, 16], ['string', '""', 17, 18], ['at-word', '@four', 19, 23], [';', ';', 24] ]) }) test('tokenizes urls', () => { run('url(/*\\))', [ ['word', 'url', 0, 2], ['brackets', '(/*\\))', 3, 8] ]) }) test('tokenizes quoted urls', () => { run('url(")")', [ ['word', 'url', 0, 2], ['(', '(', 3], ['string', '")"', 4, 6], [')', ')', 7] ]) }) test('tokenizes at-symbol', () => { run('@', [['at-word', '@', 0, 0]]) }) test('tokenizes comment', () => { run('/* a\nb */', [['comment', '/* a\nb */', 0, 8]]) }) test('changes lines in comments', () => { run('a/* \n */b', [ ['word', 'a', 0, 0], ['comment', '/* \n */', 1, 7], ['word', 'b', 8, 8] ]) }) test('supports line feed', () => { run('a\fb', [ ['word', 'a', 0, 0], ['space', '\f'], ['word', 'b', 2, 2] ]) }) test('supports carriage return', () => { run('a\rb\r\nc', [ ['word', 'a', 0, 0], ['space', '\r'], ['word', 'b', 2, 2], ['space', '\r\n'], ['word', 'c', 5, 5] ]) }) test('tokenizes CSS', () => { let css = 'a {\n' + ' content: "a";\n' + ' width: calc(1px;)\n' + ' }\n' + '/* small screen */\n' + '@media screen {}' run(css, [ ['word', 'a', 0, 0], ['space', ' '], ['{', '{', 2], ['space', '\n '], ['word', 'content', 6, 12], [':', ':', 13], ['space', ' '], ['string', '"a"', 15, 17], [';', ';', 18], ['space', '\n '], ['word', 'width', 22, 26], [':', ':', 27], ['space', ' '], ['word', 'calc', 29, 32], ['brackets', '(1px;)', 33, 38], ['space', '\n '], ['}', '}', 42], ['space', '\n'], ['comment', '/* small screen */', 44, 61], ['space', '\n'], ['at-word', '@media', 63, 68], ['space', ' '], ['word', 'screen', 70, 75], ['space', ' '], ['{', '{', 77], ['}', '}', 78] ]) }) test('throws error on unclosed string', () => { throws(() => { tokenize(' "') }, /:1:2: Unclosed string/) }) test('throws error on unclosed comment', () => { throws(() => { tokenize(' /*') }, /:1:2: Unclosed comment/) }) test('throws error on unclosed url', () => { throws(() => { tokenize('url(') }, /:1:4: Unclosed bracket/) }) test('ignores unclosing string on request', () => { run( ' "', [ ['space', ' '], ['string', '"', 1, 2] ], { ignoreErrors: true } ) }) test('ignores unclosing comment on request', () => { run( ' /*', [ ['space', ' '], ['comment', '/*', 1, 3] ], { ignoreErrors: true } ) }) test('ignores unclosing function on request', () => { run( 'url(', [ ['word', 'url', 0, 2], ['brackets', '(', 3, 3] ], { ignoreErrors: true } ) }) test('tokenizes hexadecimal escape', () => { run('\\0a \\09 \\z ', [ ['word', '\\0a ', 0, 3], ['word', '\\09 ', 4, 7], ['word', '\\z', 8, 9], ['space', ' '] ]) }) test('ignore unclosed per token request', () => { function token(css, opts) { let processor = tokenizer(new Input(css), opts) let tokens = [] while (!processor.endOfFile()) { tokens.push(processor.nextToken({ ignoreUnclosed: true })) } return tokens } let css = "How's it going (" let tokens = token(css, {}) let expected = [ ['word', 'How', 0, 2], ['string', "'s", 3, 4], ['space', ' '], ['word', 'it', 6, 7], ['space', ' '], ['word', 'going', 9, 13], ['space', ' '], ['(', '(', 15] ] equal(tokens, expected) }) test('provides correct position', () => { let css = 'Three tokens' let processor = tokenizer(new Input(css)) is(processor.position(), 0) processor.nextToken() is(processor.position(), 5) processor.nextToken() is(processor.position(), 6) processor.nextToken() is(processor.position(), 12) processor.nextToken() is(processor.position(), 12) }) test.run() postcss-8.4.49/test/types.ts000066400000000000000000000014221471446070100160140ustar00rootroot00000000000000import postcss, { Document, PluginCreator } from '../lib/postcss.js' const plugin: PluginCreator = prop => { return { Declaration: (decl, { Comment, result }) => { if (decl.prop === prop) { decl.warn(result, `${decl.prop} found in ${decl.parent?.nodes.length}`) decl.replaceWith(new Comment({ text: `${decl.prop} removed` })) } }, postcssPlugin: 'remover' } } plugin.postcss = true postcss([plugin]) .process('h1{color: black;}', { from: undefined }) .then(result => { console.log(result.root.parent) console.log(result.css) }) function parseMarkdown(): Document { return new Document() } let doc = postcss().process('a{}', { parser: parseMarkdown }).root console.log(doc.toString()) export default plugin postcss-8.4.49/test/version.js000077500000000000000000000003621471446070100163300ustar00rootroot00000000000000#!/usr/bin/env node let Processor = require('../lib/processor') let pkg = require('../package') let instance = new Processor() if (pkg.version !== instance.version) { throw new Error('Version in Processor is not equal to package.json') } postcss-8.4.49/test/visitor.test.ts000077500000000000000000001137721471446070100173440ustar00rootroot00000000000000// @ts-ignore type definitions for nanodelay@1 are wrong. import { delay } from 'nanodelay' import { basename, resolve } from 'path' import { test } from 'uvu' import { equal, is, throws, type } from 'uvu/assert' import postcss, { AnyNode, AtRule, Container, Declaration, Helpers, Plugin, PluginCreator, Root, Rule } from '../lib/postcss.js' function hasAlready(parent: Container | undefined, selector: string): boolean { if (typeof parent === 'undefined') return false return parent.nodes?.some(i => { return i.type === 'rule' && i.selectors.includes(selector) }) ?? false } function addIndex(array: any[][]): any[][] { return array.map((i, index) => { return [index, ...i] }) } function buildVisitor(): [[string, string][], Plugin] { let visits: [string, string][] = [] let visitor: Plugin = { AtRule(i) { visits.push(['AtRule', i.name]) }, AtRuleExit(i) { visits.push(['AtRuleExit', i.name]) }, Comment(i) { visits.push(['Comment', i.text]) }, CommentExit(i) { visits.push(['CommentExit', i.text]) }, Declaration(i) { visits.push(['Declaration', i.prop + ': ' + i.value]) }, DeclarationExit(i) { visits.push(['DeclarationExit', i.prop + ': ' + i.value]) }, Document(i) { visits.push(['Document', `${i.nodes.length}`]) }, DocumentExit(i) { visits.push(['DocumentExit', `${i.nodes.length}`]) }, Once(i) { visits.push(['Once', `${i.nodes.length}`]) }, OnceExit(i) { visits.push(['OnceExit', `${i.nodes.length}`]) }, postcssPlugin: 'visitor', Root(i) { visits.push(['Root', `${i.nodes.length}`]) }, RootExit(i) { visits.push(['RootExit', `${i.nodes.length}`]) }, Rule(i) { visits.push(['Rule', i.selector]) }, RuleExit(i) { visits.push(['RuleExit', i.selector]) } } return [visits, visitor] } let replaceColorGreenClassic: Plugin = { Once(root) { root.walkDecls('color', decl => { decl.value = 'green' }) }, postcssPlugin: 'replace-color' } let willChangeVisitor: Plugin = { Declaration(node) { if (node.prop !== 'will-change') return if (!node.parent) return let already = node.parent.some(i => { return i.type === 'decl' && i.prop === 'backface-visibility' }) if (already) return node.cloneBefore({ prop: 'backface-visibility', value: 'hidden' }) }, postcssPlugin: 'will-change' } let addPropsVisitor: Plugin = { Declaration(node) { if (node.prop !== 'will-change') return node.root().walkDecls('color', decl => { if (!decl.parent) return let already = decl.parent.some(i => { return i.type === 'decl' && i.prop === 'will-change' }) if (already) return decl.cloneBefore({ prop: 'will-change', value: 'transform' }) }) }, postcssPlugin: 'add-props' } let replaceAllButRedToGreen: Plugin = { Declaration(node) { if (node.prop === 'color' && node.value !== 'red') { node.value = 'green' } }, postcssPlugin: 'replace-not-red-to-green' } let replaceGreenToRed: Plugin = { Declaration(node) { if (node.prop === 'color' && node.value === 'green') { node.value = 'red' } }, postcssPlugin: 'replace-green-to-red' } let replacePrintToMobile: Plugin = { AtRule(node) { if (node.params === '(print)') { node.params = '(mobile)' } }, postcssPlugin: 'replace-to-mobile' } let replaceScreenToPrint: Plugin = { AtRule(node) { if (node.params === '(screen)') { node.params = '(print)' } }, postcssPlugin: 'replace-to-print' } let postcssFocus: Plugin = { postcssPlugin: 'postcss-focus', Rule(rule) { if (rule.selector.includes(':hover')) { let focuses: string[] = [] rule.selectors.forEach(selector => { if (selector.includes(':hover')) { let replaced = selector.replace(/:hover/g, ':focus') if (!hasAlready(rule.parent, replaced)) { focuses.push(replaced) } } }) if (focuses.length) { rule.selectors = rule.selectors.concat(focuses) } } } } let hidden: Plugin = { Declaration(decl) { if (decl.prop !== 'display') return let value = decl.value let rule = decl.parent as Rule if (value.includes('disappear')) { decl.cloneBefore({ prop: 'display', value: 'none !important' }) decl.cloneBefore({ prop: 'visibility', value: 'hidden' }) decl.remove() } if (value.includes('hidden')) { let ruleSelectors = rule.selectors.map(i => { return `${i}.focusable:active,${i}.focusable:focus` }) let newRule = rule.cloneAfter({ selectors: ruleSelectors }).removeAll() newRule.append('display: table; position: static; clear: both;') decl.cloneBefore({ prop: 'position', value: 'absolute' }) decl.cloneBefore({ prop: 'width', value: '1px' }) decl.cloneBefore({ prop: 'height', value: '1px' }) decl.cloneBefore({ prop: 'margin', value: '-1px' }) decl.cloneBefore({ prop: 'padding', value: '0' }) decl.cloneBefore({ prop: 'border', value: '0' }) decl.cloneBefore({ prop: 'overflow', value: 'hidden' }) decl.cloneBefore({ prop: 'clip', value: 'rect(0 0 0 0)' }) decl.remove() } if (value.includes('invisible')) { decl.cloneBefore({ prop: 'visibility', value: 'hidden' }) decl.remove() } }, postcssPlugin: 'hidden' } function createPlugin(creator: () => Plugin): PluginCreator { let result = creator as PluginCreator result.postcss = true return result } let postcssAlias = createPlugin(() => { let aliases: any = {} return { Declaration(decl) { let value = aliases[decl.prop] if (value !== undefined) { decl.replaceWith({ important: decl.important, prop: value, value: decl.value }) } }, Once(root) { root.walkAtRules('alias', rule => { rule.walkDecls(decl => { aliases[decl.prop] = decl.value }) rule.remove() }) }, postcssPlugin: 'postcss-alias' } }) test('works classic plugin replace-color', async () => { let { css } = await postcss([replaceColorGreenClassic]).process( '.a{ color: red; } ' + '.b{ will-change: transform; }', { from: 'a.css' } ) is(css, '.a{ color: green; } ' + '.b{ will-change: transform; }') }) test('works visitor plugin will-change', async () => { let { css } = postcss([willChangeVisitor]).process( '.foo { will-change: transform; }', { from: 'a.css' } ) is(css, '.foo { backface-visibility: hidden; will-change: transform; }') }) test('works visitor plugin add-prop', async () => { let { css } = await postcss([addPropsVisitor]).process( '.a{ color: red; } .b{ will-change: transform; }', { from: 'a.css' } ) is( css, '.a{ will-change: transform; color: red; } ' + '.b{ will-change: transform; }' ) }) test('works visitor plugin add-prop in document with single root', async () => { let document = postcss.document({ nodes: [postcss.parse('.a{ color: red; } .b{ will-change: transform; }')] }) let { css } = await postcss([addPropsVisitor]).process(document, { from: 'a.css' }) is( css, '.a{ will-change: transform; color: red; } ' + '.b{ will-change: transform; }' ) }) test('works visitor plugin add-prop in document with two roots', async () => { let document = postcss.document({ nodes: [ postcss.parse('.a{ color: red; }'), postcss.parse('.b{ will-change: transform; }') ] }) let { css } = await postcss([addPropsVisitor]).process(document, { from: 'a.css' }) is(css, '.a{ color: red; }' + '.b{ will-change: transform; }') }) test('works with at-rule params', () => { let { css } = postcss([replacePrintToMobile, replaceScreenToPrint]).process( '@media (screen) {}', { from: 'a.css' } ) is(css, '@media (mobile) {}') }) test('wraps node to proxies', () => { let proxy: any let root: Root | undefined postcss({ Once(node) { root = node }, postcssPlugin: 'proxyCatcher', Rule(node) { proxy = node } }).process('a{color:black}', { from: 'a.css' }).css if (!root) throw new Error('Nodes were not catched') let rule = root.first as Rule equal(proxy.proxyOf, rule) equal(proxy.root().proxyOf, rule.root()) equal(proxy.nodes[0].proxyOf, rule.first) equal(proxy.first.proxyOf, rule.first) type(proxy.unknown, 'undefined') is( proxy.some((decl: Declaration) => decl.prop === 'color'), true ) is( proxy.every((decl: Declaration) => decl.prop === 'color'), true ) let props: string[] = [] proxy.walkDecls((decl: Declaration) => props.push(decl.prop)) equal(props, ['color']) }) const cssThree = '.a{ color: red; } .b{ will-change: transform; }' const expectedThree = '.a{ ' + 'backface-visibility: hidden; ' + 'will-change: transform; ' + 'color: green; ' + '} ' + '.b{ backface-visibility: hidden; will-change: transform; }' test('work of three plug-ins; sequence 1', async () => { let { css } = await postcss([ replaceColorGreenClassic, willChangeVisitor, addPropsVisitor ]).process(cssThree, { from: 'a.css' }) is(css, expectedThree) }) test('work of three plug-ins; sequence 2', async () => { let { css } = await postcss([ addPropsVisitor, replaceColorGreenClassic, willChangeVisitor ]).process(cssThree, { from: 'a.css' }) is(css, expectedThree) }) const cssThreeDocument = postcss.document({ nodes: [ postcss.parse('.a{ color: red; }'), postcss.parse('.b{ will-change: transform; }') ] }) const expectedThreeDocument = '.a{ color: green; }' + '.b{ backface-visibility: hidden; will-change: transform; }' test('work of three plug-ins in a document; sequence 1', async () => { let { css } = await postcss([ replaceColorGreenClassic, willChangeVisitor, addPropsVisitor ]).process(cssThreeDocument, { from: 'a.css' }) is(css, expectedThreeDocument) }) test('work of three plug-ins in a document; sequence 2', async () => { let { css } = await postcss([ addPropsVisitor, replaceColorGreenClassic, willChangeVisitor ]).process(cssThreeDocument, { from: 'a.css' }) is(css, expectedThreeDocument) }) const cssThroughProps = '.a{color: yellow;}' const expectedThroughProps = '.a{color: red;}' test('change in node values through props; sequence 1', async () => { let { css } = await postcss([ replaceGreenToRed, replaceAllButRedToGreen ]).process(cssThroughProps, { from: 'a.css' }) is(css, expectedThroughProps) }) test('change in node values through props; sequence 2', async () => { let { css } = await postcss([ replaceAllButRedToGreen, replaceGreenToRed ]).process(cssThroughProps, { from: 'a.css' }) is(css, expectedThroughProps) }) test('works visitor plugin postcss-focus', async () => { let input = '*:focus { outline: 0; }.button:hover { background: red; }' let expected = '*:focus { outline: 0; }' + '.button:hover, .button:focus { background: red; }' let { css } = await postcss([postcssFocus]).process(input, { from: 'a.css' }) is(css, expected) }) test('works visitor plugin hidden', async () => { let input = 'h2{' + 'display: hidden;' + '}' let expected = 'h2{' + 'position: absolute;' + 'width: 1px;' + 'height: 1px;' + 'margin: -1px;' + 'padding: 0;' + 'border: 0;' + 'overflow: hidden;' + 'clip: rect(0 0 0 0);' + '}' + 'h2.focusable:active,' + 'h2.focusable:focus{' + 'display: table;' + 'position: static;' + 'clear: both;' + '}' let { css } = await postcss([hidden]).process(input, { from: 'a.css' }) is(css, expected) }) let cssFocusHidden = '*:focus { outline: 0; }' + '.button:hover { background: red; }' + 'h2:hover{' + 'display: hidden;' + '}' let expectedFocusHidden = '*:focus { outline: 0; }' + '.button:hover, .button:focus { background: red; }' + 'h2:hover,h2:focus{' + 'position: absolute;' + 'width: 1px;' + 'height: 1px;' + 'margin: -1px;' + 'padding: 0;' + 'border: 0;' + 'overflow: hidden;' + 'clip: rect(0 0 0 0);' + '}' + 'h2:hover.focusable:active,' + 'h2:hover.focusable:focus,' + 'h2:focus.focusable:active,' + 'h2:focus.focusable:focus{' + 'display: table;' + 'position: static;' + 'clear: both;' + '}' test('works visitor plugins postcss-focus and hidden; sequence 1', async () => { let { css } = await postcss([hidden, postcssFocus]).process(cssFocusHidden, { from: 'a.css' }) is(css, expectedFocusHidden) }) test('works visitor plugins postcss-focus and hidden; sequence 2', async () => { let { css } = await postcss([postcssFocus, hidden]).process(cssFocusHidden, { from: 'a.css' }) is(css, expectedFocusHidden) }) test('works visitor plugin postcss-alias', async () => { let input = '@alias { fs: font-size; bg: background; }' + '.aliased { fs: 16px; bg: white; }' let expected = '.aliased { font-size: 16px; background: white; }' let { css } = postcss([postcssAlias]).process(input, { from: 'a.css' }) is(css, expected) }) test('adds plugin to error', async () => { let broken: Plugin = { postcssPlugin: 'broken', Rule(rule) { throw rule.error('test') } } let error: any try { postcss([broken]).process('a{}', { from: 'broken.css' }).css } catch (e) { error = e } is(error.message, `broken: ${resolve('broken.css')}:1:1: test`) is(error.postcssNode.toString(), 'a{}') is(error.stack.includes('broken.css:1:1'), true) }) test('adds plugin to async error', async () => { let broken: Plugin = { postcssPlugin: 'broken', async Rule(rule) { await delay(1) throw rule.error('test') } } let error: any try { await postcss([broken]).process('a{}', { from: 'broken.css' }) } catch (e) { error = e } is(error.message, `broken: ${resolve('broken.css')}:1:1: test`) is(error.postcssNode.toString(), 'a{}') is(error.stack.includes('broken.css:1:1'), true) }) test('adds sync plugin to async error', async () => { let broken: Plugin = { postcssPlugin: 'broken', Rule(rule) { throw rule.error('test') } } let error: any try { await postcss([broken]).process('a{}', { from: 'broken.css' }) } catch (e) { error = e } is(error.message, `broken: ${resolve('broken.css')}:1:1: test`) is(error.postcssNode.toString(), 'a{}') is(error.stack.includes('broken.css:1:1'), true) }) test('adds node to error', async () => { let broken: Plugin = { postcssPlugin: 'broken', Rule() { throw new Error('test') } } let error: any try { postcss([broken]).process('a{}', { from: 'broken.css' }).css } catch (e) { error = e } is(error.message, 'test') is(error.postcssNode.toString(), 'a{}') is(error.stack.includes('broken.css:1:1'), true) }) test('adds node to async error', async () => { let broken: Plugin = { postcssPlugin: 'broken', async Rule() { await delay(1) throw new Error('test') } } let error: any try { await postcss([broken]).process('a{}', { from: 'broken.css' }) } catch (e) { error = e } is(error.message, 'test') is(error.postcssNode.toString(), 'a{}') is(error.stack.includes('broken.css:1:1'), true) }) test('shows error on sync call async plugins', () => { let asyncPlugin: Plugin = { postcssPlugin: 'asyncPlugin', async Rule() {} } let error: any try { postcss([asyncPlugin]).process('a{}', { from: 'broken.css' }).css } catch (e) { error = e } is(error.message.includes('work with async plugins'), true) }) test('passes helpers', async () => { function check(node: AnyNode, helpers: Helpers): void { equal(helpers.result.messages, []) is(typeof helpers.postcss, 'function') is(helpers.comment().type, 'comment') is(new helpers.Comment().type, 'comment') equal(helpers.list, postcss.list) } let syncPlugin: Plugin = { Once: check, OnceExit: check, postcssPlugin: 'syncPlugin', Rule: check, RuleExit: check } let asyncPlugin: Plugin = { async Once(node, helpers) { await delay(1) check(node, helpers) }, async OnceExit(node, helpers) { await delay(1) check(node, helpers) }, postcssPlugin: 'syncPlugin', async Rule(node, helpers) { await delay(1) check(node, helpers) } } postcss([syncPlugin]).process('a{}', { from: 'a.css' }).css await postcss([asyncPlugin]).process('a{}', { from: 'a.css' }) }) test('passes helpers in a document', async () => { function check(node: AnyNode, helpers: Helpers): void { equal(helpers.result.messages, []) type(helpers.postcss, 'function') is(helpers.comment().type, 'comment') is(new helpers.Comment().type, 'comment') equal(helpers.list, postcss.list) } let syncPlugin: Plugin = { Once: check, OnceExit: check, postcssPlugin: 'syncPlugin', Rule: check, RuleExit: check } let asyncPlugin: Plugin = { async Once(node, helpers) { await delay(1) check(node, helpers) }, async OnceExit(node, helpers) { await delay(1) check(node, helpers) }, postcssPlugin: 'syncPlugin', async Rule(node, helpers) { await delay(1) check(node, helpers) } } postcss([syncPlugin]).process( postcss.document({ nodes: [postcss.parse('a{}')] }), { from: 'a.css' } ).css await postcss([asyncPlugin]).process( postcss.document({ nodes: [postcss.parse('a{}')] }), { from: 'a.css' } ) }) test('detects non-changed values', () => { let plugin: Plugin = { Declaration(decl) { decl.value = 'red' }, postcssPlugin: 'test' } is( postcss([plugin]).process('a{ color: black; background: white; }', { from: 'a.css' }).css, 'a{ color: red; background: red; }' ) }) test('allows runtime listeners', () => { let root = false let plugin: Plugin = { Declaration(decl) { decl.value = 'red' }, postcssPlugin: 'test', prepare(result) { return { Once() { root = true }, Rule(rule) { rule.selector = basename(result.opts.from ?? '') } } } } is( postcss([plugin]).process('a{ color: black }', { from: 'a.css' }).css, 'a.css{ color: red }' ) is(root, true) }) test('works correctly with nodes changes', () => { let plugin: Plugin = { postcssPlugin: 'test', Rule(rule) { if (!rule.some(i => i.type === 'decl' && i.prop === 'z-index')) { rule.prepend({ prop: 'z-index', value: '1' }) } } } is( postcss([plugin]).process('a{ color: black }', { from: 'a.css' }).css, 'a{ z-index: 1; color: black }' ) }) test('throws error on unknown plugin property', () => { let plugin: any = { NO: true, postcssPlugin: 'test' } throws(() => { postcss([plugin]).process('').css }, /Unknown event NO in test\. Try to update PostCSS \(\d/) }) test('unwraps nodes on inserting', () => { let moveNode: Plugin = { Declaration: { color: decl => { if (decl.parent?.type !== 'root') { decl.root().append(decl) } } }, postcssPlugin: 'moveNode' } let root = postcss([moveNode]).process('a{color:red}').root equal((root.last as any).proxyOf, root.last) }) let redToGreen: Plugin = { Declaration: { color: decl => { if (decl.value === 'red') { decl.value = 'green' } } }, postcssPlugin: 'redToGreen' } let greenToBlue: Plugin = { Declaration(decl) { if (decl.value === 'green') { decl.value = 'blue' } }, postcssPlugin: 'greenToBlue' } let fooToBar: Plugin = { postcssPlugin: 'fooToBar', Rule(rule) { if (rule.selector === '.foo') { rule.selectors = ['.bar'] } } } let mixins: Plugin = { postcssPlugin: 'mixin', prepare() { let mixin: AnyNode | undefined return { AtRule: { 'apply-mixin': atRule => { if (mixin) atRule.replaceWith(mixin) }, 'define-mixin': atRule => { if (atRule.first) mixin = atRule.first atRule.remove() } } } } } let insertFirst: Plugin = { AtRule: { 'insert-first': atRule => { let first = atRule.root().first if (first) atRule.replaceWith(first) } }, postcssPlugin: 'insertFirst' } for (let funcType of ['sync', 'async']) { test(`walks ${funcType} through tree`, async () => { let [visits, visitor] = buildVisitor() let processor = postcss([visitor]).process( `@media screen { body { /* comment */ background: white; padding: 10px; } a { color: blue; } }`, { from: 'a.css' } ) if (funcType === 'sync') { processor.css } else { await processor } equal( addIndex(visits), addIndex([ ['Once', '1'], ['Root', '1'], ['AtRule', 'media'], ['Rule', 'body'], ['Comment', 'comment'], ['CommentExit', 'comment'], ['Declaration', 'background: white'], ['DeclarationExit', 'background: white'], ['Declaration', 'padding: 10px'], ['DeclarationExit', 'padding: 10px'], ['RuleExit', 'body'], ['Rule', 'a'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRuleExit', 'media'], ['RootExit', '1'], ['OnceExit', '1'] ]) ) }) test(`walks ${funcType} through tree in a document`, async () => { let document = postcss.document({ nodes: [ postcss.parse(`@media screen { body { /* comment */ background: white; padding: 10px; } a { color: blue; } }`) ] }) let [visits, visitor] = buildVisitor() let processor = postcss([visitor]).process(document, { from: 'a.css' }) if (funcType === 'sync') { processor.css } else { await processor } equal( addIndex(visits), addIndex([ ['Once', '1'], ['Document', '1'], ['Root', '1'], ['AtRule', 'media'], ['Rule', 'body'], ['Comment', 'comment'], ['CommentExit', 'comment'], ['Declaration', 'background: white'], ['DeclarationExit', 'background: white'], ['Declaration', 'padding: 10px'], ['DeclarationExit', 'padding: 10px'], ['RuleExit', 'body'], ['Rule', 'a'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRuleExit', 'media'], ['RootExit', '1'], ['DocumentExit', '1'], ['OnceExit', '1'] ]) ) }) test(`walks ${funcType} during transformations`, async () => { let [visits, visitor] = buildVisitor() let result = postcss([ visitor, redToGreen, greenToBlue, mixins, fooToBar, insertFirst ]).process( `.first { color: red; } @define-mixin { b { color: red; } } a { color: red; } @media (screen) { @insert-first; } .foo { background: red; } @apply-mixin;`, { from: 'a.css' } ) let output if (funcType === 'sync') { output = result.css } else { output = (await result).css } is( output, `a { color: blue; } @media (screen) {.first { color: blue; } } .bar { background: red; } b { color: blue; }` ) equal( addIndex(visits), addIndex([ ['Once', '6'], ['Root', '6'], ['Rule', '.first'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', '.first'], ['AtRule', 'define-mixin'], ['Rule', 'a'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', 'a'], ['AtRule', 'media'], ['AtRule', 'insert-first'], ['AtRuleExit', 'media'], ['Rule', '.foo'], ['Declaration', 'background: red'], ['DeclarationExit', 'background: red'], ['RuleExit', '.bar'], ['AtRule', 'apply-mixin'], ['RootExit', '4'], ['Root', '4'], ['Rule', 'a'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRule', 'media'], ['Rule', '.first'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', '.first'], ['AtRuleExit', 'media'], ['Rule', 'b'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', 'b'], ['RootExit', '4'], ['Root', '4'], ['Rule', 'a'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRule', 'media'], ['Rule', '.first'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', '.first'], ['AtRuleExit', 'media'], ['Rule', 'b'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'b'], ['RootExit', '4'], ['Root', '4'], ['Rule', 'b'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'b'], ['RootExit', '4'], ['OnceExit', '4'] ]) ) }) test(`walks ${funcType} during transformations in a document`, async () => { let document = postcss.document({ nodes: [ postcss.parse( `.first { color: red; } @define-mixin { b { color: red; } } a { color: red; } @media (screen) { @insert-first; } .foo { background: red; } @apply-mixin;` ) ] }) let [visits, visitor] = buildVisitor() let result = postcss([ visitor, redToGreen, greenToBlue, mixins, fooToBar, insertFirst ]).process(document, { from: 'a.css' }) let output if (funcType === 'sync') { output = result.css } else { output = (await result).css } is( output, `a { color: blue; } @media (screen) {.first { color: blue; } } .bar { background: red; } b { color: blue; }` ) equal( addIndex(visits), addIndex([ ['Once', '6'], ['Document', '1'], ['Root', '6'], ['Rule', '.first'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', '.first'], ['AtRule', 'define-mixin'], ['Rule', 'a'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', 'a'], ['AtRule', 'media'], ['AtRule', 'insert-first'], ['AtRuleExit', 'media'], ['Rule', '.foo'], ['Declaration', 'background: red'], ['DeclarationExit', 'background: red'], ['RuleExit', '.bar'], ['AtRule', 'apply-mixin'], ['RootExit', '4'], ['DocumentExit', '1'], ['Document', '1'], ['Root', '4'], ['Rule', 'a'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRule', 'media'], ['Rule', '.first'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', '.first'], ['AtRuleExit', 'media'], ['Rule', 'b'], ['Declaration', 'color: red'], ['DeclarationExit', 'color: green'], ['RuleExit', 'b'], ['RootExit', '4'], ['DocumentExit', '1'], ['Document', '1'], ['Root', '4'], ['Rule', 'a'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'a'], ['AtRule', 'media'], ['Rule', '.first'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', '.first'], ['AtRuleExit', 'media'], ['Rule', 'b'], ['Declaration', 'color: green'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'b'], ['RootExit', '4'], ['DocumentExit', '1'], ['Document', '1'], ['Root', '4'], ['Rule', 'b'], ['Declaration', 'color: blue'], ['DeclarationExit', 'color: blue'], ['RuleExit', 'b'], ['RootExit', '4'], ['DocumentExit', '1'], ['OnceExit', '4'] ]) ) }) test(`has ${funcType} property and at-rule name filters`, async () => { let filteredDecls: string[] = [] let allDecls: string[] = [] let filteredAtRules: string[] = [] let allAtRules: string[] = [] let allExits: string[] = [] let filteredExits: string[] = [] let scanner: Plugin = { AtRule: { '*': atRule => { allAtRules.push(atRule.name) }, 'media': atRule => { filteredAtRules.push(atRule.name) } }, Declaration: { '*': decl => { allDecls.push(decl.prop) }, 'color': decl => { filteredDecls.push(decl.prop) } }, DeclarationExit: { '*': decl => { allExits.push(decl.prop) }, 'color': decl => { filteredExits.push(decl.prop) } }, postcssPlugin: 'test' } let result = postcss([scanner]).process( `@charset "UTF-8"; @media (screen) { COLOR: black; z-index: 1 }`, { from: 'a.css' } ) if (funcType === 'sync') { result.css } else { await result } equal(filteredDecls, ['COLOR']) equal(allDecls, ['COLOR', 'z-index']) equal(filteredExits, ['COLOR']) equal(allExits, ['COLOR', 'z-index']) equal(filteredAtRules, ['media']) equal(allAtRules, ['charset', 'media']) }) test(`has ${funcType} property and at-rule name filters in a document`, async () => { let filteredDecls: string[] = [] let allDecls: string[] = [] let filteredAtRules: string[] = [] let allAtRules: string[] = [] let allExits: string[] = [] let filteredExits: string[] = [] let scanner: Plugin = { AtRule: { '*': atRule => { allAtRules.push(atRule.name) }, 'media': atRule => { filteredAtRules.push(atRule.name) } }, Declaration: { '*': decl => { allDecls.push(decl.prop) }, 'color': decl => { filteredDecls.push(decl.prop) } }, DeclarationExit: { '*': decl => { allExits.push(decl.prop) }, 'color': decl => { filteredExits.push(decl.prop) } }, postcssPlugin: 'test' } let document = postcss.document({ nodes: [ postcss.parse( `@charset "UTF-8"; @media (screen) { COLOR: black; z-index: 1 }` ) ] }) let result = postcss([scanner]).process(document, { from: 'a.css' }) if (funcType === 'sync') { result.css } else { await result } equal(filteredDecls, ['COLOR']) equal(allDecls, ['COLOR', 'z-index']) equal(filteredExits, ['COLOR']) equal(allExits, ['COLOR', 'z-index']) equal(filteredAtRules, ['media']) equal(allAtRules, ['charset', 'media']) }) test(`has ${funcType} OnceExit listener`, async () => { let rootExit = 0 let OnceExit = 0 let plugin: Plugin = { OnceExit() { OnceExit += 1 }, postcssPlugin: 'test', RootExit() { rootExit += 1 }, Rule(rule) { rule.remove() } } let result = postcss([plugin]).process('a{}', { from: 'a.css' }) if (funcType === 'sync') { result.css } else { await result } is(rootExit, 2) is(OnceExit, 1) }) test(`has ${funcType} OnceExit listener in a document with one root`, async () => { let RootExit = 0 let OnceExit = 0 let DocumentExit = 0 let plugin: Plugin = { DocumentExit() { DocumentExit += 1 }, OnceExit() { OnceExit += 1 }, postcssPlugin: 'test', RootExit() { RootExit += 1 }, Rule(rule) { rule.remove() } } let document = postcss.document({ nodes: [postcss.parse('a{}')] }) let result = postcss([plugin]).process(document, { from: 'a.css' }) if (funcType === 'sync') { result.css } else { await result } is(RootExit, 2) is(DocumentExit, 2) is(OnceExit, 1) }) test(`has ${funcType} OnceExit listener in a document with two roots`, async () => { let RootExit = 0 let OnceExit = 0 let DocumentExit = 0 let plugin: Plugin = { DocumentExit() { DocumentExit += 1 }, OnceExit() { OnceExit += 1 }, postcssPlugin: 'test', RootExit() { RootExit += 1 }, Rule(rule) { rule.remove() } } let document = postcss.document({ nodes: [postcss.parse('a{}'), postcss.parse('b{}')] }) let result = postcss([plugin]).process(document, { from: 'a.css' }) if (funcType === 'sync') { result.css } else { await result } is(RootExit, 4) is(DocumentExit, 2) is(OnceExit, 2) // 2 roots === 2 OnceExit }) } test('throws error from async OnceExit', async () => { let plugin: Plugin = { OnceExit() { throw new Error('test Exit error') }, postcssPlugin: 'test' } let result = postcss([plugin]).process('a{ color: black }', { from: 'a.css' }) let error: any try { await result } catch (e) { error = e } is(error.message, 'test Exit error') }) test('rescan Root in another processor', () => { let [visits, visitor] = buildVisitor() let root = postcss([visitor]).process('a{z-index:1}', { from: 'a.css' }).root visits.splice(0, visits.length) postcss([visitor]).process(root, { from: 'a.css' }).root equal(visits, [ ['Once', '1'], ['Root', '1'], ['Rule', 'a'], ['Declaration', 'z-index: 1'], ['DeclarationExit', 'z-index: 1'], ['RuleExit', 'a'], ['RootExit', '1'], ['OnceExit', '1'] ]) }) test('rescan Root in another processor in a document', () => { let [visits, visitor] = buildVisitor() let root = postcss([visitor]).process('a{z-index:1}', { from: 'a.css' }).root let document = postcss.document({ nodes: [root] }) visits.splice(0, visits.length) postcss([visitor]).process(document, { from: 'a.css' }).root equal(visits, [ ['Once', '1'], ['Document', '1'], ['Root', '1'], ['Rule', 'a'], ['Declaration', 'z-index: 1'], ['DeclarationExit', 'z-index: 1'], ['RuleExit', 'a'], ['RootExit', '1'], ['DocumentExit', '1'], ['OnceExit', '1'] ]) }) test('marks cleaned nodes as dirty on moving', () => { let mover: Plugin = { postcssPlugin: 'mover', Rule(rule) { if (rule.selector === 'b') { let a = rule.prev() if (a) rule.append(a) } } } let [visits, visitor] = buildVisitor() postcss([mover, visitor]).process('a { color: black } b { }', { from: 'a.css' }).root equal(visits, [ ['Once', '2'], ['Root', '2'], ['Rule', 'a'], ['Declaration', 'color: black'], ['DeclarationExit', 'color: black'], ['RuleExit', 'a'], ['Rule', 'b'], ['Rule', 'a'], ['Declaration', 'color: black'], ['DeclarationExit', 'color: black'], ['RuleExit', 'a'], ['RuleExit', 'b'], ['RootExit', '1'], ['Root', '1'], ['Rule', 'b'], ['RuleExit', 'b'], ['RootExit', '1'], ['OnceExit', '1'] ]) }) test('marks cleaned nodes as dirty on moving in a document', () => { let mover: Plugin = { postcssPlugin: 'mover', Rule(rule) { if (rule.selector === 'b') { let a = rule.prev() if (a) rule.append(a) } } } let [visits, visitor] = buildVisitor() let document = postcss.document({ nodes: [postcss.parse('a { color: black } b { }')] }) postcss([mover, visitor]).process(document, { from: 'a.css' }).root equal(visits, [ ['Once', '2'], ['Document', '1'], ['Root', '2'], ['Rule', 'a'], ['Declaration', 'color: black'], ['DeclarationExit', 'color: black'], ['RuleExit', 'a'], ['Rule', 'b'], ['Rule', 'a'], ['Declaration', 'color: black'], ['DeclarationExit', 'color: black'], ['RuleExit', 'a'], ['RuleExit', 'b'], ['RootExit', '1'], ['DocumentExit', '1'], ['Document', '1'], ['Root', '1'], ['Rule', 'b'], ['RuleExit', 'b'], ['RootExit', '1'], ['DocumentExit', '1'], ['OnceExit', '1'] ]) }) test('append works after reassigning nodes through .parent', async () => { let plugin: Plugin = { OnceExit(root) { let firstNode = root.nodes[0] as AtRule let secondNode = root.nodes[1] as AtRule let rule2 = secondNode.nodes![0] rule2.parent!.nodes = rule2.parent!.nodes firstNode.append(...secondNode.nodes!) secondNode.remove() }, postcssPlugin: 'test', Rule(rule) { if ( !( rule.selector === '.nested' && rule.nodes.length === 1 && rule.nodes[0].type === 'atrule' ) ) { return } let atrule = rule.nodes[0] atrule.append(rule.clone({ nodes: [] }).append(...atrule.nodes!)) rule.after(atrule) rule.remove() } } let { css } = await postcss([plugin]).process( postcss.parse( `@media (min-width:640px) { .page { width: auto; } } ` + `.nested { @media (min-width:640px) { width: auto; } }` ), { from: 'whatever' } ) is( css, '@media (min-width:640px) { .page { width: auto; } .nested { width: auto } }' ) }) test.run() postcss-8.4.49/test/warning.test.ts000066400000000000000000000116041471446070100172760ustar00rootroot00000000000000import { resolve } from 'path' import { test } from 'uvu' import { is, type } from 'uvu/assert' import { decl, parse, Warning } from '../lib/postcss.js' test('outputs simple warning', () => { let warning = new Warning('text') is(warning.toString(), 'text') }) test('outputs warning with plugin', () => { let warning = new Warning('text', { plugin: 'plugin' }) is(warning.toString(), 'plugin: text') }) test('outputs warning with position', () => { let root = parse('a{}') let warning = new Warning('text', { node: root.first }) is(warning.toString(), ':1:1: text') }) test('outputs warning with plugin and node', () => { let file = resolve('a.css') let root = parse('a{}', { from: file }) let warning = new Warning('text', { node: root.first, plugin: 'plugin' }) is(warning.toString(), `plugin: ${file}:1:1: text`) }) test('outputs warning with index', () => { let file = resolve('a.css') let root = parse('@rule param {}', { from: file }) let warning = new Warning('text', { index: 7, node: root.first, plugin: 'plugin' }) is(warning.toString(), `plugin: ${file}:1:8: text`) }) test('outputs warning with word', () => { let file = resolve('a.css') let root = parse('@rule param {}', { from: file }) let warning = new Warning('text', { node: root.first, plugin: 'plugin', word: 'am' }) is(warning.toString(), `plugin: ${file}:1:10: text`) }) test('generates warning without source', () => { let node = decl({ prop: 'color', value: 'black' }) let warning = new Warning('text', { node }) is(warning.toString(), ': text') }) test('has line and column is undefined by default', () => { let warning = new Warning('text') type(warning.line, 'undefined') type(warning.column, 'undefined') type(warning.endLine, 'undefined') type(warning.endColumn, 'undefined') }) test('gets range from node', () => { let root = parse('a{}') let warning = new Warning('text', { node: root.first }) is(warning.line, 1) is(warning.column, 1) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('gets range from node without end', () => { let root = parse('a{}') root.first!.source!.end = undefined let warning = new Warning('text', { node: root.first }) is(warning.line, 1) is(warning.column, 1) is(warning.endLine, 1) is(warning.endColumn, 2) }) test('gets range from node with endIndex 3', () => { let root = parse('a{}') let warning = new Warning('text', { endIndex: 3, index: 0, node: root.first }) is(warning.line, 1) is(warning.column, 1) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('gets range from node with endIndex 0', () => { let root = parse('a{}') let warning = new Warning('text', { endIndex: 0, index: 0, node: root.first }) is(warning.line, 1) is(warning.column, 1) is(warning.endLine, 1) is(warning.endColumn, 2) }) test('gets range from word', () => { let root = parse('a b{}') let warning = new Warning('text', { node: root.first, word: 'b' }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('gets range from index', () => { let root = parse('a b{}') let warning = new Warning('text', { index: 2, node: root.first }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('gets range from index and endIndex', () => { let root = parse('a b{}') let warning = new Warning('text', { endIndex: 3, index: 2, node: root.first }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('gets range from start', () => { let root = parse('a b{}') let warning = new Warning('text', { node: root.first, start: { column: 3, line: 1 } }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 6) }) test('gets range from end', () => { let root = parse('a b{}') let warning = new Warning('text', { end: { column: 3, line: 1 }, node: root.first }) is(warning.line, 1) is(warning.column, 1) is(warning.endLine, 1) is(warning.endColumn, 3) }) test('gets range from start and end', () => { let root = parse('a b{}') let warning = new Warning('text', { end: { column: 4, line: 1 }, node: root.first, start: { column: 3, line: 1 } }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 4) }) test('always returns exclusive ends', () => { let root = parse('a b{}') let warning = new Warning('text', { endIndex: 1, index: 1, node: root.first }) is(warning.line, 1) is(warning.column, 2) is(warning.endLine, 1) is(warning.endColumn, 3) }) test('always returns valid ranges', () => { let root = parse('a b{}') let warning = new Warning('text', { endIndex: 1, index: 2, node: root.first }) is(warning.line, 1) is(warning.column, 3) is(warning.endLine, 1) is(warning.endColumn, 4) }) test.run() postcss-8.4.49/tsconfig.json000066400000000000000000000002171471446070100160310ustar00rootroot00000000000000{ "compilerOptions": { "lib": ["es2018"], "target": "es2018", "module": "commonjs", "strict": true, "noEmit": true } }