diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index fae8897c8..000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* eol=lf diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..6eec078d6 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,68 @@ +# 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 diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 04f82bab2..91de44399 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,3 @@ open_collective: postcss tidelift: npm/postcss +github: ai diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..b379d876d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,99 @@ +name: 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@v2 + with: + version: 8 + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: pnpm + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + - name: Run tests + run: pnpm test + short: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: + - 18 + - 16 + name: Node.js ${{ matrix.node-version }} Quick + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + - name: Install Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: pnpm + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + - name: Run unit tests + run: pnpm run unit + old: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: + - 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@v1 + with: + version: 3 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + - name: Install Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + 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@v2 + with: + version: latest + - name: Install Node.js LTS + uses: actions/setup-node@v3 + with: + node-version: 20 + cache: pnpm + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + - name: Run unit tests + run: pnpm run unit diff --git a/.gitignore b/.gitignore index f6147a066..3030054ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,6 @@ -.DS_Store -*~ - node_modules/ -npm-debug.log -yarn-error.log - -build/ -lib/*.js -api/ coverage/ + +docs/api/index.html +docs/api/assets/ diff --git a/.jsdocrc b/.jsdocrc deleted file mode 100644 index f06a846f7..000000000 --- a/.jsdocrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "source": { - "includePattern": ".+\\.es6$" - }, - "opts": { - "template": "node_modules/docdash", - "destination": "./api/" - }, - "plugins": ["plugins/markdown"], - "templates": { - "default": { - "layoutFile": "node_modules/docdash/tmpl/layout.tmpl", - "includeDate": false - } - } -} diff --git a/.npmignore b/.npmignore index 890dc8d4f..de9010b49 100644 --- a/.npmignore +++ b/.npmignore @@ -1,14 +1,5 @@ -node_modules/ -npm-debug.log -yarn-error.log -yarn.lock - -build/ - +coverage/ test/ -.travis.yml -appveyor.yml - -gulpfile.js -api/ +docs/ +tsconfig.json diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 599e34703..000000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -cache: yarn -node_js: - - node - - "12" - - "10" - - "8" - - "6" -git: - depth: 5 -install: - - yarn install --ignore-engines diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b1cde29e..05c9da70e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,333 @@ # Change Log -This project adheres to [Semantic Versioning](http://semver.org/). +This project adheres to [Semantic Versioning](https://semver.org/). + +## 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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 227caa27d..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,78 +0,0 @@ -# Contributing Guide to PostCSS - -If you want contribute to PostCSS, there are few things that you should -be familiar with. - - -## In Case You Have Question About Using PostCSS - -* **Ask for help in [the chat]** - - If you stuck on something there is a big chance - that someone had similar problem before. - -[the chat]: https://gitter.im/postcss/postcss - - -## Adding Your Plugin to the List - -If you created or found a plugin and want to add it to PostCSS plugins list -follow this simple steps. - -PR should not change plugins defined in README it contains only favorite plugins -and moderated by PostCSS author. - -Plugins submitted by community located in [`docs/plugins`]. - -* **Keep plugins order** - - Be sure that plugin not presented yet and find suitable position - in alphabetic order for it. - But plugins with `postcss-` prefix should come first. - -* **Check spelling** - - Before submitting PR be sure that spelling check pass. - For that run command `npm test`. - If it fails with unknown word error, add it as word - to `.yaspellerrc` dictionary. - -* **Check PostCSS plugin guideline** - - Provided plugin should match plugin [guidelines]. - -- **Provide link to suggested plugin** - - Make sure your pull request description contains link to plugin - you are willing to add. - -[`docs/plugins`]: https://github.com/postcss/postcss/blob/master/docs/plugins.md -[guidelines]: https://github.com/postcss/postcss/blob/master/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 same subject. - * Interfaces used for defining custom types. - - Make sure you read through declaration file writing [best practices] - by 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 feature or fix existed issue - -- **Become familiar with PostCSS architecture** - - For gentle intro to PostCSS architecture look through our [guide]. - -[guide]: https://github.com/postcss/postcss/blob/master/docs/architecture.md diff --git a/README.md b/README.md index c008e1f40..c6a041523 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,28 @@ -# PostCSS [![Gitter][chat-img]][chat] +# PostCSS Philosopher’s stone, logo of PostCSS - -[chat-img]: https://img.shields.io/badge/Gitter-Join_the_PostCSS_chat-brightgreen.svg -[chat]: https://gitter.im/postcss/postcss + src="https://postcss.org/logo.svg"> 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] PostCSS plugin is one of the most popular -CSS processors. +and JetBrains. The [Autoprefixer] and [Stylelint] PostCSS plugins is one of the most popular CSS tools. -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 insert vendor prefixes. +--- -**Support / Discussion:** [Gitter](https://gitter.im/postcss/postcss)
-**Twitter account:** [@postcss](https://twitter.com/postcss)
-**VK.com page:** [postcss](https://vk.com/postcss)
-**中文翻译**: [`README-cn.md`](./README-cn.md) +  Made in Evil Martians, product consulting for developer tools. -For PostCSS commercial support (consulting, improving the front-end culture -of your company, PostCSS plugins), contact [Evil Martians] -at . +--- [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 - - Sponsored by Evil Martians - ## Sponsorship @@ -46,11 +31,20 @@ PostCSS needs your support. We are accepting donations Sponsored by Tailwind CSS + alt="Sponsored by Tailwind CSS" width="213" height="50"> +       + 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] or in the [searchable catalog]. Below is a list of our favorite plugins — the best demonstrations of what can be built @@ -58,8 +52,9 @@ on top of PostCSS. If you have any new ideas, [PostCSS plugin development] is really easy. -[searchable catalog]: http://postcss.parts -[plugins list]: https://github.com/postcss/postcss/blob/master/docs/plugins.md +[searchable catalog]: https://www.postcss.parts/ +[plugins list]: https://github.com/postcss/postcss/blob/main/docs/plugins.md + ### Solve Global CSS Problem @@ -74,26 +69,30 @@ If you have any new ideas, [PostCSS plugin development] is really easy. * [`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 -* [`precss`] contains plugins for Sass-like features, like variables, nesting, - and mixins. +* [`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-assets`] inserts image dimensions and inlines files. +* [`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 @@ -103,39 +102,40 @@ If you have any new ideas, [PostCSS plugin development] is really easy. * [`doiuse`] lints CSS for browser support, using data from Can I Use. * [`colorguard`] helps you maintain a consistent color palette. + ### Other -* [`postcss-rtl`] combines both-directional (left-to-right and right-to-left) styles in one CSS file. * [`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/master/docs/writing-a-plugin.md +[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/jonathantneal/postcss-preset-env +[`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/jonathantneal/postcss-write-svg +[`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 -[`postcss-assets`]: https://github.com/assetsjs/postcss-assets -[`font-magician`]: https://github.com/jonathantneal/postcss-font-magician +[`font-magician`]: https://github.com/csstools/postcss-font-magician [`autoprefixer`]: https://github.com/postcss/autoprefixer [`cq-prolyfill`]: https://github.com/ausi/cq-prolyfill -[`postcss-rtl`]: https://github.com/vkalinichev/postcss-rtl +[`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`]: http://cssnano.co -[`precss`]: https://github.com/jonathantneal/precss +[`cssnano`]: https://cssnano.co/ +[`postcss-nested`]: https://github.com/postcss/postcss-nested [`doiuse`]: https://github.com/anandthakker/doiuse [`rtlcss`]: https://github.com/MohammadYounes/rtlcss -[`short`]: https://github.com/jonathantneal/postcss-short +[`short`]: https://github.com/csstools/postcss-short [`lost`]: https://github.com/peterramsing/lost ## Syntaxes @@ -148,6 +148,8 @@ you can write a parser and/or stringifier to extend PostCSS. * [`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 { + parent: undefined + type: 'document' + + constructor(defaults?: Document.DocumentProps) + + assign(overrides: Document.DocumentProps | object): this + clone(overrides?: Partial): Document + cloneAfter(overrides?: Partial): Document + cloneBefore(overrides?: Partial): Document + + /** + * 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 diff --git a/lib/document.js b/lib/document.js new file mode 100644 index 000000000..44689917f --- /dev/null +++ b/lib/document.js @@ -0,0 +1,33 @@ +'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 diff --git a/lib/fromJSON.d.ts b/lib/fromJSON.d.ts new file mode 100644 index 000000000..e1deedbd3 --- /dev/null +++ b/lib/fromJSON.d.ts @@ -0,0 +1,9 @@ +import { JSONHydrator } from './postcss.js' + +interface FromJSON extends JSONHydrator { + default: FromJSON +} + +declare const fromJSON: FromJSON + +export = fromJSON diff --git a/lib/fromJSON.js b/lib/fromJSON.js new file mode 100644 index 000000000..09f2b89aa --- /dev/null +++ b/lib/fromJSON.js @@ -0,0 +1,54 @@ +'use strict' + +let Declaration = require('./declaration') +let PreviousMap = require('./previous-map') +let Comment = require('./comment') +let AtRule = require('./at-rule') +let Input = require('./input') +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 diff --git a/lib/input.d.ts b/lib/input.d.ts new file mode 100644 index 000000000..c718bd1d9 --- /dev/null +++ b/lib/input.d.ts @@ -0,0 +1,194 @@ +import { 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 + /** + * 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 diff --git a/lib/input.es6 b/lib/input.es6 deleted file mode 100644 index 21db68284..000000000 --- a/lib/input.es6 +++ /dev/null @@ -1,182 +0,0 @@ -import path from 'path' - -import CssSyntaxError from './css-syntax-error' -import PreviousMap from './previous-map' - -let sequence = 0 - -/** - * Represents the source CSS. - * - * @example - * const root = postcss.parse(css, { from: file }) - * const input = root.source.input - */ -class Input { - /** - * @param {string} css Input CSS source. - * @param {object} [opts] {@link Processor#process} options. - */ - constructor (css, opts = { }) { - if ( - css === null || - typeof css === 'undefined' || - (typeof css === 'object' && !css.toString) - ) { - throw new Error(`PostCSS received ${ css } instead of CSS string`) - } - - /** - * Input CSS source - * - * @type {string} - * - * @example - * const input = postcss.parse('a{}', { from: file }).input - * input.css //=> "a{}" - */ - 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 (/^\w+:\/\//.test(opts.from) || path.isAbsolute(opts.from)) { - /** - * The absolute path to the CSS source file defined - * with the `from` option. - * - * @type {string} - * - * @example - * const root = postcss.parse(css, { from: 'a.css' }) - * root.source.input.file //=> '/home/ai/a.css' - */ - this.file = opts.from - } else { - this.file = path.resolve(opts.from) - } - } - - let map = new PreviousMap(this.css, opts) - if (map.text) { - /** - * The input source map passed from a compilation step before PostCSS - * (for example, from Sass compiler). - * - * @type {PreviousMap} - * - * @example - * root.source.input.map.consumer().sources //=> ['a.sass'] - */ - this.map = map - let file = map.consumer().file - if (!this.file && file) this.file = this.mapResolve(file) - } - - if (!this.file) { - sequence += 1 - /** - * 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). - * - * @type {string} - * - * @example - * const root = postcss.parse(css) - * root.source.input.file //=> undefined - * root.source.input.id //=> "" - */ - this.id = '' - } - if (this.map) this.map.file = this.from - } - - error (message, line, column, opts = { }) { - let result - let origin = this.origin(line, column) - if (origin) { - result = new CssSyntaxError( - message, origin.line, origin.column, - origin.source, origin.file, opts.plugin - ) - } else { - result = new CssSyntaxError( - message, line, column, this.css, this.file, opts.plugin) - } - - result.input = { line, column, source: this.css } - if (this.file) result.input.file = this.file - - return result - } - - /** - * 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). - * - * @param {number} line Line in input CSS. - * @param {number} column Column in input CSS. - * - * @return {filePosition} Position in input source. - * - * @example - * root.source.input.origin(1, 1) //=> { file: 'a.css', line: 3, column: 1 } - */ - origin (line, column) { - if (!this.map) return false - let consumer = this.map.consumer() - - let from = consumer.originalPositionFor({ line, column }) - if (!from.source) return false - - let result = { - file: this.mapResolve(from.source), - line: from.line, - column: from.column - } - - let source = consumer.sourceContentFor(from.source) - if (source) result.source = source - - return result - } - - mapResolve (file) { - if (/^\w+:\/\//.test(file)) { - return file - } - return path.resolve(this.map.consumer().sourceRoot || '.', file) - } - - /** - * The CSS source identifier. Contains {@link Input#file} if the user - * set the `from` option, or {@link Input#id} if they did not. - * - * @type {string} - * - * @example - * 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 () { - return this.file || this.id - } -} - -export default Input - -/** - * @typedef {object} filePosition - * @property {string} file Path to file. - * @property {number} line Source line in file. - * @property {number} column Source column in file. - */ diff --git a/lib/input.js b/lib/input.js new file mode 100644 index 000000000..4b5ee5e02 --- /dev/null +++ b/lib/input.js @@ -0,0 +1,248 @@ +'use strict' + +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { fileURLToPath, pathToFileURL } = require('url') +let { isAbsolute, resolve } = require('path') +let { nanoid } = require('nanoid/non-secure') + +let terminalHighlight = require('./terminal-highlight') +let CssSyntaxError = require('./css-syntax-error') +let PreviousMap = require('./previous-map') + +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 result, endLine, endColumn + + 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) +} diff --git a/lib/lazy-result.d.ts b/lib/lazy-result.d.ts new file mode 100644 index 000000000..dd291aa3a --- /dev/null +++ b/lib/lazy-result.d.ts @@ -0,0 +1,190 @@ +import 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 diff --git a/lib/lazy-result.es6 b/lib/lazy-result.es6 deleted file mode 100644 index 5621b1a94..000000000 --- a/lib/lazy-result.es6 +++ /dev/null @@ -1,390 +0,0 @@ -import MapGenerator from './map-generator' -import stringify from './stringify' -import warnOnce from './warn-once' -import Result from './result' -import parse from './parse' - -function isPromise (obj) { - return typeof obj === 'object' && typeof obj.then === 'function' -} - -/** - * A Promise proxy for the result of PostCSS transformations. - * - * A `LazyResult` instance is returned by {@link Processor#process}. - * - * @example - * const lazy = postcss([autoprefixer]).process(css) - */ -class LazyResult { - constructor (processor, css, opts) { - this.stringified = false - this.processed = false - - let root - if (typeof css === 'object' && css !== null && css.type === 'root') { - root = css - } else if (css instanceof LazyResult || css instanceof Result) { - root = 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.error = error - } - } - - this.result = new Result(processor, root, opts) - } - - /** - * Returns a {@link Processor} instance, which will be used - * for CSS transformations. - * - * @type {Processor} - */ - get processor () { - return this.result.processor - } - - /** - * Options from the {@link Processor#process} call. - * - * @type {processOptions} - */ - get opts () { - return this.result.opts - } - - /** - * Processes input CSS through synchronous plugins, converts `Root` - * to a CSS string and returns {@link Result#css}. - * - * This property will only work with synchronous plugins. - * If the processor contains any asynchronous plugins - * it will throw an error. This is why this method is only - * for debug purpose, you should always use {@link LazyResult#then}. - * - * @type {string} - * @see Result#css - */ - get css () { - return this.stringify().css - } - - /** - * 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. This is why this method is only - * for debug purpose, you should always use {@link LazyResult#then}. - * - * @type {string} - * @see Result#content - */ - get content () { - return this.stringify().content - } - - /** - * Processes input CSS through synchronous plugins - * and returns {@link Result#map}. - * - * This property will only work with synchronous plugins. - * If the processor contains any asynchronous plugins - * it will throw an error. This is why this method is only - * for debug purpose, you should always use {@link LazyResult#then}. - * - * @type {SourceMapGenerator} - * @see Result#map - */ - get map () { - return this.stringify().map - } - - /** - * Processes input CSS through synchronous plugins - * and returns {@link Result#root}. - * - * This property will only work with synchronous plugins. If the processor - * contains any asynchronous plugins it will throw an error. - * - * This is why this method is only for debug purpose, - * you should always use {@link LazyResult#then}. - * - * @type {Root} - * @see Result#root - */ - get root () { - return this.sync().root - } - - /** - * Processes input CSS through synchronous plugins - * and returns {@link Result#messages}. - * - * This property will only work with synchronous plugins. If the processor - * contains any asynchronous plugins it will throw an error. - * - * This is why this method is only for debug purpose, - * you should always use {@link LazyResult#then}. - * - * @type {Message[]} - * @see Result#messages - */ - get messages () { - return this.sync().messages - } - - /** - * Processes input CSS through synchronous plugins - * and calls {@link Result#warnings()}. - * - * @return {Warning[]} Warnings from plugins. - */ - warnings () { - return this.sync().warnings() - } - - /** - * Alias for the {@link LazyResult#css} property. - * - * @example - * lazy + '' === lazy.css - * - * @return {string} Output CSS. - */ - toString () { - return this.css - } - - /** - * 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. - * - * @param {onFulfilled} onFulfilled Callback will be executed - * when all plugins will finish work. - * @param {onRejected} onRejected Callback will be executed on any error. - * - * @return {Promise} Promise API to make queue. - * - * @example - * postcss([autoprefixer]).process(css, { from: cssPath }).then(result => { - * console.log(result.css) - * }) - */ - 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) - } - - /** - * Processes input CSS through synchronous and asynchronous plugins - * and calls onRejected for each error thrown in any plugin. - * - * It implements standard Promise API. - * - * @param {onRejected} onRejected Callback will be executed on any error. - * - * @return {Promise} Promise API to make queue. - * - * @example - * postcss([autoprefixer]).process(css).then(result => { - * console.log(result.css) - * }).catch(error => { - * console.error(error) - * }) - */ - catch (onRejected) { - return this.async().catch(onRejected) - } - /** - * 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. - * - * @param {onFinally} onFinally Callback will be executed on any error or - * when all plugins will finish work. - * - * @return {Promise} Promise API to make queue. - * - * @example - * postcss([autoprefixer]).process(css).finally(() => { - * console.log('processing ended') - * }) - */ - finally (onFinally) { - return this.async().then(onFinally, onFinally) - } - - handleError (error, plugin) { - try { - 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])) { - 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) { - if (console && console.error) console.error(err) - } - } - - asyncTick (resolve, reject) { - if (this.plugin >= this.processor.plugins.length) { - this.processed = true - return resolve() - } - - try { - let plugin = this.processor.plugins[this.plugin] - let promise = this.run(plugin) - this.plugin += 1 - - if (isPromise(promise)) { - promise.then(() => { - this.asyncTick(resolve, reject) - }).catch(error => { - this.handleError(error, plugin) - this.processed = true - reject(error) - }) - } else { - this.asyncTick(resolve, reject) - } - } catch (error) { - this.processed = true - reject(error) - } - } - - async () { - if (this.processed) { - return new Promise((resolve, reject) => { - if (this.error) { - reject(this.error) - } else { - resolve(this.stringify()) - } - }) - } - if (this.processing) { - return this.processing - } - - this.processing = new Promise((resolve, reject) => { - if (this.error) return reject(this.error) - this.plugin = 0 - this.asyncTick(resolve, reject) - }).then(() => { - this.processed = true - return this.stringify() - }) - - return this.processing - } - - sync () { - if (this.processed) return this.result - this.processed = true - - if (this.processing) { - throw new Error( - 'Use process(css).then(cb) to work with async plugins') - } - - if (this.error) throw this.error - - for (let plugin of this.result.processor.plugins) { - let promise = this.run(plugin) - if (isPromise(promise)) { - throw new Error( - 'Use process(css).then(cb) to work with async plugins') - } - } - - return this.result - } - - run (plugin) { - this.result.lastPlugin = plugin - - try { - return plugin(this.result.root, this.result) - } catch (error) { - this.handleError(error, plugin) - throw error - } - } - - stringify () { - 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 - } -} - -export default LazyResult - -/** - * @callback onFulfilled - * @param {Result} result - */ - -/** - * @callback onRejected - * @param {Error} error - */ diff --git a/lib/lazy-result.js b/lib/lazy-result.js new file mode 100644 index 000000000..126f40c7e --- /dev/null +++ b/lib/lazy-result.js @@ -0,0 +1,550 @@ +'use strict' + +let { isClean, my } = require('./symbols') +let MapGenerator = require('./map-generator') +let stringify = require('./stringify') +let Container = require('./container') +let Document = require('./document') +let warnOnce = require('./warn-once') +let Result = require('./result') +let parse = require('./parse') +let Root = require('./root') + +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) diff --git a/lib/list.d.ts b/lib/list.d.ts new file mode 100644 index 000000000..1a74d74cf --- /dev/null +++ b/lib/list.d.ts @@ -0,0 +1,57 @@ +declare 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: string[], last: boolean): string[] + } +} + +// eslint-disable-next-line @typescript-eslint/no-redeclare +declare const list: list.List + +export = list diff --git a/lib/list.es6 b/lib/list.es6 deleted file mode 100644 index db2b65caa..000000000 --- a/lib/list.es6 +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Contains helpers for safely splitting lists of CSS values, - * preserving parentheses and quotes. - * - * @example - * const list = postcss.list - * - * @namespace list - */ -let list = { - - split (string, separators, last) { - let array = [] - let current = '' - let split = false - - let func = 0 - let quote = false - let escape = false - - for (let i = 0; i < string.length; i++) { - let letter = string[i] - - if (quote) { - if (escape) { - escape = false - } else if (letter === '\\') { - escape = true - } else if (letter === quote) { - quote = false - } - } else if (letter === '"' || letter === '\'') { - quote = letter - } else if (letter === '(') { - func += 1 - } else if (letter === ')') { - if (func > 0) func -= 1 - } else if (func === 0) { - if (separators.indexOf(letter) !== -1) 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 - }, - - /** - * Safely splits space-separated values (such as those for `background`, - * `border-radius`, and other shorthand properties). - * - * @param {string} string Space-separated values. - * - * @return {string[]} Split values. - * - * @example - * postcss.list.space('1px calc(10% + 1px)') //=> ['1px', 'calc(10% + 1px)'] - */ - space (string) { - let spaces = [' ', '\n', '\t'] - return list.split(string, spaces) - }, - - /** - * Safely splits comma-separated values (such as those for `transition-*` - * and `background` properties). - * - * @param {string} string Comma-separated values. - * - * @return {string[]} Split values. - * - * @example - * postcss.list.comma('black, linear-gradient(white, black)') - * //=> ['black', 'linear-gradient(white, black)'] - */ - comma (string) { - return list.split(string, [','], true) - } - -} - -export default list diff --git a/lib/list.js b/lib/list.js new file mode 100644 index 000000000..1b31f9809 --- /dev/null +++ b/lib/list.js @@ -0,0 +1,58 @@ +'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 diff --git a/lib/map-generator.es6 b/lib/map-generator.es6 deleted file mode 100644 index fc235f74e..000000000 --- a/lib/map-generator.es6 +++ /dev/null @@ -1,269 +0,0 @@ -import mozilla from 'source-map' -import path from 'path' - -class MapGenerator { - constructor (stringify, root, opts) { - this.stringify = stringify - this.mapOpts = opts.map || { } - this.root = root - this.opts = opts - } - - isMap () { - if (typeof this.opts.map !== 'undefined') { - return !!this.opts.map - } - return this.previous().length > 0 - } - - previous () { - if (!this.previousMaps) { - this.previousMaps = [] - this.root.walk(node => { - if (node.source && node.source.input.map) { - let map = node.source.input.map - if (this.previousMaps.indexOf(map) === -1) { - this.previousMaps.push(map) - } - } - }) - } - - return this.previousMaps - } - - 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 - } - - isSourcesContent () { - if (typeof this.mapOpts.sourcesContent !== 'undefined') { - return this.mapOpts.sourcesContent - } - if (this.previous().length) { - return this.previous().some(i => i.withContent()) - } - return true - } - - clearAnnotation () { - if (this.mapOpts.annotation === false) return - - 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.indexOf('# sourceMappingURL=') === 0) { - this.root.removeChild(i) - } - } - } - - setSourcesContent () { - let already = { } - this.root.walk(node => { - if (node.source) { - let from = node.source.input.from - if (from && !already[from]) { - already[from] = true - let relative = this.relative(from) - this.map.setSourceContent(relative, node.source.input.css) - } - } - }) - } - - applyPrevMaps () { - for (let prev of this.previous()) { - let from = this.relative(prev.file) - let root = prev.root || path.dirname(prev.file) - let map - - if (this.mapOpts.sourcesContent === false) { - map = new mozilla.SourceMapConsumer(prev.text) - if (map.sourcesContent) { - map.sourcesContent = map.sourcesContent.map(() => null) - } - } else { - map = prev.consumer() - } - - this.map.applySourceMap(map, from, this.relative(root)) - } - } - - 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 - } - - toBase64 (str) { - if (Buffer) { - return Buffer.from(str).toString('base64') - } - return window.btoa(unescape(encodeURIComponent(str))) - } - - 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 { - content = this.outputFile() + '.map' - } - - let eol = '\n' - if (this.css.indexOf('\r\n') !== -1) eol = '\r\n' - - this.css += eol + '/*# sourceMappingURL=' + content + ' */' - } - - outputFile () { - if (this.opts.to) { - return this.relative(this.opts.to) - } - if (this.opts.from) { - return this.relative(this.opts.from) - } - return 'to.css' - } - - generateMap () { - this.generateString() - if (this.isSourcesContent()) this.setSourcesContent() - if (this.previous().length > 0) this.applyPrevMaps() - if (this.isAnnotation()) this.addAnnotation() - - if (this.isInline()) { - return [this.css] - } - return [this.css, this.map] - } - - relative (file) { - if (file.indexOf('<') === 0) return file - if (/^\w+:\/\//.test(file)) return file - - let from = this.opts.to ? path.dirname(this.opts.to) : '.' - - if (typeof this.mapOpts.annotation === 'string') { - from = path.dirname(path.resolve(from, this.mapOpts.annotation)) - } - - file = path.relative(from, file) - if (path.sep === '\\') { - return file.replace(/\\/g, '/') - } - return file - } - - sourcePath (node) { - if (this.mapOpts.from) { - return this.mapOpts.from - } - return this.relative(node.source.input.from) - } - - generateString () { - this.css = '' - this.map = new mozilla.SourceMapGenerator({ file: this.outputFile() }) - - let line = 1 - let column = 1 - - let lines, last - this.stringify(this.root, (str, node, type) => { - this.css += str - - if (node && type !== 'end') { - if (node.source && node.source.start) { - this.map.addMapping({ - source: this.sourcePath(node), - generated: { line, column: column - 1 }, - original: { - line: node.source.start.line, - column: node.source.start.column - 1 - } - }) - } else { - this.map.addMapping({ - source: '', - original: { line: 1, column: 0 }, - generated: { line, column: column - 1 } - }) - } - } - - 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: { } } - if (node.type !== 'decl' || node !== p.last || p.raws.semicolon) { - if (node.source && node.source.end) { - this.map.addMapping({ - source: this.sourcePath(node), - generated: { line, column: column - 2 }, - original: { - line: node.source.end.line, - column: node.source.end.column - 1 - } - }) - } else { - this.map.addMapping({ - source: '', - original: { line: 1, column: 0 }, - generated: { line, column: column - 1 } - }) - } - } - } - }) - } - - generate () { - this.clearAnnotation() - - if (this.isMap()) { - return this.generateMap() - } - - let result = '' - this.stringify(this.root, i => { - result += i - }) - return [result] - } -} - -export default MapGenerator diff --git a/lib/map-generator.js b/lib/map-generator.js new file mode 100644 index 000000000..523b46397 --- /dev/null +++ b/lib/map-generator.js @@ -0,0 +1,359 @@ +'use strict' + +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { dirname, relative, resolve, sep } = require('path') +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.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 = map.sourcesContent.map(() => 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.indexOf('# sourceMappingURL=') === 0) { + 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) + } else { + this.map = new SourceMapGenerator({ file: this.outputFile() }) + 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() }) + + let line = 1 + let column = 1 + + let noSource = '' + let mapping = { + generated: { column: 0, line: 0 }, + original: { column: 0, line: 0 }, + source: '' + } + + let lines, last + 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.css, 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 diff --git a/lib/no-work-result.d.ts b/lib/no-work-result.d.ts new file mode 100644 index 000000000..803907654 --- /dev/null +++ b/lib/no-work-result.d.ts @@ -0,0 +1,46 @@ +import 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 diff --git a/lib/no-work-result.js b/lib/no-work-result.js new file mode 100644 index 000000000..a0609f797 --- /dev/null +++ b/lib/no-work-result.js @@ -0,0 +1,135 @@ +'use strict' + +let MapGenerator = require('./map-generator') +let stringify = require('./stringify') +let warnOnce = require('./warn-once') +let parse = require('./parse') +const Result = require('./result') + +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 + } + } + } + + 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 diff --git a/lib/node.d.ts b/lib/node.d.ts new file mode 100644 index 000000000..71b30159a --- /dev/null +++ b/lib/node.d.ts @@ -0,0 +1,536 @@ +import AtRule = require('./at-rule.js') + +import { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container 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) + + /** + * 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 | Node[] | string): 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 | Node[] | string): 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): Node + + /** + * 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): Node + + /** + * 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): Node + + /** + * 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: ( + | Node.ChildNode + | Node.ChildNode[] + | Node.ChildProps + | Node.ChildProps[] + )[] + ): 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 diff --git a/lib/node.es6 b/lib/node.es6 deleted file mode 100644 index 63c4ae5ae..000000000 --- a/lib/node.es6 +++ /dev/null @@ -1,525 +0,0 @@ -import CssSyntaxError from './css-syntax-error' -import Stringifier from './stringifier' -import stringify from './stringify' - -function cloneNode (obj, parent) { - let cloned = new obj.constructor() - - for (let i in obj) { - if (!obj.hasOwnProperty(i)) 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 (value instanceof Array) { - cloned[i] = value.map(j => cloneNode(j, cloned)) - } else { - if (type === 'object' && value !== null) value = cloneNode(value) - cloned[i] = value - } - } - - return cloned -} - -/** - * All node classes inherit the following common methods. - * - * @abstract - */ -class Node { - /** - * @param {object} [defaults] Value for node properties. - */ - constructor (defaults = { }) { - this.raws = { } - if (process.env.NODE_ENV !== 'production') { - if (typeof defaults !== 'object' && typeof defaults !== 'undefined') { - throw new Error( - 'PostCSS nodes constructor accepts object, not ' + - JSON.stringify(defaults) - ) - } - } - for (let name in defaults) { - this[name] = defaults[name] - } - } - - /** - * Returns a `CssSyntaxError` instance containing the original position - * of the node in the source, showing line and column numbers and also - * a small excerpt to facilitate debugging. - * - * If present, an input source map will be used to get the original position - * of the source, even from a previous compilation step - * (e.g., from Sass compilation). - * - * This method produces very useful error messages. - * - * @param {string} message Error description. - * @param {object} [opts] Options. - * @param {string} opts.plugin Plugin name that created this error. - * PostCSS will set it automatically. - * @param {string} opts.word A word inside a node’s string that should - * be highlighted as the source of the error. - * @param {number} opts.index An index inside a node’s string that should - * be highlighted as the source of the error. - * - * @return {CssSyntaxError} Error object to throw it. - * - * @example - * 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 - * } - */ - error (message, opts = { }) { - if (this.source) { - let pos = this.positionBy(opts) - return this.source.input.error(message, pos.line, pos.column, opts) - } - return new CssSyntaxError(message) - } - - /** - * This method is provided as a convenience wrapper for {@link Result#warn}. - * - * @param {Result} result The {@link Result} instance - * that will receive the warning. - * @param {string} text Warning message. - * @param {object} [opts] Options - * @param {string} opts.plugin Plugin name that created this warning. - * PostCSS will set it automatically. - * @param {string} opts.word A word inside a node’s string that should - * be highlighted as the source of the warning. - * @param {number} opts.index An index inside a node’s string that should - * be highlighted as the source of the warning. - * - * @return {Warning} Created warning object. - * - * @example - * const plugin = postcss.plugin('postcss-deprecated', () => { - * return (root, result) => { - * root.walkDecls('bad', decl => { - * decl.warn(result, 'Deprecated property bad') - * }) - * } - * }) - */ - warn (result, text, opts) { - let data = { node: this } - for (let i in opts) data[i] = opts[i] - return result.warn(text, data) - } - - /** - * Removes the node from its parent and cleans the parent properties - * from the node and its children. - * - * @example - * if (decl.prop.match(/^-webkit-/)) { - * decl.remove() - * } - * - * @return {Node} Node to make calls chain. - */ - remove () { - if (this.parent) { - this.parent.removeChild(this) - } - this.parent = undefined - return this - } - - /** - * Returns a CSS string representing the node. - * - * @param {stringifier|syntax} [stringifier] A syntax to use - * in string generation. - * - * @return {string} CSS string of this node. - * - * @example - * postcss.rule({ selector: 'a' }).toString() //=> "a {}" - */ - toString (stringifier = stringify) { - if (stringifier.stringify) stringifier = stringifier.stringify - let result = '' - stringifier(this, i => { - result += i - }) - return result - } - - /** - * Returns an exact clone of the node. - * - * The resulting cloned node and its (cloned) children will retain - * code style properties. - * - * @param {object} [overrides] New properties to override in the clone. - * - * @example - * decl.raws.before //=> "\n " - * const cloned = decl.clone({ prop: '-moz-' + decl.prop }) - * cloned.raws.before //=> "\n " - * cloned.toString() //=> -moz-transform: scale(0) - * - * @return {Node} Clone of the node. - */ - clone (overrides = { }) { - let cloned = cloneNode(this) - for (let name in overrides) { - cloned[name] = overrides[name] - } - return cloned - } - - /** - * Shortcut to clone the node and insert the resulting cloned node - * before the current node. - * - * @param {object} [overrides] Mew properties to override in the clone. - * - * @example - * decl.cloneBefore({ prop: '-moz-' + decl.prop }) - * - * @return {Node} New node - */ - cloneBefore (overrides = { }) { - let cloned = this.clone(overrides) - this.parent.insertBefore(this, cloned) - return cloned - } - - /** - * Shortcut to clone the node and insert the resulting cloned node - * after the current node. - * - * @param {object} [overrides] New properties to override in the clone. - * - * @return {Node} New node. - */ - cloneAfter (overrides = { }) { - let cloned = this.clone(overrides) - this.parent.insertAfter(this, cloned) - return cloned - } - - /** - * Inserts node(s) before the current node and removes the current node. - * - * @param {...Node} nodes Mode(s) to replace current one. - * - * @example - * if (atrule.name === 'mixin') { - * atrule.replaceWith(mixinRules[atrule.params]) - * } - * - * @return {Node} Current node to methods chain. - */ - replaceWith (...nodes) { - if (this.parent) { - for (let node of nodes) { - this.parent.insertBefore(this, node) - } - - this.remove() - } - - return this - } - - /** - * Returns the next child of the node’s parent. - * Returns `undefined` if the current node is the last child. - * - * @return {Node|undefined} Next node. - * - * @example - * if (comment.text === 'delete next') { - * const next = comment.next() - * if (next) { - * next.remove() - * } - * } - */ - next () { - if (!this.parent) return undefined - let index = this.parent.index(this) - return this.parent.nodes[index + 1] - } - - /** - * Returns the previous child of the node’s parent. - * Returns `undefined` if the current node is the first child. - * - * @return {Node|undefined} Previous node. - * - * @example - * const annotation = decl.prev() - * if (annotation.type === 'comment') { - * readAnnotation(annotation.text) - * } - */ - prev () { - if (!this.parent) return undefined - let index = this.parent.index(this) - return this.parent.nodes[index - 1] - } - - /** - * Insert new node before current node to current node’s parent. - * - * Just alias for `node.parent.insertBefore(node, add)`. - * - * @param {Node|object|string|Node[]} add New node. - * - * @return {Node} This node for methods chain. - * - * @example - * decl.before('content: ""') - */ - before (add) { - this.parent.insertBefore(this, add) - return this - } - - /** - * Insert new node after current node to current node’s parent. - * - * Just alias for `node.parent.insertAfter(node, add)`. - * - * @param {Node|object|string|Node[]} add New node. - * - * @return {Node} This node for methods chain. - * - * @example - * decl.after('color: black') - */ - after (add) { - this.parent.insertAfter(this, add) - return this - } - - toJSON () { - let fixed = { } - - for (let name in this) { - if (!this.hasOwnProperty(name)) continue - if (name === 'parent') continue - let value = this[name] - - if (value instanceof Array) { - fixed[name] = value.map(i => { - if (typeof i === 'object' && i.toJSON) { - return i.toJSON() - } else { - return i - } - }) - } else if (typeof value === 'object' && value.toJSON) { - fixed[name] = value.toJSON() - } else { - fixed[name] = value - } - } - - return fixed - } - - /** - * Returns a {@link Node#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. - * - * @param {string} prop Name of code style property. - * @param {string} [defaultType] Name of default value, it can be missed - * if the value is the same as prop. - * - * @example - * 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') //=> ' ' - * - * @return {string} Code style value. - */ - raw (prop, defaultType) { - let str = new Stringifier() - return str.raw(this, prop, defaultType) - } - - /** - * Finds the Root instance of the node’s tree. - * - * @example - * root.nodes[0].nodes[0].root() === root - * - * @return {Root} Root parent. - */ - root () { - let result = this - while (result.parent) result = result.parent - return result - } - - /** - * Clear the code style properties for the node and its children. - * - * @param {boolean} [keepBetween] Keep the raws.between symbols. - * - * @return {undefined} - * - * @example - * node.raws.before //=> ' ' - * node.cleanRaws() - * node.raws.before //=> undefined - */ - cleanRaws (keepBetween) { - delete this.raws.before - delete this.raws.after - if (!keepBetween) delete this.raws.between - } - - positionInside (index) { - let string = this.toString() - let column = this.source.start.column - let line = this.source.start.line - - for (let i = 0; i < index; i++) { - if (string[i] === '\n') { - column = 1 - line += 1 - } else { - column += 1 - } - } - - return { line, column } - } - - positionBy (opts) { - let pos = this.source.start - if (opts.index) { - pos = this.positionInside(opts.index) - } else if (opts.word) { - let index = this.toString().indexOf(opts.word) - if (index !== -1) pos = this.positionInside(index) - } - return pos - } - - /** - * @memberof Node# - * @member {string} type String representing the node’s type. - * Possible values are `root`, `atrule`, `rule`, - * `decl`, or `comment`. - * - * @example - * postcss.decl({ prop: 'color', value: 'black' }).type //=> 'decl' - */ - - /** - * @memberof Node# - * @member {Container} parent The node’s parent node. - * - * @example - * root.nodes[0].parent === root - */ - - /** - * @memberof Node# - * @member {source} source The input source of the node. - * - * The property is used in source map generation. - * - * If you create a node manually (e.g., with `postcss.decl()`), - * that node will not have a `source` property and will be absent - * from the source map. For this reason, the plugin developer should - * consider cloning nodes to create new ones (in which case the new node’s - * source will reference the original, cloned node) or setting - * the `source` property manually. - * - * ```js - * // Bad - * const prefixed = postcss.decl({ - * prop: '-moz-' + decl.prop, - * value: decl.value - * }) - * - * // Good - * 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) - * } - * ``` - * - * @example - * decl.source.input.from //=> '/home/ai/a.sass' - * decl.source.start //=> { line: 10, column: 2 } - * decl.source.end //=> { line: 10, column: 12 } - */ - - /** - * @memberof Node# - * @member {object} raws Information to generate byte-to-byte equal - * node string as it was in the origin input. - * - * Every parser saves its own properties, - * but the default CSS parser uses: - * - * * `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 cleans selectors, declaration values and at-rule parameters - * from comments and extra spaces, but it stores origin content in raws - * properties. As such, if you don’t change a declaration’s value, - * PostCSS will use the raw value with comments. - * - * @example - * const root = postcss.parse('a {\n color:black\n}') - * root.first.first.raws //=> { before: '\n ', between: ':' } - */ -} - -export default Node - -/** - * @typedef {object} position - * @property {number} line Source line in file. - * @property {number} column Source column in file. - */ - -/** - * @typedef {object} source - * @property {Input} input {@link Input} with input file - * @property {position} start The starting position of the node’s source. - * @property {position} end The ending position of the node’s source. - */ diff --git a/lib/node.js b/lib/node.js new file mode 100644 index 000000000..d79dd56e5 --- /dev/null +++ b/lib/node.js @@ -0,0 +1,381 @@ +'use strict' + +let { isClean, my } = require('./symbols') +let CssSyntaxError = require('./css-syntax-error') +let Stringifier = require('./stringifier') +let stringify = require('./stringify') + +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 +} + +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 + } + } + } + + 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, stringRepresentation) { + let pos = this.source.start + if (opts.index) { + pos = this.positionInside(opts.index, stringRepresentation) + } else if (opts.word) { + stringRepresentation = this.toString() + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) pos = this.positionInside(index, stringRepresentation) + } + return pos + } + + positionInside(index, stringRepresentation) { + let string = stringRepresentation || this.toString() + let column = this.source.start.column + let line = this.source.start.line + + for (let i = 0; i < index; i++) { + if (string[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.toString() + let index = stringRepresentation.indexOf(opts.word) + if (index !== -1) { + start = this.positionInside(index, stringRepresentation) + end = this.positionInside(index + opts.word.length, stringRepresentation) + } + } 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 (opts.endIndex) { + 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 diff --git a/lib/parse.d.ts b/lib/parse.d.ts new file mode 100644 index 000000000..4c943a4d6 --- /dev/null +++ b/lib/parse.d.ts @@ -0,0 +1,9 @@ +import { Parser } from './postcss.js' + +interface Parse extends Parser { + default: Parse +} + +declare const parse: Parse + +export = parse diff --git a/lib/parse.es6 b/lib/parse.es6 deleted file mode 100644 index 1a32fae5d..000000000 --- a/lib/parse.es6 +++ /dev/null @@ -1,33 +0,0 @@ -import Parser from './parser' -import Input from './input' - -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 -} - -export default parse diff --git a/lib/parse.js b/lib/parse.js new file mode 100644 index 000000000..971431f23 --- /dev/null +++ b/lib/parse.js @@ -0,0 +1,42 @@ +'use strict' + +let Container = require('./container') +let Parser = require('./parser') +let Input = require('./input') + +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) diff --git a/lib/parser.es6 b/lib/parser.js similarity index 59% rename from lib/parser.es6 rename to lib/parser.js index 8a75deb26..e1e2e19e2 100644 --- a/lib/parser.es6 +++ b/lib/parser.js @@ -1,179 +1,218 @@ -import Declaration from './declaration' -import tokenizer from './tokenize' -import Comment from './comment' -import AtRule from './at-rule' -import Root from './root' -import Rule from './rule' - -export default class Parser { - constructor (input) { +'use strict' + +let Declaration = require('./declaration') +let tokenizer = require('./tokenize') +let Comment = require('./comment') +let AtRule = require('./at-rule') +let Root = require('./root') +let Rule = require('./rule') + +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.customProperty = false this.createTokenizer() - this.root.source = { input, start: { line: 1, column: 1 } } + this.root.source = { input, start: { column: 1, line: 1, offset: 0 } } } - createTokenizer () { - this.tokenizer = tokenizer(this.input) - } + 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 = [] - parse () { - let token while (!this.tokenizer.endOfFile()) { token = this.tokenizer.nextToken() + type = token[0] - switch (token[0]) { - case 'space': - this.spaces += token[1] - break - - case ';': - this.freeSemicolon(token) - break - - case '}': - this.end(token) - break + if (type === '(' || type === '[') { + brackets.push(type === '(' ? ')' : ']') + } else if (type === '{' && brackets.length > 0) { + brackets.push('}') + } else if (type === brackets[brackets.length - 1]) { + brackets.pop() + } - case 'comment': - this.comment(token) + if (brackets.length === 0) { + if (type === ';') { + node.source.end = this.getPosition(token[2]) + node.source.end.offset++ + this.semicolon = true break - - case 'at-word': - this.atrule(token) + } else if (type === '{') { + open = true break - - case '{': - this.emptyRule(token) + } 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) + } - default: - this.other(token) - break + if (this.tokenizer.endOfFile()) { + last = true + break } } - this.endFile() - } - comment (token) { - let node = new Comment() - this.init(node, token[2], token[3]) - node.source.end = { line: token[4], column: token[5] } - - let text = token[1].slice(2, -2) - if (/^\s*$/.test(text)) { - node.text = '' - node.raws.left = text - node.raws.right = '' + 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 { - let match = text.match(/^(\s*)([^]*[^\s])(\s*)$/) - node.text = match[2] - node.raws.left = match[1] - node.raws.right = match[3] + node.raws.afterName = '' + node.params = '' } - } - emptyRule (token) { - let node = new Rule() - this.init(node, token[2], token[3]) - node.selector = '' - node.raws.between = '' - this.current = node + if (open) { + node.nodes = [] + this.current = node + } } - other (start) { - let end = false - let type = null - let colon = false - let bracket = null - let brackets = [] + checkMissedSemicolon(tokens) { + let colon = this.colon(tokens) + if (colon === false) return - let tokens = [] - let token = start - while (token) { + 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 token, type, prev + for (let [i, element] of tokens.entries()) { + token = element type = token[0] - tokens.push(token) - if (type === '(' || type === '[') { - if (!bracket) bracket = token - brackets.push(type === '(' ? ')' : ']') - } else if (brackets.length === 0) { - if (type === ';') { - if (colon) { - this.decl(tokens) - 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 + 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 } - } else if (type === brackets[brackets.length - 1]) { - brackets.pop() - if (brackets.length === 0) bracket = null } - token = this.tokenizer.nextToken() + prev = token } + return false + } - if (this.tokenizer.endOfFile()) end = true - if (brackets.length > 0) this.unclosedBracket(bracket) + comment(token) { + let node = new Comment() + this.init(node, token[2]) + node.source.end = this.getPosition(token[3] || token[2]) + node.source.end.offset++ - if (end && colon) { - while (tokens.length) { - token = tokens[tokens.length - 1][0] - if (token !== 'space' && token !== 'comment') break - this.tokenizer.back(tokens.pop()) - } - this.decl(tokens) + let text = token[1].slice(2, -2) + if (/^\s*$/.test(text)) { + node.text = '' + node.raws.left = text + node.raws.right = '' } else { - this.unknownWord(tokens) + let match = text.match(/^(\s*)([^]*\S)(\s*)$/) + node.text = match[2] + node.raws.left = match[1] + node.raws.right = match[3] } } - rule (tokens) { - tokens.pop() - - let node = new Rule() - this.init(node, tokens[0][2], tokens[0][3]) - - node.raws.between = this.spacesAndCommentsFromEnd(tokens) - this.raw(node, 'selector', tokens) - this.current = node + createTokenizer() { + this.tokenizer = tokenizer(this.input) } - decl (tokens) { + decl(tokens, customProperty) { let node = new Declaration() - this.init(node) + this.init(node, tokens[0][2]) let last = tokens[tokens.length - 1] if (last[0] === ';') { this.semicolon = true tokens.pop() } - if (last[4]) { - node.source.end = { line: last[4], column: last[5] } - } else { - node.source.end = { line: last[2], column: last[3] } - } + + 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 = { line: tokens[0][2], column: tokens[0][3] } + node.source.start = this.getPosition(tokens[0][2]) node.prop = '' while (tokens.length) { @@ -205,10 +244,18 @@ export default class Parser { node.raws.before += node.prop[0] node.prop = node.prop.slice(1) } - node.raws.between += this.spacesAndCommentsFromStart(tokens) + + 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--) { + for (let i = tokens.length - 1; i >= 0; i--) { token = tokens[i] if (token[1].toLowerCase() === '!important') { node.important = true @@ -238,80 +285,36 @@ export default class Parser { } } - this.raw(node, 'value', tokens) - - if (node.value.indexOf(':') !== -1) this.checkMissedSemicolon(tokens) - } + let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment') - atrule (token) { - let node = new AtRule() - node.name = token[1].slice(1) - if (node.name === '') { - this.unnamedAtrule(node, token) + if (hasWord) { + node.raws.between += firstSpaces.map(i => i[1]).join('') + firstSpaces = [] } - this.init(node, token[2], token[3]) - - let prev - let shift - let last = false - let open = false - let params = [] - - while (!this.tokenizer.endOfFile()) { - token = this.tokenizer.nextToken() + this.raw(node, 'value', firstSpaces.concat(tokens), customProperty) - if (token[0] === ';') { - node.source.end = { line: token[2], column: token[3] } - this.semicolon = true - break - } else if (token[0] === '{') { - open = true - break - } else if (token[0] === '}') { - if (params.length > 0) { - shift = params.length - 1 - prev = params[shift] - while (prev && prev[0] === 'space') { - prev = params[--shift] - } - if (prev) { - node.source.end = { line: prev[4], column: prev[5] } - } - } - this.end(token) - break - } else { - params.push(token) - } - - if (this.tokenizer.endOfFile()) { - last = true - break - } + if (node.value.includes(':') && !customProperty) { + this.checkMissedSemicolon(tokens) } + } - 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 = { line: token[4], column: token[5] } - this.spaces = node.raws.between - node.raws.between = '' - } - } else { - node.raws.afterName = '' - node.params = '' - } + doubleColon(token) { + throw this.input.error( + 'Double colon', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) + } - if (open) { - node.nodes = [] - this.current = node - } + emptyRule(token) { + let node = new Rule() + this.init(node, token[2]) + node.selector = '' + node.raws.between = '' + this.current = node } - end (token) { + end(token) { if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon } @@ -321,22 +324,24 @@ export default class Parser { this.spaces = '' if (this.current.parent) { - this.current.source.end = { line: token[2], column: token[3] } + this.current.source.end = this.getPosition(token[2]) + this.current.source.end.offset++ this.current = this.current.parent } else { this.unexpectedClose(token) } } - endFile () { + 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) { + freeSemicolon(token) { this.spaces += token[1] if (this.current.nodes) { let prev = this.current.nodes[this.current.nodes.length - 1] @@ -349,59 +354,178 @@ export default class Parser { // Helpers - init (node, line, column) { - this.current.push(node) + getPosition(offset) { + let pos = this.input.fromOffset(offset) + return { + column: pos.col, + line: pos.line, + offset + } + } - node.source = { start: { line, column }, input: this.input } + 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 } - raw (node, prop, tokens) { + 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 - let pattern = /^([.|#])?([\w])+/i for (let i = 0; i < length; i += 1) { token = tokens[i] type = token[0] - - if (type === 'comment' && node.type === 'rule') { - prev = tokens[i - 1] - next = tokens[i + 1] - - if ( - prev[0] !== 'space' && - next[0] !== 'space' && - pattern.test(prev[1]) && - pattern.test(next[1]) - ) { - value += token[1] + 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 } - - continue - } - - if (type === 'comment' || (type === 'space' && i === length - 1)) { - clean = false } else { value += token[1] } } if (!clean) { let raw = tokens.reduce((all, i) => all + i[1], '') - node.raws[prop] = { value, raw } + node.raws[prop] = { raw, value } } node[prop] = value } - spacesAndCommentsFromEnd (tokens) { + 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) { @@ -412,7 +536,9 @@ export default class Parser { return spaces } - spacesAndCommentsFromStart (tokens) { + // Errors + + spacesAndCommentsFromStart(tokens) { let next let spaces = '' while (tokens.length) { @@ -423,7 +549,7 @@ export default class Parser { return spaces } - spacesFromEnd (tokens) { + spacesFromEnd(tokens) { let lastTokenType let spaces = '' while (tokens.length) { @@ -434,7 +560,7 @@ export default class Parser { return spaces } - stringFrom (tokens, from) { + stringFrom(tokens, from) { let result = '' for (let i = from; i < tokens.length; i++) { result += tokens[i][1] @@ -443,78 +569,42 @@ export default class Parser { return result } - colon (tokens) { - let brackets = 0 - let token, type, prev - for (let i = 0; i < tokens.length; i++) { - token = tokens[i] - 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 - } - - // Errors - - unclosedBracket (bracket) { - throw this.input.error('Unclosed bracket', bracket[2], bracket[3]) - } - - unknownWord (tokens) { - throw this.input.error('Unknown word', tokens[0][2], tokens[0][3]) - } - - unexpectedClose (token) { - throw this.input.error('Unexpected }', token[2], token[3]) - } - - unclosedBlock () { + unclosedBlock() { let pos = this.current.source.start throw this.input.error('Unclosed block', pos.line, pos.column) } - doubleColon (token) { - throw this.input.error('Double colon', token[2], token[3]) + unclosedBracket(bracket) { + throw this.input.error( + 'Unclosed bracket', + { offset: bracket[2] }, + { offset: bracket[2] + 1 } + ) } - unnamedAtrule (node, token) { - throw this.input.error('At-rule without name', token[2], token[3]) + unexpectedClose(token) { + throw this.input.error( + 'Unexpected }', + { offset: token[2] }, + { offset: token[2] + 1 } + ) } - precheckMissedSemicolon (/* tokens */) { - // Hook for Safe Parser + unknownWord(tokens) { + throw this.input.error( + 'Unknown word', + { offset: tokens[0][2] }, + { offset: tokens[0][2] + tokens[0][1].length } + ) } - 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 - } - } - throw this.input.error('Missed semicolon', token[2], token[3]) + unnamedAtrule(node, token) { + throw this.input.error( + 'At-rule without name', + { offset: token[2] }, + { offset: token[2] + token[1].length } + ) } } + +module.exports = Parser diff --git a/lib/postcss.d.mts b/lib/postcss.d.mts new file mode 100644 index 000000000..a8ca8c7a1 --- /dev/null +++ b/lib/postcss.d.mts @@ -0,0 +1,72 @@ +export { + // 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' diff --git a/lib/postcss.d.ts b/lib/postcss.d.ts index 7513b4da0..70d758959 100644 --- a/lib/postcss.d.ts +++ b/lib/postcss.d.ts @@ -1,1283 +1,441 @@ -import * as mozilla from 'source-map'; +import { RawSourceMap, SourceMapGenerator } from 'source-map-js' -/** - * @param plugins Can also be included with the Processor#use method. - * @returns A processor that will apply plugins as CSS processors. - */ -declare function postcss(plugins?: postcss.AcceptedPlugin[]): postcss.Processor; -declare function postcss(...plugins: postcss.AcceptedPlugin[]): postcss.Processor; -declare namespace postcss { - type AcceptedPlugin = Plugin | Transformer | { - postcss: TransformCallback | Processor; - } | Processor; +import AtRule, { AtRuleProps } from './at-rule.js' +import Comment, { CommentProps } from './comment.js' +import Container, { ContainerProps } 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 { /** - * Creates a PostCSS plugin with a standard API. - * @param name Plugin name. Same as in name property in package.json. It will - * be saved in plugin.postcssPlugin property. - * @param initializer Will receive plugin options and should return functions - * to modify nodes in input CSS. + * Will be called on all`AtRule` nodes. + * + * Will be called again on node or children changes. */ - function plugin(name: string, initializer: PluginInitializer): Plugin; - interface Plugin extends Transformer { - (opts?: T): Transformer; - postcss: Transformer; - process: (css: string | { - toString(): string; - } | Result, processOpts?: ProcessOptions, pluginOpts?: T) => LazyResult; - } - interface Transformer extends TransformCallback { - postcssPlugin?: string; - postcssVersion?: string; - } - interface TransformCallback { - /** - * @returns A Promise that resolves when all work is complete. May return - * synchronously, but that style of plugin is only meant for debugging and - * development. In either case, the resolved or returned value is not used - - * the "result" is the output. - */ - (root: Root, result: Result): Promise | any; - } - interface PluginInitializer { - (pluginOptions?: T): Transformer; - } + AtRule?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + /** - * Contains helpers for working with vendor prefixes. + * Will be called on all `AtRule` nodes, when all children will be processed. + * + * Will be called again on node or children changes. */ - export namespace vendor { - /** - * @returns The vendor prefix extracted from the input string. - */ - function prefix(prop: string): string; - /** - * @returns The input string stripped of its vendor prefix. - */ - function unprefixed(prop: string): string; - } - type ParserInput = string | { toString(): string }; - interface Parser { - (css: ParserInput, opts?: Pick): Root; - } - interface Builder { - (part: string, node?: Node, type?: 'start' | 'end'): void; - } - interface Stringifier { - (node: Node, builder: Builder): void; - } + AtRuleExit?: { [name: string]: AtRuleProcessor } | AtRuleProcessor + /** - * Default function to convert a node tree into a CSS string. + * Will be called on all `Comment` nodes. + * + * Will be called again on node or children changes. */ - const stringify: Stringifier; + Comment?: CommentProcessor + /** - * Parses source CSS. - * @param css The CSS to parse. - * @param options - * @returns {} A new Root node, which contains the source CSS nodes. + * Will be called on all `Comment` nodes after listeners + * for `Comment` event. + * + * Will be called again on node or children changes. */ - const parse: Parser; + CommentExit?: CommentProcessor + /** - * Contains helpers for safely splitting lists of CSS values, preserving - * parentheses and quotes. + * Will be called on all `Declaration` nodes after listeners + * for `Declaration` event. + * + * Will be called again on node or children changes. */ - export namespace list { - /** - * Safely splits space-separated values (such as those for background, - * border-radius and other shorthand properties). - */ - function space(str: string): string[]; - /** - * Safely splits comma-separated values (such as those for transition-* and - * background properties). - */ - function comma(str: string): string[]; - } + Declaration?: { [prop: string]: DeclarationProcessor } | DeclarationProcessor + /** - * Creates a new Comment node. - * @param defaults Properties for the new Comment node. - * @returns The new node. + * Will be called on all `Declaration` nodes. + * + * Will be called again on node or children changes. */ - function comment(defaults?: CommentNewProps): Comment; + DeclarationExit?: + | { [prop: string]: DeclarationProcessor } + | DeclarationProcessor + /** - * Creates a new AtRule node. - * @param defaults Properties for the new AtRule node. - * @returns The new node. + * Will be called on `Document` node. + * + * Will be called again on children changes. */ - function atRule(defaults?: AtRuleNewProps): AtRule; + Document?: DocumentProcessor + /** - * Creates a new Declaration node. - * @param defaults Properties for the new Declaration node. - * @returns The new node. + * Will be called on `Document` node, when all children will be processed. + * + * Will be called again on children changes. */ - function decl(defaults?: DeclarationNewProps): Declaration; + DocumentExit?: DocumentProcessor + /** - * Creates a new Rule node. - * @param defaults Properties for the new Rule node. - * @returns The new node. + * Will be called on `Root` node once. */ - function rule(defaults?: RuleNewProps): Rule; + Once?: RootProcessor + /** - * Creates a new Root node. - * @param defaults Properties for the new Root node. - * @returns The new node. + * Will be called on `Root` node once, when all children will be processed. */ - function root(defaults?: object): Root; - interface SourceMapOptions { - /** - * 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 compilation). - * 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?: any; - /** - * 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; - /** - * 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?: string | boolean; - /** - * Override "from" in map's sources. - */ - from?: string; - } + OnceExit?: RootProcessor + /** - * A Processor instance contains plugins to process CSS. Create one - * Processor instance, initialize its plugins, and then use that instance - * on numerous CSS files. + * Will be called on `Root` node. + * + * Will be called again on children changes. */ - interface Processor { - /** - * Adds a plugin to be used as a CSS processor. Plugins can also be - * added by passing them as arguments when creating a postcss instance. - */ - use(plugin: AcceptedPlugin): Processor; - /** - * Parses source CSS. Because some plugins can be asynchronous it doesn't - * make any transformations. Transformations will be applied in LazyResult's - * methods. - * @param css Input CSS or any object with toString() method, like a file - * stream. If a Result instance is passed the processor will take the - * existing Root parser from it. - */ - process(css: ParserInput | Result | LazyResult | Root, options?: ProcessOptions): LazyResult; - /** - * Contains plugins added to this processor. - */ - plugins: Plugin[]; - /** - * Contains the current version of PostCSS (e.g., "4.0.5"). - */ - version: string; - } - 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; - /** - * The path where you'll put the output CSS file. You should always set "to" - * to generate correct source maps. - */ - to?: string; - /** - * Function to generate AST by string. - */ - parser?: Parser; - /** - * Class to generate string by AST. - */ - stringifier?: Stringifier; - /** - * Object with parse and stringify. - */ - syntax?: Syntax; - /** - * Source map options - */ - map?: SourceMapOptions | boolean; - } - interface Syntax { - /** - * Function to generate AST by string. - */ - parse?: Parser; - /** - * Class to generate string by AST. - */ - stringify?: Stringifier; - } + Root?: RootProcessor + /** - * A promise proxy for the result of PostCSS transformations. + * Will be called on `Root` node, when all children will be processed. + * + * Will be called again on children changes. */ - interface LazyResult { - /** - * Processes input CSS through synchronous and asynchronous plugins. - * @param onRejected Called if any plugin throws an error. - */ - then: Promise["then"]; - /** - * Processes input CSS through synchronous and asynchronous plugins. - * @param onRejected Called if any plugin throws an error. - */ - catch: Promise["catch"]; - /** - * Alias for css property. - */ - toString(): string; - /** - * Processes input CSS through synchronous plugins and converts Root to - * CSS string. This property will only work with synchronous plugins. If - * the processor contains any asynchronous plugins it will throw an error. - * In this case, you should use LazyResult#then() instead. - * @returns Result#css. - */ - css: string; - /** - * Alias for css property to use when syntaxes generate non-CSS output. - */ - content: string; - /** - * Processes input CSS through synchronous plugins. This property will - * work only with synchronous plugins. If processor contains any - * asynchronous plugins it will throw an error. You should use - * LazyResult#then() instead. - */ - map: ResultMap; - /** - * Processes input CSS through synchronous plugins. This property will work - * only with synchronous plugins. If processor contains any asynchronous - * plugins it will throw an error. You should use LazyResult#then() instead. - */ - root: Root; - /** - * Processes input CSS through synchronous plugins and calls Result#warnings(). - * This property will only work with synchronous plugins. If the processor - * contains any asynchronous plugins it will throw an error. In this case, - * you should use LazyResult#then() instead. - */ - warnings(): Warning[]; - /** - * Processes input CSS through synchronous plugins. This property will work - * only with synchronous plugins. If processor contains any asynchronous - * plugins it will throw an error. You should use LazyResult#then() instead. - */ - messages: ResultMessage[]; - /** - * @returns A processor used for CSS transformations. - */ - processor: Processor; - /** - * @returns Options from the Processor#process(css, opts) call that produced - * this Result instance. - */ - opts: ResultOptions; - } + RootExit?: RootProcessor + /** - * Provides the result of the PostCSS transformations. + * Will be called on all `Rule` nodes. + * + * Will be called again on node or children changes. */ - interface Result { - /** - * Alias for css property. - */ - toString(): string; - /** - * Creates an instance of Warning and adds it to messages. - * @param message Used in the text property of the message object. - * @param options Properties for Message object. - */ - warn(message: string, options?: WarningOptions): void; - /** - * @returns Warnings from plugins, filtered from messages. - */ - warnings(): Warning[]; - /** - * A CSS string representing this Result's Root instance. - */ - css: string; - /** - * Alias for css property to use with syntaxes that generate non-CSS output. - */ - content: string; - /** - * An instance of the SourceMapGenerator class from the source-map library, - * representing changes to the Result's Root instance. - * This property will have a value only if the user does not want an inline - * source map. By default, PostCSS generates inline source maps, written - * directly into the processed CSS. The map property will be empty by default. - * An external source map will be generated — and assigned to map — only if - * the user has set the map.inline option to false, or if PostCSS was passed - * an external input source map. - */ - map: ResultMap; - /** - * Contains the Root node after all transformations. - */ - root?: Root; - /** - * Contains messages from plugins (e.g., warnings or custom messages). - * Add a warning using Result#warn() and get all warnings - * using the Result#warnings() method. - */ - messages: ResultMessage[]; - /** - * The Processor instance used for this transformation. - */ - processor?: Processor; - /** - * Options from the Processor#process(css, opts) or Root#toResult(opts) call - * that produced this Result instance. - */ - opts?: ResultOptions; + 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, + Node, + NodeErrorOptions, + NodeProps, + Position, + Processor, + Result, + Root, + RootProps, + Rule, + RuleProps, + Source, + Warning, + WarningOptions } - interface ResultOptions extends ProcessOptions { - /** - * The CSS node that was the source of the warning. - */ - node?: postcss.Node; - /** - * Name of plugin that created this warning. Result#warn() will fill it - * automatically with plugin.postcssPlugin value. - */ - plugin?: string; + + export type SourceMap = SourceMapGenerator & { + toJSON(): RawSourceMap } - interface ResultMap { - /** - * Add a single mapping from original source line and column to the generated - * source's line and column for this source map being created. The mapping - * object should have the following properties: - * @param mapping - * @returns {} - */ - addMapping(mapping: mozilla.Mapping): void; - /** - * Set the source content for an original source file. - * @param sourceFile The URL of the original source file. - * @param sourceContent The content of the source file. - */ - setSourceContent(sourceFile: string, sourceContent: string): void; - /** - * Applies a SourceMap for a source file to the SourceMap. Each mapping to - * the supplied source file is rewritten using the supplied SourceMap. - * Note: The resolution for the resulting mappings is the minimum of this - * map and the supplied map. - * @param sourceMapConsumer The SourceMap to be applied. - * @param sourceFile The filename of the source file. If omitted, sourceMapConsumer - * file will be used, if it exists. Otherwise an error will be thrown. - * @param sourceMapPath The dirname of the path to the SourceMap to be applied. - * If relative, it is relative to the SourceMap. This parameter is needed when - * the two SourceMaps aren't in the same directory, and the SourceMap to be - * applied contains relative source paths. If so, those relative source paths - * need to be rewritten relative to the SourceMap. - * If omitted, it is assumed that both SourceMaps are in the same directory; - * thus, not needing any rewriting (Supplying '.' has the same effect). - */ - applySourceMap( - sourceMapConsumer: mozilla.SourceMapConsumer, - sourceFile?: string, - sourceMapPath?: string - ): void; - /** - * Renders the source map being generated to JSON. - */ - toJSON: () => mozilla.RawSourceMap; - /** - * Renders the source map being generated to a string. - */ - toString: () => string; + + export type Helpers = { postcss: Postcss; result: Result } & Postcss + + export interface Plugin extends Processors { + postcssPlugin: string + prepare?: (result: Result) => Processors } - interface ResultMessage { - type: string; - plugin: string; - [others: string]: any; + + export interface PluginCreator { + (opts?: PluginOptions): Plugin | Processor + postcss: true } - /** - * Represents a plugin warning. It can be created using Result#warn(). - */ - interface Warning { - /** - * @returns Error position, message. - */ - toString(): string; - /** - * Contains the warning message. - */ - text: string; - /** - * Contains the name of the plugin that created this warning. When you - * call Result#warn(), it will fill this property automatically. - */ - plugin: string; - /** - * The CSS node that caused the warning. - */ - node: Node; - /** - * The line in the input file with this warning's source. - */ - line: number; - /** - * Column in the input file with this warning's source. - */ - column: number; + + export interface Transformer extends TransformCallback { + postcssPlugin: string + postcssVersion: string } - interface WarningOptions extends ResultOptions { - /** - * A word inside a node's string that should be highlighted as source - * of warning. - */ - word?: string; - /** - * The index inside a node's string that should be highlighted as - * source of warning. - */ - index?: number; + + export interface TransformCallback { + (root: Root, result: Result): Promise | void } - /** - * The CSS parser throws this error for broken CSS. - */ - interface CssSyntaxError extends InputOrigin { - name: string; - /** - * @returns Error position, message and source code of broken part. - */ - toString(): string; - /** - * @param color Whether arrow should be colored red by terminal color codes. - * By default, PostCSS will use process.stdout.isTTY and - * process.env.NODE_DISABLE_COLORS. - * @returns A few lines of CSS source that caused the error. If CSS has - * input source map without sourceContent this method will return an empty - * string. - */ - showSourceCode(color?: boolean): string; - /** - * Contains full error text in the GNU error format. - */ - message: string; - /** - * Contains only the error description. - */ - reason: string; - /** - * Contains the PostCSS plugin name if the error didn't come from the - * CSS parser. - */ - plugin?: string; - input?: InputOrigin; + + export interface OldPlugin extends Transformer { + (opts?: T): Transformer + postcss: Transformer } - interface InputOrigin { - /** - * If parser's from option is set, contains the absolute path to the - * broken file. PostCSS will use the input source map to detect the - * original error location. If you wrote a Sass file, then compiled it - * to CSS and parsed it with PostCSS, PostCSS will show the original - * position in the Sass file. If you need the position in the PostCSS - * input (e.g., to debug the previous compiler), use error.input.file. - */ - file?: string; - /** - * Contains the source line of the error. PostCSS will use the input - * source map to detect the original error location. If you wrote a Sass - * file, then compiled it to CSS and parsed it with PostCSS, PostCSS - * will show the original position in the Sass file. If you need the - * position in the PostCSS input (e.g., to debug the previous - * compiler), use error.input.line. - */ - line?: number; - /** - * Contains the source column of the error. PostCSS will use input - * source map to detect the original error location. If you wrote a - * Sass file, then compiled it to CSS and parsed it with PostCSS, - * PostCSS will show the original position in the Sass file. If you - * need the position in the PostCSS input (e.g., to debug the - * previous compiler), use error.input.column. - */ - column?: number; - /** - * Contains the source code of the broken file. PostCSS will use the - * input source map to detect the original error location. If you wrote - * a Sass file, then compiled it to CSS and parsed it with PostCSS, - * PostCSS will show the original position in the Sass file. If you need - * the position in the PostCSS input (e.g., to debug the previous - * compiler), use error.input.source. - */ - source?: string; + + export type AcceptedPlugin = + | { + postcss: Processor | TransformCallback + } + | OldPlugin + | Plugin + | PluginCreator + | Processor + | TransformCallback + + export interface Parser { + ( + css: { toString(): string } | string, + opts?: Pick + ): RootNode } - export class PreviousMap { - private inline; - annotation: string; - root: string; - private consumerCache; - text: string; - file: string; - constructor(css: any, opts: any); - consumer(): mozilla.SourceMapConsumer; - withContent(): boolean; - startWith(string: string, start: string): boolean; - getAnnotationURL(sourceMapString: string): string; - loadAnnotation(css: string): void; - decodeInline(text: string): string; - loadMap( - file: any, - prev: string | Function | mozilla.SourceMapConsumer | mozilla.SourceMapGenerator | mozilla.RawSourceMap - ): string; - isMap(map: any): boolean; + + export interface Builder { + (part: string, node?: AnyNode, type?: 'end' | 'start'): void } - /** - * Represents the source CSS. - */ - interface Input { - /** - * The absolute path to the CSS source file defined with the "from" option. - * Either this property or the "id" property are always defined. - */ - file?: string; - /** - * The unique ID of the CSS source. Used if "from" option is not provided - * (because PostCSS does not know the file path). Either this property - * or the "file" property are always defined. - */ - id?: string; - /** - * The CSS source identifier. Contains input.file if the user set the - * "from" option, or input.id if they did not. - */ - from: string; - /** - * Represents the input source map passed from a compilation step before - * PostCSS (e.g., from the Sass compiler). - */ - map: PreviousMap; - /** - * The flag to indicate whether or not the source code has Unicode BOM. - */ - hasBOM: boolean; - /** - * Reads the input source map. - * @returns A symbol position in the input source (e.g., in a Sass file - * that was compiled to CSS before being passed to PostCSS): - */ - origin(line: number, column: number): InputOrigin | false; + + export interface Stringifier { + (node: AnyNode, builder: Builder): void } - type ChildNode = AtRule | Rule | Declaration | Comment; - type Node = Root | ChildNode; - interface NodeBase { - /** - * Returns the input source of the node. The property is used in source - * map generation. If you create a node manually - * (e.g., with postcss.decl() ), that node will not have a source - * property and will be absent from the source map. For this reason, the - * plugin developer should consider cloning nodes to create new ones - * (in which case the new node's source will reference the original, - * cloned node) or setting the source property manually. - */ - source?: NodeSource; - /** - * Contains information to generate byte-to-byte equal node string as it - * was in origin input. - */ - raws: NodeRaws; + + export interface JSONHydrator { + (data: object): Node + (data: object[]): Node[] + } + + export interface Syntax { /** - * @returns A CSS string representing the node. + * Function to generate AST by string. */ - toString(stringifier?: Stringifier | Syntax): string; + parse?: Parser + /** - * This method produces very useful error messages. If present, an input - * source map will be used to get the original position of the source, even - * from a previous compilation step (e.g., from Sass compilation). - * @returns The original position of the node in the source, showing line - * and column numbers and also a small excerpt to facilitate debugging. + * Class to generate string by AST. */ - error( - /** - * Error description. - */ - message: string, options?: NodeErrorOptions): CssSyntaxError; + stringify?: Stringifier + } + + export interface SourceMapOptions { /** - * Creates an instance of Warning and adds it to messages. This method is - * provided as a convenience wrapper for Result#warn. - * Note that `opts.node` is automatically passed to Result#warn for you. - * @param result The result that will receive the warning. - * @param text Warning message. It will be used in the `text` property of - * the message object. - * @param opts Properties to assign to the message object. + * Use absolute path in generated source map. */ - warn(result: Result, text: string, opts?: WarningOptions): void; + absolute?: boolean + /** - * @returns The next child of the node's parent; or, returns undefined if - * the current node is the last child. + * 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. */ - next(): ChildNode | undefined; + annotation?: ((file: string, root: Root) => string) | boolean | string + /** - * @returns The previous child of the node's parent; or, returns undefined - * if the current node is the first child. + * Override `from` in map’s sources. */ - prev(): ChildNode | undefined; + from?: string + /** - * Insert new node before current node to current node’s parent. - * - * Just an alias for `node.parent.insertBefore(node, newNode)`. + * 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. * - * @returns this node for method chaining. - * - * @example - * decl.before('content: ""'); + * 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`. */ - before(newNode: Node | object | string | Node[]): this; + inline?: boolean + /** - * Insert new node after current node to current node’s parent. - * - * Just an alias for `node.parent.insertAfter(node, newNode)`. + * Source map content from a previous processing step (e.g., Sass). * - * @returns this node for method chaining. + * 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. * - * @example - * decl.after('color: black'); - */ - after(newNode: Node | object | string | Node[]): this; - /** - * @returns The Root instance of the node's tree. + * If desired, you can omit the previous map with prev: `false`. */ - root(): Root; - /** - * Removes the node from its parent and cleans the parent property in the - * node and its children. - * @returns This node for chaining. - */ - remove(): this; - /** - * Inserts node(s) before the current node and removes the current node. - * @returns This node for chaining. - */ - replaceWith(...nodes: (Node | object)[]): this; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - /** - * Shortcut to clone the node and insert the resulting cloned node before - * the current node. - * @param overrides New Properties to override in the clone. - * @returns The cloned node. - */ - cloneBefore(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. - * @returns The cloned node. - */ - cloneAfter(overrides?: object): this; - /** - * @param prop Name or code style property. - * @param defaultType Name of default value. It can be easily missed if the - * value is the same as prop. - * @returns A code style property 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. - */ - raw(prop: string, defaultType?: string): string; - } - interface NodeNewProps { - source?: NodeSource; - raws?: NodeRaws; - } - interface NodeRaws { - /** - * The space symbols before the node. It also stores `*` and `_` - * symbols before the declaration (IE hack). - */ - before?: string; - /** - * The space symbols after the last child of the node to the end of - * the node. - */ - after?: string; - /** - * The symbols between the property and value for declarations, - * selector and "{" for rules, last parameter and "{" for at-rules. - */ - between?: string; - /** - * True if last child has (optional) semicolon. - */ - semicolon?: boolean; - /** - * The space between the at-rule's name and parameters. - */ - afterName?: string; - /** - * The space symbols between "/*" and comment's text. - */ - left?: string; - /** - * The space symbols between comment's text and "*\/". - */ - right?: string; - /** - * The content of important statement, if it is not just "!important". - */ - important?: string; - } - interface NodeSource { - input: Input; - /** - * The starting position of the node's source. - */ - start?: { - column: number; - line: number; - }; + prev?: ((file: string) => string) | boolean | object | string + /** - * The ending position of the node's source. + * 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. */ - end?: { - column: number; - line: number; - }; + sourcesContent?: boolean } - interface NodeErrorOptions { - /** - * Plugin name that created this error. PostCSS will set it automatically. - */ - plugin?: string; + + export interface ProcessOptions { /** - * A word inside a node's string, that should be highlighted as source - * of error. + * The path of the CSS source file. You should always set `from`, + * because it is used in source map generation and syntax error messages. */ - word?: string; + from?: string + /** - * An index inside a node's string that should be highlighted as source - * of error. + * Source map options */ - index?: number; - } - interface JsonNode { + map?: boolean | SourceMapOptions + /** - * Returns a string representing the node's type. Possible values are - * root, atrule, rule, decl or comment. + * Function to generate AST by string. */ - type?: string; + parser?: Parser | Syntax + /** - * Returns the node's parent node. + * Class to generate string by AST. */ - parent?: JsonContainer; + stringifier?: Stringifier | Syntax + /** - * Returns the input source of the node. The property is used in source - * map generation. If you create a node manually (e.g., with - * postcss.decl() ), that node will not have a source property and - * will be absent from the source map. For this reason, the plugin - * developer should consider cloning nodes to create new ones (in which - * case the new node's source will reference the original, cloned node) - * or setting the source property manually. + * Object with parse and stringify. */ - source?: NodeSource; + syntax?: Syntax + /** - * Contains information to generate byte-to-byte equal node string as it - * was in origin input. + * The path where you'll put the output CSS file. You should always set `to` + * to generate correct source maps. */ - raws?: NodeRaws; + to?: string } - type Container = Root | AtRule | Rule; + + export type Postcss = typeof postcss + /** - * Containers can store any content. If you write a rule inside a rule, - * PostCSS will parse it. + * Default function to convert a node tree into a CSS string. */ - interface ContainerBase extends NodeBase { - /** - * Contains the container's children. - */ - nodes?: ChildNode[]; - /** - * @returns The container's first child. - */ - first?: ChildNode; - /** - * @returns The container's last child. - */ - last?: ChildNode; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - /** - * @param child Child of the current container. - * @returns The child's index within the container's "nodes" array. - */ - index(child: ChildNode | number): number; - /** - * Determines whether all child nodes satisfy the specified test. - * @param callback A function that accepts up to three arguments. The - * every method calls the callback function for each node until the - * callback returns false, or until the end of the array. - * @returns True if the callback returns true for all of the container's - * children. - */ - every(callback: (node: ChildNode, index: number, nodes: ChildNode[]) => boolean): boolean; - /** - * Determines whether the specified callback returns true for any child node. - * @param callback A function that accepts up to three arguments. The some - * method calls the callback for each node until the callback returns true, - * or until the end of the array. - * @returns True if callback returns true for (at least) one of the - * container's children. - */ - some(callback: (node: ChildNode, index: number, nodes: ChildNode[]) => boolean): boolean; - /** - * Iterates through the container's immediate children, calling the - * callback function for each child. If you need to recursively iterate - * through all the container's descendant nodes, use container.walk(). - * Unlike the for {} -cycle or Array#forEach() this iterator is safe if - * you are mutating the array of child nodes during iteration. - * @param callback Iterator. Returning false will break iteration. Safe - * if you are mutating the array of child nodes during iteration. PostCSS - * will adjust the current index to match the mutations. - * @returns False if the callback returns false during iteration. - */ - each(callback: (node: ChildNode, index: number) => void): void; - each(callback: (node: ChildNode, index: number) => boolean): boolean; - /** - * Traverses the container's descendant nodes, calling `callback` for each - * node. Like container.each(), this method is safe to use if you are - * mutating arrays during iteration. If you only need to iterate through - * the container's immediate children, use container.each(). - * @param callback Iterator. - */ - walk(callback: (node: ChildNode, index: number) => void): void; - walk(callback: (node: ChildNode, index: number) => boolean): boolean; - /** - * Traverses the container's descendant nodes, calling `callback` for each - * declaration. Like container.each(), this method is safe to use if you - * are mutating arrays during iteration. - * @param propFilter Filters declarations by property name. Only those - * declarations whose property matches propFilter will be iterated over. - * @param callback Called for each declaration node within the container. - */ - walkDecls(propFilter: string | RegExp, callback: (decl: Declaration, index: number) => void): void; - walkDecls(callback: (decl: Declaration, index: number) => void): void; - walkDecls(propFilter: string | RegExp, callback: (decl: Declaration, index: number) => boolean): boolean; - walkDecls(callback: (decl: Declaration, index: number) => boolean): boolean; - /** - * Traverses the container's descendant nodes, calling `callback` for each - * at-rule. Like container.each(), this method is safe to use if you are - * mutating arrays during iteration. - * @param nameFilter Filters at-rules by name. If provided, iteration - * will only happen over at-rules that have matching names. - * @param callback Iterator called for each at-rule node within the - * container. - */ - walkAtRules(nameFilter: string | RegExp, callback: (atRule: AtRule, index: number) => void): void; - walkAtRules(callback: (atRule: AtRule, index: number) => void): void; - walkAtRules(nameFilter: string | RegExp, callback: (atRule: AtRule, index: number) => boolean): boolean; - walkAtRules(callback: (atRule: AtRule, index: number) => boolean): boolean; - /** - * Traverses the container's descendant nodes, calling `callback` for each - * rule. Like container.each(), this method is safe to use if you are - * mutating arrays during iteration. - * @param selectorFilter Filters rules by selector. If provided, - * iteration will only happen over rules that have matching names. - * @param callback Iterator called for each rule node within the - * container. - */ - walkRules(selectorFilter: string | RegExp, callback: (atRule: Rule, index: number) => void): void; - walkRules(callback: (atRule: Rule, index: number) => void): void; - walkRules(selectorFilter: string | RegExp, callback: (atRule: Rule, index: number) => boolean): boolean; - walkRules(callback: (atRule: Rule, index: number) => boolean): boolean; - /** - * Traverses the container's descendant nodes, calling `callback` for each - * comment. Like container.each(), this method is safe to use if you are - * mutating arrays during iteration. - * @param callback Iterator called for each comment node within the container. - */ - walkComments(callback: (comment: Comment, indexed: number) => void): void; - walkComments(callback: (comment: Comment, indexed: number) => boolean): boolean; - /** - * Passes all declaration values within the container that match pattern - * through the callback, replacing those values with the returned result of - * callback. This method is useful if you are using a custom unit or - * function and need to iterate through all values. - * @param pattern Pattern that we need to replace. - * @param options Options to speed up the search. - * @param callbackOrReplaceValue String to replace pattern or callback - * that will return a new value. The callback will receive the same - * arguments as those passed to a function parameter of String#replace. - */ - replaceValues(pattern: string | RegExp, options: { - /** - * Property names. The method will only search for values that match - * regexp within declarations of listed properties. - */ - props?: string[]; - /** - * Used to narrow down values and speed up the regexp search. Searching - * every single value with a regexp can be slow. If you pass a fast - * string, PostCSS will first check whether the value contains the fast - * string; and only if it does will PostCSS check that value against - * regexp. For example, instead of just checking for /\d+rem/ on all - * values, set fast: 'rem' to first check whether a value has the rem - * unit, and only if it does perform the regexp check. - */ - fast?: string; - }, callbackOrReplaceValue: string | { - (substring: string, ...args: any[]): string; - }): this; - replaceValues(pattern: string | RegExp, callbackOrReplaceValue: string | { - (substring: string, ...args: any[]): string; - }): this; - /** - * Inserts new nodes to the beginning of the container. - * Because each node class is identifiable by unique properties, use the - * following shortcuts to create nodes in insert methods: - * root.prepend({ name: '@charset', params: '"UTF-8"' }); // at-rule - * root.prepend({ selector: 'a' }); // rule - * rule.prepend({ prop: 'color', value: 'black' }); // declaration - * rule.prepend({ text: 'Comment' }) // comment - * A string containing the CSS of the new element can also be used. This - * approach is slower than the above shortcuts. - * root.prepend('a {}'); - * root.first.prepend('color: black; z-index: 1'); - * @param nodes New nodes. - * @returns This container for chaining. - */ - prepend(...nodes: (Node | object | string)[]): this; - /** - * Inserts new nodes to the end of the container. - * Because each node class is identifiable by unique properties, use the - * following shortcuts to create nodes in insert methods: - * root.append({ name: '@charset', params: '"UTF-8"' }); // at-rule - * root.append({ selector: 'a' }); // rule - * rule.append({ prop: 'color', value: 'black' }); // declaration - * rule.append({ text: 'Comment' }) // comment - * A string containing the CSS of the new element can also be used. This - * approach is slower than the above shortcuts. - * root.append('a {}'); - * root.first.append('color: black; z-index: 1'); - * @param nodes New nodes. - * @returns This container for chaining. - */ - append(...nodes: (Node | object | string)[]): this; - /** - * Insert newNode before oldNode within the container. - * @param oldNode Child or child's index. - * @returns This container for chaining. - */ - insertBefore(oldNode: ChildNode | number, newNode: ChildNode | object | string): this; - /** - * Insert newNode after oldNode within the container. - * @param oldNode Child or child's index. - * @returns This container for chaining. - */ - insertAfter(oldNode: ChildNode | number, newNode: ChildNode | object | string): this; - /** - * Removes the container from its parent and cleans the parent property in the - * container and its children. - * @returns This container for chaining. - */ - remove(): this; - /** - * Removes child from the container and cleans the parent properties - * from the node and its children. - * @param child Child or child's index. - * @returns This container for chaining. - */ - removeChild(child: ChildNode | number): this; - /** - * Removes all children from the container and cleans their parent - * properties. - * @returns This container for chaining. - */ - removeAll(): this; - } - interface ContainerNewProps extends NodeNewProps { - /** - * Contains the container's children. - */ - nodes?: ChildNode[]; - raws?: ContainerRaws; - } - interface ContainerRaws extends NodeRaws { - indent?: string; - } - interface JsonContainer extends JsonNode { - /** - * Contains the container's children. - */ - nodes?: ChildNode[]; - /** - * @returns The container's first child. - */ - first?: ChildNode; - /** - * @returns The container's last child. - */ - last?: ChildNode; - } - /** - * Represents a CSS file and contains all its parsed nodes. - */ - interface Root extends ContainerBase { - type: 'root'; - /** - * Inherited from Container. Should always be undefined for a Root node. - */ - parent: void; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - /** - * @returns A Result instance representing the root's CSS. - */ - toResult(options?: { - /** - * The path where you'll put the output CSS file. You should always - * set "to" to generate correct source maps. - */ - to?: string; - map?: SourceMapOptions; - }): Result; - /** - * Removes child from the root node, and the parent properties of node and - * its children. - * @param child Child or child's index. - * @returns This root node for chaining. - */ - removeChild(child: ChildNode | number): this; - } - interface RootNewProps extends ContainerNewProps { - } - interface JsonRoot extends JsonContainer { - } + export let stringify: Stringifier + /** - * Represents an at-rule. If it's followed in the CSS by a {} block, this - * node will have a nodes property representing its children. + * 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 + * ``` */ - interface AtRule extends ContainerBase { - type: 'atrule'; - /** - * Returns the atrule's parent node. - */ - parent: Container; - /** - * The identifier that immediately follows the @. - */ - name: string; - /** - * These are the values that follow the at-rule's name, but precede any {} - * block. The spec refers to this area as the at-rule's "prelude". - */ - params: string; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - } - interface AtRuleNewProps extends ContainerNewProps { - /** - * The identifier that immediately follows the @. - */ - name?: string; - /** - * These are the values that follow the at-rule's name, but precede any {} - * block. The spec refers to this area as the at-rule's "prelude". - */ - params?: string | number; - raws?: AtRuleRaws; - } - interface AtRuleRaws extends NodeRaws { - params?: string; - } - interface JsonAtRule extends JsonContainer { - /** - * The identifier that immediately follows the @. - */ - name?: string; - /** - * These are the values that follow the at-rule's name, but precede any {} - * block. The spec refers to this area as the at-rule's "prelude". - */ - params?: string; - } + export let parse: Parser + /** - * Represents a CSS rule: a selector followed by a declaration block. + * 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) + * ``` */ - interface Rule extends ContainerBase { - type: 'rule'; - /** - * Returns the rule's parent node. - */ - parent: Container; - /** - * The rule's full selector. If there are multiple comma-separated selectors, - * the entire group will be included. - */ - selector: string; - /** - * An array containing the rule's individual selectors. - * Groups of selectors are split at commas. - */ - selectors: string[]; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - } - interface RuleNewProps extends ContainerNewProps { - /** - * The rule's full selector. If there are multiple comma-separated selectors, - * the entire group will be included. - */ - selector?: string; - /** - * An array containing the rule's individual selectors. Groups of selectors - * are split at commas. - */ - selectors?: string[]; - raws?: RuleRaws; - } - interface RuleRaws extends ContainerRaws { - /** - * The rule's full selector. If there are multiple comma-separated selectors, - * the entire group will be included. - */ - selector?: string; - } - interface JsonRule extends JsonContainer { - /** - * The rule's full selector. If there are multiple comma-separated selectors, - * the entire group will be included. - */ - selector?: string; - /** - * An array containing the rule's individual selectors. - * Groups of selectors are split at commas. - */ - selectors?: string[]; - } + export let fromJSON: JSONHydrator + /** - * Represents a CSS declaration. + * Creates a new `Comment` node. + * + * @param defaults Properties for the new node. + * @return New comment node */ - interface Declaration extends NodeBase { - type: 'decl'; - /** - * Returns the declaration's parent node. - */ - parent: Container; - /** - * The declaration's property name. - */ - prop: string; - /** - * The declaration's value. This value will be cleaned of comments. If the - * source value contained comments, those comments will be available in the - * _value.raws property. If you have not changed the value, the result of - * decl.toString() will include the original raws value (comments and all). - */ - value: string; - /** - * True if the declaration has an !important annotation. - */ - important: boolean; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - } - interface DeclarationNewProps { - /** - * The declaration's property name. - */ - prop?: string; - /** - * The declaration's value. This value will be cleaned of comments. If the - * source value contained comments, those comments will be available in the - * _value.raws property. If you have not changed the value, the result of - * decl.toString() will include the original raws value (comments and all). - */ - value?: string; - raws?: DeclarationRaws; - } - interface DeclarationRaws extends NodeRaws { - /** - * The declaration's value. This value will be cleaned of comments. - * If the source value contained comments, those comments will be - * available in the _value.raws property. If you have not changed the value, the result of - * decl.toString() will include the original raws value (comments and all). - */ - value?: string; - } - interface JsonDeclaration extends JsonNode { - /** - * True if the declaration has an !important annotation. - */ - important?: boolean; - } + export function comment(defaults?: CommentProps): Comment + /** - * Represents a comment between declarations or statements (rule and at-rules). - * Comments inside selectors, at-rule parameters, or declaration values will - * be stored in the Node#raws properties. + * Creates a new `AtRule` node. + * + * @param defaults Properties for the new node. + * @return New at-rule node. */ - interface Comment extends NodeBase { - type: 'comment'; - /** - * Returns the comment's parent node. - */ - parent: Container; - /** - * The comment's text. - */ - text: string; - /** - * @param overrides New properties to override in the clone. - * @returns A clone of this node. The node and its (cloned) children will - * have a clean parent and code style properties. - */ - clone(overrides?: object): this; - } - interface CommentNewProps { - /** - * The comment's text. - */ - text?: string; - } - interface JsonComment extends JsonNode { - } + 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 } } -export = postcss; + +/** + * 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?: postcss.AcceptedPlugin[]): Processor +declare function postcss(...plugins: postcss.AcceptedPlugin[]): Processor + +export = postcss diff --git a/lib/postcss.es6 b/lib/postcss.es6 deleted file mode 100644 index 4f75edd2d..000000000 --- a/lib/postcss.es6 +++ /dev/null @@ -1,245 +0,0 @@ -import Declaration from './declaration' -import Processor from './processor' -import stringify from './stringify' -import Comment from './comment' -import AtRule from './at-rule' -import vendor from './vendor' -import parse from './parse' -import list from './list' -import Rule from './rule' -import Root from './root' - -/** - * Create a new {@link Processor} instance that will apply `plugins` - * as CSS processors. - * - * @param {Array.|Processor} plugins PostCSS plugins. - * See {@link Processor#use} for plugin format. - * - * @return {Processor} Processor to process multiple CSS. - * - * @example - * import postcss from 'postcss' - * - * postcss(plugins).process(css, { from, to }).then(result => { - * console.log(result.css) - * }) - * - * @namespace postcss - */ -function postcss (...plugins) { - if (plugins.length === 1 && Array.isArray(plugins[0])) { - plugins = plugins[0] - } - return new Processor(plugins) -} - -/** - * Creates a PostCSS plugin with a standard API. - * - * The newly-wrapped function will provide both the name and PostCSS - * version of the plugin. - * - * ```js - * const processor = postcss([replace]) - * processor.plugins[0].postcssPlugin //=> 'postcss-replace' - * processor.plugins[0].postcssVersion //=> '6.0.0' - * ``` - * - * The plugin function receives 2 arguments: {@link Root} - * and {@link Result} instance. The function should mutate the provided - * `Root` node. Alternatively, you can create a new `Root` node - * and override the `result.root` property. - * - * ```js - * const cleaner = postcss.plugin('postcss-cleaner', () => { - * return (root, result) => { - * result.root = postcss.root() - * } - * }) - * ``` - * - * As a convenience, plugins also expose a `process` method so that you can use - * them as standalone tools. - * - * ```js - * cleaner.process(css, processOpts, pluginOpts) - * // This is equivalent to: - * postcss([ cleaner(pluginOpts) ]).process(css, processOpts) - * ``` - * - * Asynchronous plugins should return a `Promise` instance. - * - * ```js - * postcss.plugin('postcss-import', () => { - * return (root, result) => { - * return new Promise( (resolve, reject) => { - * fs.readFile('base.css', (base) => { - * root.prepend(base) - * resolve() - * }) - * }) - * } - * }) - * ``` - * - * Add warnings using the {@link Node#warn} method. - * Send data to other plugins using the {@link Result#messages} array. - * - * ```js - * postcss.plugin('postcss-caniuse-test', () => { - * return (root, result) => { - * root.walkDecls(decl => { - * if (!caniuse.support(decl.prop)) { - * decl.warn(result, 'Some browsers do not support ' + decl.prop) - * } - * }) - * } - * }) - * ``` - * - * @param {string} name PostCSS plugin name. Same as in `name` - * property in `package.json`. It will be saved - * in `plugin.postcssPlugin` property. - * @param {function} initializer Will receive plugin options - * and should return {@link pluginFunction} - * - * @return {Plugin} PostCSS plugin. - */ -postcss.plugin = function plugin (name, initializer) { - function creator (...args) { - 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 -} - -/** - * Default function to convert a node tree into a CSS string. - * - * @param {Node} node Start node for stringifing. Usually {@link Root}. - * @param {builder} builder Function to concatenate CSS from node’s parts - * or generate string and source map. - * - * @return {void} - * - * @function - */ -postcss.stringify = stringify - -/** - * Parses source css and returns a new {@link Root} node, - * which contains the source CSS nodes. - * - * @param {string|toString} css String with input CSS or any object - * with toString() method, like a Buffer - * @param {processOptions} [opts] Options with only `from` and `map` keys. - * - * @return {Root} PostCSS AST. - * - * @example - * // 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 - * - * @function - */ -postcss.parse = parse - -/** - * Contains the {@link vendor} module. - * - * @type {vendor} - * - * @example - * postcss.vendor.unprefixed('-moz-tab') //=> ['tab'] - */ -postcss.vendor = vendor - -/** - * Contains the {@link list} module. - * - * @member {list} - * - * @example - * postcss.list.space('5px calc(10% + 5px)') //=> ['5px', 'calc(10% + 5px)'] - */ -postcss.list = list - -/** - * Creates a new {@link Comment} node. - * - * @param {object} [defaults] Properties for the new node. - * - * @return {Comment} New comment node - * - * @example - * postcss.comment({ text: 'test' }) - */ -postcss.comment = defaults => new Comment(defaults) - -/** - * Creates a new {@link AtRule} node. - * - * @param {object} [defaults] Properties for the new node. - * - * @return {AtRule} new at-rule node - * - * @example - * postcss.atRule({ name: 'charset' }).toString() //=> "@charset" - */ -postcss.atRule = defaults => new AtRule(defaults) - -/** - * Creates a new {@link Declaration} node. - * - * @param {object} [defaults] Properties for the new node. - * - * @return {Declaration} new declaration node - * - * @example - * postcss.decl({ prop: 'color', value: 'red' }).toString() //=> "color: red" - */ -postcss.decl = defaults => new Declaration(defaults) - -/** - * Creates a new {@link Rule} node. - * - * @param {object} [defaults] Properties for the new node. - * - * @return {Rule} new rule node - * - * @example - * postcss.rule({ selector: 'a' }).toString() //=> "a {\n}" - */ -postcss.rule = defaults => new Rule(defaults) - -/** - * Creates a new {@link Root} node. - * - * @param {object} [defaults] Properties for the new node. - * - * @return {Root} new root node. - * - * @example - * postcss.root({ after: '\n' }).toString() //=> "\n" - */ -postcss.root = defaults => new Root(defaults) - -export default postcss diff --git a/lib/postcss.js b/lib/postcss.js new file mode 100644 index 000000000..080ee8378 --- /dev/null +++ b/lib/postcss.js @@ -0,0 +1,101 @@ +'use strict' + +let CssSyntaxError = require('./css-syntax-error') +let Declaration = require('./declaration') +let LazyResult = require('./lazy-result') +let Container = require('./container') +let Processor = require('./processor') +let stringify = require('./stringify') +let fromJSON = require('./fromJSON') +let Document = require('./document') +let Warning = require('./warning') +let Comment = require('./comment') +let AtRule = require('./at-rule') +let Result = require('./result.js') +let Input = require('./input') +let parse = require('./parse') +let list = require('./list') +let Rule = require('./rule') +let Root = require('./root') +let Node = require('./node') + +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 diff --git a/lib/postcss.mjs b/lib/postcss.mjs new file mode 100644 index 000000000..35075988c --- /dev/null +++ b/lib/postcss.mjs @@ -0,0 +1,30 @@ +import 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 diff --git a/lib/previous-map.d.ts b/lib/previous-map.d.ts new file mode 100644 index 000000000..23edeb5c5 --- /dev/null +++ b/lib/previous-map.d.ts @@ -0,0 +1,81 @@ +import { 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 diff --git a/lib/previous-map.es6 b/lib/previous-map.es6 deleted file mode 100644 index d2c44b814..000000000 --- a/lib/previous-map.es6 +++ /dev/null @@ -1,157 +0,0 @@ -import mozilla from 'source-map' -import path from 'path' -import fs from 'fs' - -function fromBase64 (str) { - if (Buffer) { - return Buffer.from(str, 'base64').toString() - } else { - return window.atob(str) - } -} - -/** - * 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). - * - * @example - * const root = postcss.parse(css, { from: 'a.sass.css' }) - * root.input.map //=> PreviousMap - */ -class PreviousMap { - /** - * @param {string} css Input CSS source. - * @param {processOptions} [opts] {@link Processor#process} options. - */ - constructor (css, opts) { - this.loadAnnotation(css) - /** - * Was source map inlined by data-uri to input CSS. - * - * @type {boolean} - */ - this.inline = this.startWith(this.annotation, 'data:') - - let prev = opts.map ? opts.map.prev : undefined - let text = this.loadMap(opts.from, prev) - if (text) this.text = text - } - - /** - * 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 {SourceMapGenerator} Object with source map information. - */ - consumer () { - if (!this.consumerCache) { - this.consumerCache = new mozilla.SourceMapConsumer(this.text) - } - return this.consumerCache - } - - /** - * Does source map contains `sourcesContent` with input source text. - * - * @return {boolean} Is `sourcesContent` present. - */ - withContent () { - return !!(this.consumer().sourcesContent && - this.consumer().sourcesContent.length > 0) - } - - startWith (string, start) { - if (!string) return false - return string.substr(0, start.length) === start - } - - getAnnotationURL (sourceMapString) { - return sourceMapString - .match(/\/\*\s*# sourceMappingURL=((?:(?!sourceMappingURL=).)*)\*\//)[1] - .trim() - } - - loadAnnotation (css) { - let annotations = css.match( - /\/\*\s*# sourceMappingURL=(?:(?!sourceMappingURL=).)*\*\//gm - ) - - if (annotations && annotations.length > 0) { - // Locate the last sourceMappingURL to avoid picking up - // sourceMappingURLs from comments, strings, etc. - let lastAnnotation = annotations[annotations.length - 1] - if (lastAnnotation) { - this.annotation = this.getAnnotationURL(lastAnnotation) - } - } - } - - decodeInline (text) { - let baseCharsetUri = /^data:application\/json;charset=utf-?8;base64,/ - let baseUri = /^data:application\/json;base64,/ - let uri = 'data:application/json,' - - if (this.startWith(text, uri)) { - return decodeURIComponent(text.substr(uri.length)) - } - - if (baseCharsetUri.test(text) || baseUri.test(text)) { - return fromBase64(text.substr(RegExp.lastMatch.length)) - } - - let encoding = text.match(/data:application\/json;([^,]+),/)[1] - throw new Error('Unsupported source map encoding ' + encoding) - } - - 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 && fs.existsSync && fs.existsSync(prevPath)) { - return fs.readFileSync(prevPath, 'utf-8').toString().trim() - } else { - throw new Error( - 'Unable to load previous source map: ' + prevPath.toString()) - } - } else if (prev instanceof mozilla.SourceMapConsumer) { - return mozilla.SourceMapGenerator.fromSourceMap(prev).toString() - } else if (prev instanceof mozilla.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 = path.join(path.dirname(file), map) - - this.root = path.dirname(map) - if (fs.existsSync && fs.existsSync(map)) { - return fs.readFileSync(map, 'utf-8').toString().trim() - } else { - return false - } - } - } - - isMap (map) { - if (typeof map !== 'object') return false - return typeof map.mappings === 'string' || typeof map._mappings === 'string' - } -} - -export default PreviousMap diff --git a/lib/previous-map.js b/lib/previous-map.js new file mode 100644 index 000000000..f3093dfb8 --- /dev/null +++ b/lib/previous-map.js @@ -0,0 +1,142 @@ +'use strict' + +let { SourceMapConsumer, SourceMapGenerator } = require('source-map-js') +let { existsSync, readFileSync } = require('fs') +let { dirname, join } = require('path') + +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,/ + + if (charsetUri.test(text) || uri.test(text)) { + return decodeURIComponent(text.substr(RegExp.lastMatch.length)) + } + + if (baseCharsetUri.test(text) || baseUri.test(text)) { + return fromBase64(text.substr(RegExp.lastMatch.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=/gm) + 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 diff --git a/lib/processor.d.ts b/lib/processor.d.ts new file mode 100644 index 000000000..50c9a07d3 --- /dev/null +++ b/lib/processor.d.ts @@ -0,0 +1,115 @@ +import 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?: 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 diff --git a/lib/processor.es6 b/lib/processor.es6 deleted file mode 100644 index 4f83f4560..000000000 --- a/lib/processor.es6 +++ /dev/null @@ -1,234 +0,0 @@ -import LazyResult from './lazy-result' - -/** - * Contains plugins to process CSS. Create one `Processor` instance, - * initialize its plugins, and then use that instance on numerous CSS files. - * - * @example - * const processor = postcss([autoprefixer, precss]) - * processor.process(css1).then(result => console.log(result.css)) - * processor.process(css2).then(result => console.log(result.css)) - */ -class Processor { - /** - * @param {Array.|Processor} plugins PostCSS plugins. - * See {@link Processor#use} for plugin format. - */ - constructor (plugins = []) { - /** - * Current PostCSS version. - * - * @type {string} - * - * @example - * if (result.processor.version.split('.')[0] !== '6') { - * throw new Error('This plugin works only with PostCSS 6') - * } - */ - this.version = '7.0.36' - /** - * Plugins added to this processor. - * - * @type {pluginFunction[]} - * - * @example - * const processor = postcss([autoprefixer, precss]) - * processor.plugins.length //=> 2 - */ - this.plugins = this.normalize(plugins) - } - - /** - * Adds a plugin to be used as a CSS processor. - * - * PostCSS plugin can be in 4 formats: - * * A plugin created by {@link postcss.plugin} method. - * * A function. PostCSS will pass the function a @{link Root} - * as the first argument and current {@link Result} instance - * as the second. - * * An object with a `postcss` method. PostCSS will use that method - * as described in #2. - * * Another {@link 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. - * - * @param {Plugin|pluginFunction|Processor} plugin PostCSS plugin - * or {@link Processor} - * with plugins. - * - * @example - * const processor = postcss() - * .use(autoprefixer) - * .use(precss) - * - * @return {Processes} Current processor to make methods chain. - */ - use (plugin) { - this.plugins = this.plugins.concat(this.normalize([plugin])) - return this - } - - /** - * Parses source CSS and returns a {@link LazyResult} Promise proxy. - * Because some plugins can be asynchronous it doesn’t make - * any transformations. Transformations will be applied - * in the {@link LazyResult} methods. - * - * @param {string|toString|Result} css String with input CSS or any object - * with a `toString()` method, - * like a Buffer. Optionally, send - * a {@link Result} instance - * and the processor will take - * the {@link Root} from it. - * @param {processOptions} [opts] Options. - * - * @return {LazyResult} Promise proxy. - * - * @example - * processor.process(css, { from: 'a.css', to: 'a.out.css' }) - * .then(result => { - * console.log(result.css) - * }) - */ - process (css, opts = { }) { - if (this.plugins.length === 0 && opts.parser === opts.stringifier) { - if (process.env.NODE_ENV !== 'production') { - if (typeof console !== 'undefined' && console.warn) { - console.warn( - 'You did not set any plugins, parser, or stringifier. ' + - 'Right now, PostCSS does nothing. Pick plugins for your case ' + - 'on https://www.postcss.parts/ and use them in postcss.config.js.' - ) - } - } - } - return new LazyResult(this, css, opts) - } - - normalize (plugins) { - let normalized = [] - for (let i of plugins) { - if (i.postcss === true) { - let plugin = i() - throw new Error( - 'PostCSS plugin ' + plugin.postcssPlugin + ' requires PostCSS 8.\n' + - 'Migration guide for end-users:\n' + - 'https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users' - ) - } - - if (i.postcss) i = i.postcss - - if (typeof i === 'object' && Array.isArray(i.plugins)) { - normalized = normalized.concat(i.plugins) - } 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 if (typeof i === 'object' && i.postcssPlugin) { - throw new Error( - 'PostCSS plugin ' + i.postcssPlugin + ' requires PostCSS 8.\n' + - 'Migration guide for end-users:\n' + - 'https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users' - ) - } else { - throw new Error(i + ' is not a PostCSS plugin') - } - } - return normalized - } -} - -export default Processor - -/** - * @callback builder - * @param {string} part Part of generated CSS connected to this node. - * @param {Node} node AST node. - * @param {"start"|"end"} [type] Node’s part type. - */ - -/** - * @callback parser - * - * @param {string|toString} css String with input CSS or any object - * with toString() method, like a Buffer. - * @param {processOptions} [opts] Options with only `from` and `map` keys. - * - * @return {Root} PostCSS AST - */ - -/** - * @callback stringifier - * - * @param {Node} node Start node for stringifing. Usually {@link Root}. - * @param {builder} builder Function to concatenate CSS from node’s parts - * or generate string and source map. - * - * @return {void} - */ - -/** - * @typedef {object} syntax - * @property {parser} parse Function to generate AST by string. - * @property {stringifier} stringify Function to generate string by AST. - */ - -/** - * @typedef {object} toString - * @property {function} toString - */ - -/** - * @callback pluginFunction - * @param {Root} root Parsed input CSS. - * @param {Result} result Result to set warnings or check other plugins. - */ - -/** - * @typedef {object} Plugin - * @property {function} postcss PostCSS plugin function. - */ - -/** - * @typedef {object} processOptions - * @property {string} from The path of the CSS source file. - * You should always set `from`, - * because it is used in source map - * generation and syntax error messages. - * @property {string} to The path where you’ll put the output - * CSS file. You should always set `to` - * to generate correct source maps. - * @property {parser} parser Function to generate AST by string. - * @property {stringifier} stringifier Class to generate string by AST. - * @property {syntax} syntax Object with `parse` and `stringify`. - * @property {object} map Source map options. - * @property {boolean} map.inline Does source map should - * be embedded in the output - * CSS as a base64-encoded - * comment. - * @property {string|object|false|function} map.prev Source map content - * from a previous - * processing step - * (for example, Sass). - * PostCSS will try to find - * previous map automatically, - * so you could disable it by - * `false` value. - * @property {boolean} map.sourcesContent Does PostCSS should set - * the origin content to map. - * @property {string|false} map.annotation Does PostCSS should set - * annotation comment to map. - * @property {string} map.from Override `from` in map’s - * sources`. - */ diff --git a/lib/processor.js b/lib/processor.js new file mode 100644 index 000000000..92842b699 --- /dev/null +++ b/lib/processor.js @@ -0,0 +1,67 @@ +'use strict' + +let NoWorkResult = require('./no-work-result') +let LazyResult = require('./lazy-result') +let Document = require('./document') +let Root = require('./root') + +class Processor { + constructor(plugins = []) { + this.version = '8.4.31' + 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 === 0 && + typeof opts.parser === 'undefined' && + typeof opts.stringifier === 'undefined' && + typeof opts.syntax === 'undefined' + ) { + 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) diff --git a/lib/result.d.ts b/lib/result.d.ts new file mode 100644 index 000000000..c3dcbdab1 --- /dev/null +++ b/lib/result.d.ts @@ -0,0 +1,206 @@ +import { + 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 diff --git a/lib/result.es6 b/lib/result.es6 deleted file mode 100644 index e67a73b55..000000000 --- a/lib/result.es6 +++ /dev/null @@ -1,178 +0,0 @@ -import Warning from './warning' - -/** - * Provides the result of the PostCSS transformations. - * - * A Result instance is returned by {@link LazyResult#then} - * or {@link Root#toResult} methods. - * - * @example - * postcss([autoprefixer]).process(css).then(result => { - * console.log(result.css) - * }) - * - * @example - * const result2 = postcss.parse(css).toResult() - */ -class Result { - /** - * @param {Processor} processor Processor used for this transformation. - * @param {Root} root Root node after all transformations. - * @param {processOptions} opts Options from the {@link Processor#process} - * or {@link Root#toResult}. - */ - constructor (processor, root, opts) { - /** - * The Processor instance used for this transformation. - * - * @type {Processor} - * - * @example - * for (const plugin of result.processor.plugins) { - * if (plugin.postcssPlugin === 'postcss-bad') { - * throw 'postcss-good is incompatible with postcss-bad' - * } - * }) - */ - this.processor = processor - /** - * Contains messages from plugins (e.g., warnings or custom messages). - * Each message should have type and plugin properties. - * - * @type {Message[]} - * - * @example - * postcss.plugin('postcss-min-browser', () => { - * return (root, result) => { - * const browsers = detectMinBrowsersByCanIUse(root) - * result.messages.push({ - * type: 'min-browser', - * plugin: 'postcss-min-browser', - * browsers - * }) - * } - * }) - */ - this.messages = [] - /** - * Root node after all transformations. - * - * @type {Root} - * - * @example - * root.toResult().root === root - */ - this.root = root - /** - * Options from the {@link Processor#process} or {@link Root#toResult} call - * that produced this Result instance. - * - * @type {processOptions} - * - * @example - * root.toResult(opts).opts === opts - */ - this.opts = opts - /** - * A CSS string representing of {@link Result#root}. - * - * @type {string} - * - * @example - * postcss.parse('a{}').toResult().css //=> "a{}" - */ - this.css = undefined - /** - * An instance of `SourceMapGenerator` class from the `source-map` library, - * representing changes to the {@link Result#root} instance. - * - * @type {SourceMapGenerator} - * - * @example - * result.map.toJSON() //=> { version: 3, file: 'a.css', … } - * - * @example - * if (result.map) { - * fs.writeFileSync(result.opts.to + '.map', result.map.toString()) - * } - */ - this.map = undefined - } - - /** - * Returns for @{link Result#css} content. - * - * @example - * result + '' === result.css - * - * @return {string} String representing of {@link Result#root}. - */ - toString () { - return this.css - } - - /** - * Creates an instance of {@link Warning} and adds it - * to {@link Result#messages}. - * - * @param {string} text Warning message. - * @param {Object} [opts] Warning options. - * @param {Node} opts.node CSS node that caused the warning. - * @param {string} opts.word Word in CSS source that caused the warning. - * @param {number} opts.index Index in CSS node string that caused - * the warning. - * @param {string} opts.plugin Name of the plugin that created - * this warning. {@link Result#warn} fills - * this property automatically. - * - * @return {Warning} Created warning. - */ - 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 - } - - /** - * Returns warnings from plugins. Filters {@link Warning} instances - * from {@link Result#messages}. - * - * @example - * result.warnings().forEach(warn => { - * console.warn(warn.toString()) - * }) - * - * @return {Warning[]} Warnings from plugins. - */ - warnings () { - return this.messages.filter(i => i.type === 'warning') - } - - /** - * An alias for the {@link Result#css} property. - * Use it with syntaxes that generate non-CSS output. - * - * @type {string} - * - * @example - * result.css === result.content - */ - get content () { - return this.css - } -} - -export default Result - -/** - * @typedef {object} Message - * @property {string} type Message type. - * @property {string} plugin Source PostCSS plugin name. - */ diff --git a/lib/result.js b/lib/result.js new file mode 100644 index 000000000..a39751de0 --- /dev/null +++ b/lib/result.js @@ -0,0 +1,42 @@ +'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 diff --git a/lib/root.d.ts b/lib/root.d.ts new file mode 100644 index 000000000..98fb4bc91 --- /dev/null +++ b/lib/root.d.ts @@ -0,0 +1,86 @@ +import 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 { + parent: Document | undefined + raws: Root.RootRaws + type: 'root' + + constructor(defaults?: Root.RootProps) + + assign(overrides: object | Root.RootProps): this + clone(overrides?: Partial): Root + cloneAfter(overrides?: Partial): Root + cloneBefore(overrides?: Partial): Root + + /** + * 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 opts Options. + * @return Result with current root’s CSS. + */ + toResult(options?: ProcessOptions): Result +} + +declare class Root extends Root_ {} + +export = Root diff --git a/lib/root.es6 b/lib/root.es6 deleted file mode 100644 index d813db840..000000000 --- a/lib/root.es6 +++ /dev/null @@ -1,88 +0,0 @@ -import Container from './container' - -/** - * Represents a CSS file and contains all its parsed nodes. - * - * @extends Container - * - * @example - * const root = postcss.parse('a{color:black} b{z-index:2}') - * root.type //=> 'root' - * root.nodes.length //=> 2 - */ -class Root extends Container { - constructor (defaults) { - super(defaults) - this.type = 'root' - if (!this.nodes) this.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) - } - - 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 - } - - /** - * Returns a {@link Result} instance representing the root’s CSS. - * - * @param {processOptions} [opts] Options with only `to` and `map` keys. - * - * @return {Result} Result with current root’s CSS. - * - * @example - * 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 }) - */ - toResult (opts = { }) { - let LazyResult = require('./lazy-result') - let Processor = require('./processor') - - let lazy = new LazyResult(new Processor(), this, opts) - return lazy.stringify() - } - - /** - * @memberof Root# - * @member {object} raws Information to generate byte-to-byte equal - * node string as it was in the origin input. - * - * Every parser saves its own properties, - * but the default CSS parser uses: - * - * * `after`: the space symbols after the last child to the end of file. - * * `semicolon`: is the last child has an (optional) semicolon. - * - * @example - * postcss.parse('a {}\n').raws //=> { after: '\n' } - * postcss.parse('a {}').raws //=> { after: '' } - */ -} - -export default Root diff --git a/lib/root.js b/lib/root.js new file mode 100644 index 000000000..ea574edca --- /dev/null +++ b/lib/root.js @@ -0,0 +1,61 @@ +'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) diff --git a/lib/rule.d.ts b/lib/rule.d.ts new file mode 100644 index 000000000..04be5d6c0 --- /dev/null +++ b/lib/rule.d.ts @@ -0,0 +1,113 @@ +import Container, { ContainerProps } 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 interface RuleProps extends ContainerProps { + /** 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 of the rule represented as an array of strings. */ + selectors?: string[] + } + + // 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 { + parent: Container | undefined + raws: Rule.RuleRaws + /** + * The rule’s full selector represented as a string. + * + * ```js + * const root = postcss.parse('a, b { }') + * const rule = root.first + * rule.selector //=> 'a, b' + * ``` + */ + selector: 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' + * ``` + */ + selectors: string[] + + type: 'rule' + + constructor(defaults?: Rule.RuleProps) + assign(overrides: object | Rule.RuleProps): this + clone(overrides?: Partial): Rule + cloneAfter(overrides?: Partial): Rule + cloneBefore(overrides?: Partial): Rule +} + +declare class Rule extends Rule_ {} + +export = Rule diff --git a/lib/rule.es6 b/lib/rule.es6 deleted file mode 100644 index 294399dcf..000000000 --- a/lib/rule.es6 +++ /dev/null @@ -1,89 +0,0 @@ -import Container from './container' -import list from './list' - -/** - * Represents a CSS rule: a selector followed by a declaration block. - * - * @extends Container - * - * @example - * const root = postcss.parse('a{}') - * const rule = root.first - * rule.type //=> 'rule' - * rule.toString() //=> 'a{}' - */ -class Rule extends Container { - constructor (defaults) { - super(defaults) - this.type = 'rule' - if (!this.nodes) this.nodes = [] - } - - /** - * An array containing the rule’s individual selectors. - * Groups of selectors are split at commas. - * - * @type {string[]} - * - * @example - * 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 () { - 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) - } - - /** - * @memberof Rule# - * @member {string} selector The rule’s full selector represented - * as a string. - * - * @example - * const root = postcss.parse('a, b { }') - * const rule = root.first - * rule.selector //=> 'a, b' - */ - - /** - * @memberof Rule# - * @member {object} raws Information to generate byte-to-byte equal - * node string as it was in the origin input. - * - * Every parser saves its own properties, - * but the default CSS parser uses: - * - * * `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. - * * `ownSemicolon`: contains `true` if there is semicolon after rule. - * - * PostCSS cleans selectors from comments and extra spaces, - * but it stores origin content in raws properties. - * As such, if you don’t change a declaration’s value, - * PostCSS will use the raw value with comments. - * - * @example - * const root = postcss.parse('a {\n color:black\n}') - * root.first.first.raws //=> { before: '', between: ' ', after: '\n' } - */ -} - -export default Rule diff --git a/lib/rule.js b/lib/rule.js new file mode 100644 index 000000000..a93ab25bf --- /dev/null +++ b/lib/rule.js @@ -0,0 +1,27 @@ +'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) diff --git a/lib/stringifier.d.ts b/lib/stringifier.d.ts new file mode 100644 index 000000000..f707a6aa3 --- /dev/null +++ b/lib/stringifier.d.ts @@ -0,0 +1,46 @@ +import { + 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 diff --git a/lib/stringifier.es6 b/lib/stringifier.js similarity index 81% rename from lib/stringifier.es6 rename to lib/stringifier.js index 3180599fe..e07ad12e7 100644 --- a/lib/stringifier.es6 +++ b/lib/stringifier.js @@ -1,62 +1,30 @@ +'use strict' + const DEFAULT_RAW = { - colon: ': ', - indent: ' ', - beforeDecl: '\n', - beforeRule: '\n', - beforeOpen: ' ', + after: '\n', beforeClose: '\n', beforeComment: '\n', - after: '\n', - emptyBody: '', + beforeDecl: '\n', + beforeOpen: ' ', + beforeRule: '\n', + colon: ': ', commentLeft: ' ', commentRight: ' ', + emptyBody: '', + indent: ' ', semicolon: false } -function capitalize (str) { +function capitalize(str) { return str[0].toUpperCase() + str.slice(1) } class Stringifier { - constructor (builder) { + constructor(builder) { this.builder = builder } - stringify (node, semicolon) { - this[node.type](node, semicolon) - } - - root (node) { - this.body(node) - if (node.raws.after) this.builder(node.raws.after) - } - - 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) - } - - rule (node) { - this.block(node, this.rawValue(node, 'selector')) - if (node.raws.ownSemicolon) { - this.builder(node.raws.ownSemicolon, node, 'end') - } - } - - atrule (node, semicolon) { + atrule(node, semicolon) { let name = '@' + node.name let params = node.params ? this.rawValue(node, 'params') : '' @@ -74,23 +42,36 @@ class Stringifier { } } - body (node) { - let last = node.nodes.length - 1 - while (last > 0) { - if (node.nodes[last].type !== 'comment') break - last -= 1 + 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 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) + 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) { + block(node, start) { let between = this.raw(node, 'between', 'beforeOpen') this.builder(start + between + '{', node, 'start') @@ -106,7 +87,45 @@ class Stringifier { this.builder('}', node, 'end') } - raw (node, own, detect) { + 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 @@ -118,11 +137,16 @@ class Stringifier { let parent = node.parent - // Hack for first rule in CSS 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 @@ -130,7 +154,7 @@ class Stringifier { // Detect style by other nodes let root = node.root() - if (!root.rawCache) root.rawCache = { } + if (!root.rawCache) root.rawCache = {} if (typeof root.rawCache[detect] !== 'undefined') { return root.rawCache[detect] } @@ -155,51 +179,29 @@ class Stringifier { 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 - } - - 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 + rawBeforeClose(root) { 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, '') + 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) { + rawBeforeComment(root, node) { let value root.walkComments(i => { if (typeof i.raws.before !== 'undefined') { value = i.raws.before - if (value.indexOf('\n') !== -1) { + if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false @@ -208,17 +210,17 @@ class Stringifier { if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeDecl') } else if (value) { - value = value.replace(/[^\s]/g, '') + value = value.replace(/\S/g, '') } return value } - rawBeforeDecl (root, node) { + rawBeforeDecl(root, node) { let value root.walkDecls(i => { if (typeof i.raws.before !== 'undefined') { value = i.raws.before - if (value.indexOf('\n') !== -1) { + if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false @@ -227,97 +229,90 @@ class Stringifier { if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeRule') } else if (value) { - value = value.replace(/[^\s]/g, '') + value = value.replace(/\S/g, '') } return value } - rawBeforeRule (root) { + 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.indexOf('\n') !== -1) { + if (value.includes('\n')) { value = value.replace(/[^\n]+$/, '') } return false } } }) - if (value) value = value.replace(/[^\s]/g, '') + if (value) value = value.replace(/\S/g, '') return value } - rawBeforeClose (root) { + rawColon(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.indexOf('\n') !== -1) { - value = value.replace(/[^\n]+$/, '') - } - return false - } + root.walkDecls(i => { + if (typeof i.raws.between !== 'undefined') { + value = i.raws.between.replace(/[^\s:]/g, '') + return false } }) - if (value) value = value.replace(/[^\s]/g, '') return value } - rawBeforeOpen (root) { + rawEmptyBody(root) { let value root.walk(i => { - if (i.type !== 'decl') { - value = i.raws.between + if (i.nodes && i.nodes.length === 0) { + value = i.raws.after if (typeof value !== 'undefined') return false } }) return value } - rawColon (root) { + rawIndent(root) { + if (root.raws.indent) return root.raws.indent let value - root.walkDecls(i => { - if (typeof i.raws.between !== 'undefined') { - value = i.raws.between.replace(/[^\s:]/g, '') - return false + 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 } - beforeAfter (node, detect) { + rawSemicolon(root) { 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.indexOf('\n') !== -1) { - let indent = this.raw(node, null, 'indent') - if (indent.length) { - for (let step = 0; step < depth; step++) value += indent + 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) { + rawValue(node, prop) { let value = node[prop] let raw = node.raws[prop] if (raw && raw.value === value) { @@ -326,6 +321,33 @@ class Stringifier { 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) + } } -export default Stringifier +module.exports = Stringifier +Stringifier.default = Stringifier diff --git a/lib/stringify.d.ts b/lib/stringify.d.ts new file mode 100644 index 000000000..06ad0b4de --- /dev/null +++ b/lib/stringify.d.ts @@ -0,0 +1,9 @@ +import { Stringifier } from './postcss.js' + +interface Stringify extends Stringifier { + default: Stringify +} + +declare const stringify: Stringify + +export = stringify diff --git a/lib/stringify.es6 b/lib/stringify.es6 deleted file mode 100644 index bea29b0f2..000000000 --- a/lib/stringify.es6 +++ /dev/null @@ -1,8 +0,0 @@ -import Stringifier from './stringifier' - -function stringify (node, builder) { - let str = new Stringifier(builder) - str.stringify(node) -} - -export default stringify diff --git a/lib/stringify.js b/lib/stringify.js new file mode 100644 index 000000000..77bd0178b --- /dev/null +++ b/lib/stringify.js @@ -0,0 +1,11 @@ +'use strict' + +let Stringifier = require('./stringifier') + +function stringify(node, builder) { + let str = new Stringifier(builder) + str.stringify(node) +} + +module.exports = stringify +stringify.default = stringify diff --git a/lib/symbols.js b/lib/symbols.js new file mode 100644 index 000000000..a142c268d --- /dev/null +++ b/lib/symbols.js @@ -0,0 +1,5 @@ +'use strict' + +module.exports.isClean = Symbol('isClean') + +module.exports.my = Symbol('my') diff --git a/lib/terminal-highlight.es6 b/lib/terminal-highlight.js similarity index 50% rename from lib/terminal-highlight.es6 rename to lib/terminal-highlight.js index 10816cb2f..6196c9df1 100644 --- a/lib/terminal-highlight.es6 +++ b/lib/terminal-highlight.js @@ -1,27 +1,34 @@ -import chalk from 'chalk' +'use strict' -import tokenizer from './tokenize' -import Input from './input' +let pico = require('picocolors') + +let tokenizer = require('./tokenize') + +let Input + +function registerInput(dependant) { + Input = dependant +} const HIGHLIGHT_THEME = { - 'brackets': chalk.cyan, - 'at-word': chalk.cyan, - 'comment': chalk.gray, - 'string': chalk.green, - 'class': chalk.yellow, - 'call': chalk.cyan, - 'hash': chalk.magenta, - '(': chalk.cyan, - ')': chalk.cyan, - '{': chalk.yellow, - '}': chalk.yellow, - '[': chalk.yellow, - ']': chalk.yellow, - ':': chalk.yellow, - ';': chalk.yellow + ';': 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) { +function getTokenType([type, value], processor) { if (type === 'word') { if (value[0] === '.') { return 'class' @@ -40,14 +47,15 @@ function getTokenType ([type, value], processor) { return type } -function terminalHighlight (css) { +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/) + result += token[1] + .split(/\r?\n/) .map(i => color(i)) .join('\n') } else { @@ -57,4 +65,6 @@ function terminalHighlight (css) { return result } -export default terminalHighlight +terminalHighlight.registerInput = registerInput + +module.exports = terminalHighlight diff --git a/lib/tokenize.es6 b/lib/tokenize.js similarity index 61% rename from lib/tokenize.es6 rename to lib/tokenize.js index 934281a34..39a20a37d 100644 --- a/lib/tokenize.es6 +++ b/lib/tokenize.js @@ -1,4 +1,6 @@ -const SINGLE_QUOTE = '\''.charCodeAt(0) +'use strict' + +const SINGLE_QUOTE = "'".charCodeAt(0) const DOUBLE_QUOTE = '"'.charCodeAt(0) const BACKSLASH = '\\'.charCodeAt(0) const SLASH = '/'.charCodeAt(0) @@ -18,66 +20,53 @@ const ASTERISK = '*'.charCodeAt(0) const COLON = ':'.charCodeAt(0) const AT = '@'.charCodeAt(0) -const RE_AT_END = /[ \n\t\r\f{}()'"\\;/[\]#]/g -const RE_WORD_END = /[ \n\t\r\f(){}:;@!'"\\\][#]|\/(?=\*)/g -const RE_BAD_BRACKET = /.[\\/("'\n]/ -const RE_HEX_ESCAPE = /[a-f0-9]/i +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 -export default function tokenizer (input, options = {}) { +module.exports = function tokenizer(input, options = {}) { let css = input.css.valueOf() let ignore = options.ignoreErrors - let code, next, quote, lines, last, content, escape - let nextLine, nextOffset, escaped, escapePos, prev, n, currentToken + let code, next, quote, content, escape + let escaped, escapePos, prev, n, currentToken let length = css.length - let offset = -1 - let line = 1 let pos = 0 let buffer = [] let returned = [] - function position () { + function position() { return pos } - function unclosed (what) { - throw input.error('Unclosed ' + what, line, pos - offset) + function unclosed(what) { + throw input.error('Unclosed ' + what, pos) } - function endOfFile () { + function endOfFile() { return returned.length === 0 && pos >= length } - function nextToken (opts) { + function nextToken(opts) { if (returned.length) return returned.pop() if (pos >= length) return let ignoreUnclosed = opts ? opts.ignoreUnclosed : false code = css.charCodeAt(pos) - if ( - code === NEWLINE || code === FEED || - (code === CR && css.charCodeAt(pos + 1) !== NEWLINE) - ) { - offset = pos - line += 1 - } switch (code) { case NEWLINE: case SPACE: case TAB: case CR: - case FEED: + case FEED: { next = pos do { next += 1 code = css.charCodeAt(next) - if (code === NEWLINE) { - offset = next - line += 1 - } } while ( code === SPACE || code === NEWLINE || @@ -89,6 +78,7 @@ export default function tokenizer (input, options = {}) { currentToken = ['space', css.slice(pos, next)] pos = next - 1 break + } case OPEN_SQUARE: case CLOSE_SQUARE: @@ -96,19 +86,24 @@ export default function tokenizer (input, options = {}) { case CLOSE_CURLY: case COLON: case SEMICOLON: - case CLOSE_PARENTHESES: + case CLOSE_PARENTHESES: { let controlChar = String.fromCharCode(code) - currentToken = [controlChar, controlChar, line, pos - offset] + currentToken = [controlChar, controlChar, pos] break + } - case OPEN_PARENTHESES: + 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 + n !== SINGLE_QUOTE && + n !== DOUBLE_QUOTE && + n !== SPACE && + n !== NEWLINE && + n !== TAB && + n !== FEED && + n !== CR ) { next = pos do { @@ -129,10 +124,7 @@ export default function tokenizer (input, options = {}) { } } while (escaped) - currentToken = ['brackets', css.slice(pos, next + 1), - line, pos - offset, - line, next - offset - ] + currentToken = ['brackets', css.slice(pos, next + 1), pos, next] pos = next } else { @@ -140,21 +132,19 @@ export default function tokenizer (input, options = {}) { content = css.slice(pos, next + 1) if (next === -1 || RE_BAD_BRACKET.test(content)) { - currentToken = ['(', '(', line, pos - offset] + currentToken = ['(', '(', pos] } else { - currentToken = ['brackets', content, - line, pos - offset, - line, next - offset - ] + currentToken = ['brackets', content, pos, next] pos = next } } break + } case SINGLE_QUOTE: - case DOUBLE_QUOTE: - quote = code === SINGLE_QUOTE ? '\'' : '"' + case DOUBLE_QUOTE: { + quote = code === SINGLE_QUOTE ? "'" : '"' next = pos do { escaped = false @@ -174,29 +164,12 @@ export default function tokenizer (input, options = {}) { } } while (escaped) - content = css.slice(pos, next + 1) - lines = content.split('\n') - last = lines.length - 1 - - if (last > 0) { - nextLine = line + last - nextOffset = next - lines[last].length - } else { - nextLine = line - nextOffset = offset - } - - currentToken = ['string', css.slice(pos, next + 1), - line, pos - offset, - nextLine, next - nextOffset - ] - - offset = nextOffset - line = nextLine + currentToken = ['string', css.slice(pos, next + 1), pos, next] pos = next break + } - case AT: + case AT: { RE_AT_END.lastIndex = pos + 1 RE_AT_END.test(css) if (RE_AT_END.lastIndex === 0) { @@ -205,15 +178,13 @@ export default function tokenizer (input, options = {}) { next = RE_AT_END.lastIndex - 2 } - currentToken = ['at-word', css.slice(pos, next + 1), - line, pos - offset, - line, next - offset - ] + currentToken = ['at-word', css.slice(pos, next + 1), pos, next] pos = next break + } - case BACKSLASH: + case BACKSLASH: { next = pos escape = true while (css.charCodeAt(next + 1) === BACKSLASH) { @@ -241,15 +212,13 @@ export default function tokenizer (input, options = {}) { } } - currentToken = ['word', css.slice(pos, next + 1), - line, pos - offset, - line, next - offset - ] + currentToken = ['word', css.slice(pos, next + 1), pos, next] pos = next break + } - default: + default: { if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { next = css.indexOf('*/', pos + 2) + 1 if (next === 0) { @@ -260,25 +229,7 @@ export default function tokenizer (input, options = {}) { } } - content = css.slice(pos, next + 1) - lines = content.split('\n') - last = lines.length - 1 - - if (last > 0) { - nextLine = line + last - nextOffset = next - lines[last].length - } else { - nextLine = line - nextOffset = offset - } - - currentToken = ['comment', content, - line, pos - offset, - nextLine, next - nextOffset - ] - - offset = nextOffset - line = nextLine + currentToken = ['comment', css.slice(pos, next + 1), pos, next] pos = next } else { RE_WORD_END.lastIndex = pos + 1 @@ -289,31 +240,27 @@ export default function tokenizer (input, options = {}) { next = RE_WORD_END.lastIndex - 2 } - currentToken = ['word', css.slice(pos, next + 1), - line, pos - offset, - line, next - offset - ] - + currentToken = ['word', css.slice(pos, next + 1), pos, next] buffer.push(currentToken) - pos = next } break + } } pos++ return currentToken } - function back (token) { + function back(token) { returned.push(token) } return { back, - nextToken, endOfFile, + nextToken, position } } diff --git a/lib/vendor.es6 b/lib/vendor.es6 deleted file mode 100644 index 515bba2c2..000000000 --- a/lib/vendor.es6 +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Contains helpers for working with vendor prefixes. - * - * @example - * const vendor = postcss.vendor - * - * @namespace vendor - */ -let vendor = { - - /** - * Returns the vendor prefix extracted from an input string. - * - * @param {string} prop String with or without vendor prefix. - * - * @return {string} vendor prefix or empty string - * - * @example - * postcss.vendor.prefix('-moz-tab-size') //=> '-moz-' - * postcss.vendor.prefix('tab-size') //=> '' - */ - prefix (prop) { - let match = prop.match(/^(-\w+-)/) - if (match) { - return match[0] - } - - return '' - }, - - /** - * Returns the input string stripped of its vendor prefix. - * - * @param {string} prop String with or without vendor prefix. - * - * @return {string} String name without vendor prefixes. - * - * @example - * postcss.vendor.unprefixed('-moz-tab-size') //=> 'tab-size' - */ - unprefixed (prop) { - return prop.replace(/^-\w+-/, '') - } - -} - -export default vendor diff --git a/lib/warn-once.es6 b/lib/warn-once.js similarity index 57% rename from lib/warn-once.es6 rename to lib/warn-once.js index 98386993b..316e1cf46 100644 --- a/lib/warn-once.es6 +++ b/lib/warn-once.js @@ -1,6 +1,9 @@ -let printed = { } +/* eslint-disable no-console */ +'use strict' -export default function warnOnce (message) { +let printed = {} + +module.exports = function warnOnce(message) { if (printed[message]) return printed[message] = true diff --git a/lib/warning.d.ts b/lib/warning.d.ts new file mode 100644 index 000000000..b25bba816 --- /dev/null +++ b/lib/warning.d.ts @@ -0,0 +1,147 @@ +import { 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 diff --git a/lib/warning.es6 b/lib/warning.es6 deleted file mode 100644 index aabdb1406..000000000 --- a/lib/warning.es6 +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Represents a plugin’s warning. It can be created using {@link Node#warn}. - * - * @example - * if (decl.important) { - * decl.warn(result, 'Avoid !important', { word: '!important' }) - * } - */ -class Warning { - /** - * @param {string} text Warning message. - * @param {Object} [opts] Warning options. - * @param {Node} opts.node CSS node that caused the warning. - * @param {string} opts.word Word in CSS source that caused the warning. - * @param {number} opts.index Index in CSS node string that caused - * the warning. - * @param {string} opts.plugin Name of the plugin that created - * this warning. {@link Result#warn} fills - * this property automatically. - */ - constructor (text, opts = { }) { - /** - * Type to filter warnings from {@link Result#messages}. - * Always equal to `"warning"`. - * - * @type {string} - * - * @example - * const nonWarning = result.messages.filter(i => i.type !== 'warning') - */ - this.type = 'warning' - /** - * The warning message. - * - * @type {string} - * - * @example - * warning.text //=> 'Try to avoid !important' - */ - this.text = text - - if (opts.node && opts.node.source) { - let pos = opts.node.positionBy(opts) - /** - * Line in the input file with this warning’s source. - * @type {number} - * - * @example - * warning.line //=> 5 - */ - this.line = pos.line - /** - * Column in the input file with this warning’s source. - * - * @type {number} - * - * @example - * warning.column //=> 6 - */ - this.column = pos.column - } - - for (let opt in opts) this[opt] = opts[opt] - } - - /** - * Returns a warning position and message. - * - * @example - * warning.toString() //=> 'postcss-lint:a.css:10:14: Avoid !important' - * - * @return {string} Warning position and message. - */ - toString () { - if (this.node) { - return this.node.error(this.text, { - plugin: this.plugin, - index: this.index, - word: this.word - }).message - } - - if (this.plugin) { - return this.plugin + ': ' + this.text - } - - return this.text - } - - /** - * @memberof Warning# - * @member {string} plugin The name of the plugin that created - * it will fill this property automatically. - * this warning. When you call {@link Node#warn} - * - * @example - * warning.plugin //=> 'postcss-important' - */ - - /** - * @memberof Warning# - * @member {Node} node Contains the CSS node that caused the warning. - * - * @example - * warning.node.toString() //=> 'color: white !important' - */ -} - -export default Warning diff --git a/lib/warning.js b/lib/warning.js new file mode 100644 index 000000000..3a3d79c93 --- /dev/null +++ b/lib/warning.js @@ -0,0 +1,37 @@ +'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 diff --git a/package.json b/package.json old mode 100644 new mode 100755 index ca383d90f..5c6e5fee4 --- a/package.json +++ b/package.json @@ -1,10 +1,46 @@ { "name": "postcss", - "version": "7.0.36", + "version": "8.4.31", "description": "Tool for transforming styles with JS plugins", "engines": { - "node": ">=6.0.0" + "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", @@ -17,428 +53,137 @@ "transpiler" ], "scripts": { - "lint": "eslint-ci *.js lib/*.es6 test/*.js", - "test": "gulp && jest && yarn lint" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "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": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" }, "devDependencies": { - "@babel/core": "^7.11.6", - "@babel/preset-env": "^7.11.5", - "@logux/eslint-config": "^28.1.0", - "babel-eslint": "^10.1.0", - "babel-plugin-add-module-exports": "^1.0.4", + "@logux/eslint-config": "^52.0.1", + "@size-limit/preset-small-lib": "^9.0.0", + "@types/node": "^20.7.1", + "@typescript-eslint/eslint-plugin": "^6.7.3", + "@typescript-eslint/parser": "^6.7.3", + "c8": "^8.0.1", + "check-dts": "^0.7.2", + "clean-publish": "^4.2.0", "concat-with-sourcemaps": "^1.1.0", - "del": "^4.1.0", - "eslint": "^5.16.0", - "eslint-ci": "^1.0.0", - "eslint-config-postcss": "^3.0.7", - "eslint-config-standard": "^12.0.0", - "eslint-plugin-import": "^2.16.0", - "eslint-plugin-import-helpers": "^0.1.4", - "eslint-plugin-jest": "^22.4.1", - "eslint-plugin-node": "^8.0.1", - "eslint-plugin-prefer-let": "^1.0.1", - "eslint-plugin-promise": "^4.1.1", - "eslint-plugin-security": "^1.4.0", - "eslint-plugin-standard": "^4.0.0", - "fs-extra": "^7.0.1", - "gulp": "^4.0.0", - "gulp-babel": "^8.0.0", - "gulp-changed": "^3.2.0", - "gulp-json-editor": "^2.5.1", - "gulp-sourcemaps": "^2.6.5", - "husky": "^1.3.1", - "jest": "^24.7.1", - "jest-cli": "^24.7.1", - "lint-staged": "^8.1.5", - "postcss-parser-tests": "6.3.1", - "run-sequence": "^2.2.1", - "strip-ansi": "^5.2.0", - "yaspeller": "^7.0.0" + "eslint": "^8.50.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-n": "^16.1.0", + "eslint-plugin-perfectionist": "^2.1.0", + "eslint-plugin-prefer-let": "^3.0.1", + "eslint-plugin-promise": "^6.1.1", + "nanodelay": "^1.0.8", + "nanospy": "^1.0.0", + "postcss-parser-tests": "^8.8.0", + "simple-git-hooks": "^2.9.0", + "size-limit": "^9.0.0", + "strip-ansi": "^6.0.1", + "ts-node": "^10.9.1", + "typescript": "^5.2.2", + "uvu": "^0.5.6" }, - "main": "lib/postcss", - "types": "lib/postcss.d.ts", - "lint-staged": { - "test/*.js": "eslint", - "lib/*.es6": "eslint", - "*.md": "yaspeller" + "c8": { + "exclude": [ + "**/*.test.*", + "lib/map-generator.js" + ], + "lines": 100, + "reporter": "lcov", + "check-coverage": true }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } + "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, - "supports-color": false, - "chalk": false, + "source-map-js": false, + "path": false, + "url": false, "fs": false }, - "browserslist": [ - "and_chr 71", - "and_ff 64", - "and_qq 1.2", - "and_uc 11.8", - "android 67", - "android 4.4.3-4.4.4", - "baidu 7.12", - "chrome 73", - "chrome 72", - "edge 18", - "edge 17", - "firefox 66", - "firefox 65", - "ios_saf 12.0-12.1", - "ios_saf 11.3-11.4", - "node 6.17.0", - "op_mini all", - "op_mob 46", - "opera 58", - "opera 57", - "safari 12", - "safari 11.1", - "samsung 8.2", - "samsung 7.2-7.4" + "size-limit": [ + { + "path": "lib/postcss.js", + "limit": "17 KB" + } ], - "babel": { - "presets": [ - [ - "@babel/env", - { - "loose": true - } - ] - ], - "plugins": [ - "add-module-exports" - ] - }, - "jest": { - "testEnvironment": "node", - "modulePathIgnorePatterns": [ - "/build" - ] - }, "eslintConfig": { - "parser": "babel-eslint", - "parserOptions": { - "sourceType": "module" - }, - "extends": "eslint-config-postcss", + "extends": "@logux/eslint-config/ts", "rules": { - "node/no-unsupported-features/es-syntax": [ - "error", - { - "ignores": [ - "modules" - ] - } - ], + "@typescript-eslint/consistent-type-imports": "off", + "@typescript-eslint/no-explicit-any": "off", + "node-import/prefer-node-protocol": "off", "consistent-return": "off", "global-require": "off" }, - "env": { - "browser": true - }, "overrides": [ { "files": [ - "gulpfile.js" + "*.d.ts" ], "rules": { - "node/no-unpublished-require": "off", - "global-require": "off" + "@typescript-eslint/no-redeclare": "off" } }, { "files": [ - "*.test.js" + "*.test.*" ], "rules": { + "@typescript-eslint/no-unused-expressions": "off", "no-unused-expressions": "off", + "no-console": "off", "func-style": "off" } } ] }, - "yaspeller": { - "lang": "en", - "format": "markdown", - "fileExtensions": [ - ".md" - ], - "excludeFiles": [ - ".git", - "node_modules", - "build", - "api/*.es6.html", - "README-cn.md" - ], - "ignoreText": [ - " \\(by [^)]+\\)." - ], - "ignoreCapitalization": true, - "dictionary": [ - "6to5", - "ASE", - "AtCSS", - "Autoprefixer", - "Base64", - "cssnano", - "Browserhacks", - "CoffeeScript", - "GitHub", - "JetBrains", - "WebStorm", - "Traceur", - "PostCSS", - "PostCSS’s", - "postcss", - "Shopify", - "Instagram", - "Travis", - "poststylus", - "Gofmt", - "CI", - "MD5", - "W3C", - "WebP", - "VK", - "IE8", - "IE9", - "ES5", - "ES6", - "ENB", - "Vapula", - "Zagan", - "SemVer", - "Sass", - "Sass’s", - "SCSS", - "Weibo", - "PreCSS", - "libsass", - "CSSOM", - "Popp", - "Jeet", - "Modernizr", - "npm", - "webpack", - "Amdusias", - "Anton", - "Alexey", - "Andres", - "Andromalius", - "Andrealphus", - "Andalusian", - "Andras", - "asan", - "Lind", - "Zuo", - "Jed", - "Neal", - "Valac", - "Vue", - "Briggs", - "Bogdan", - "Chadkin", - "ClojureWerkz’s", - "Dantalion", - "Montoro", - "Decarabia", - "Dvornov", - "Efremov", - "Flauros", - "Josiah", - "Lydell", - "Locati", - "Lolspeak", - "Matija", - "Marohnić", - "Maxime", - "Michele", - "Mohammad", - "Nikitenko", - "Savary", - "Seere", - "Suarez", - "Thirouin", - "Peterson", - "Yakushev", - "Younes", - "Cimeies", - "Autodetect", - "autodetect", - "codebases", - "flexbox", - "unprefixes", - "regexp", - "changelog", - "Changelog", - "Transpiler", - "transpiler", - "transpile", - "transpiles", - "transpiling", - "tokenize", - "tokenizer", - "linter", - "linters", - "CamelCase", - "rebases", - "resolver", - "minifier", - "isolatable", - "minifiers", - "mixins", - "mixin", - "multitool", - "io", - "partials", - "inlined", - "inlines", - "polyfill", - "stylesheet", - "stylesheets", - "stringifier", - "keyframes", - "BEM", - "CLI", - "CSS3", - "CSS4", - "SugarSS", - "SVG", - "SVGO", - "Markdown", - "JS", - "js", - "vs", - "pantone", - "YIQ", - "gitter", - "evilmartians", - "Less’s", - "visualizer", - "Rollup", - "AtRule", - "CssSyntaxError", - "LazyResult", - "RegExp", - "atRule", - "childIterator", - "cloneAfter", - "cloneBefore", - "docdash", - "withContent", - "walkRules", - "walkDecls", - "walkComments", - "unprefixed", - "toResult", - "showSourceCode", - "replaceWith", - "replaceValues", - "removeChild", - "removeAll", - "prepend", - "params", - "insertBefore", - "insertAfter", - "decl", - "es6", - "stringify", - "defaultType", - "newParent", - "otherNode", - "SourceMapGenerator", - "onFulfilled", - "onRejected", - "onFinally", - "base64", - "stringifing", - "Browserify", - "CodePen", - "LTS", - "Garet", - "McKinley", - "Semigradsky", - "janschoenherr", - "bumbleblym", - "Packt", - "Libby", - "LTR", - "RTL", - "Orias", - "Oleh", - "Kuchuk", - "Kalani", - "Adamenko", - "Eppstein", - "Taskr", - "AST", - "EOL", - "Keller", - "Sylvain", - "Pollet", - "Villard", - "Schiffer", - "Cavit", - "Nikhil", - "Gaba", - "Kamyshev", - "cleanRaws", - "keepBetween", - "Steven", - "Rui", - "Pedro", - "Versioning", - "JSDoc", - "PreviousMap", - "walkAtRules", - "tokenization", - "childCondition", - "filePosition", - "pluginFunction", - "processOptions", - "is SCSS", - "SVGs", - "polyfills", - "replaces EOL", - "JSS", - "sanitization", - "A CI", - "Browserify or", - "as ES6", - "extendability", - "Powell", - "RTLCSS", - "Gilad", - "Peleg", - "Veniamin", - "Krol", - "Ankur", - "Oberoi", - "Niklas", - "Mischkulnig", - "Tidelift", - "Solovev", - "VS", - "iOS", - "maintainers", - "Backport", - "ReDoS" - ] + "eslintIgnore": [ + "docs/api/assets/", + "errors.ts" + ], + "clean-publish": { + "cleanDocs": true } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..b15e52df1 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2624 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + nanoid: + specifier: ^3.3.6 + version: 3.3.6 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + source-map-js: + specifier: ^1.0.2 + version: 1.0.2 + +devDependencies: + '@logux/eslint-config': + specifier: ^52.0.1 + version: 52.0.1(eslint-config-standard@17.1.0)(eslint-plugin-import@2.28.1)(eslint-plugin-n@16.1.0)(eslint-plugin-node-import@1.0.4)(eslint-plugin-perfectionist@2.1.0)(eslint-plugin-prefer-let@3.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.50.0) + '@size-limit/preset-small-lib': + specifier: ^9.0.0 + version: 9.0.0(size-limit@9.0.0) + '@types/node': + specifier: ^20.7.1 + version: 20.7.1 + '@typescript-eslint/eslint-plugin': + specifier: ^6.7.3 + version: 6.7.3(@typescript-eslint/parser@6.7.3)(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/parser': + specifier: ^6.7.3 + version: 6.7.3(eslint@8.50.0)(typescript@5.2.2) + c8: + specifier: ^8.0.1 + version: 8.0.1 + check-dts: + specifier: ^0.7.2 + version: 0.7.2(typescript@5.2.2) + clean-publish: + specifier: ^4.2.0 + version: 4.2.0 + concat-with-sourcemaps: + specifier: ^1.1.0 + version: 1.1.0 + eslint: + specifier: ^8.50.0 + version: 8.50.0 + eslint-config-standard: + specifier: ^17.1.0 + version: 17.1.0(eslint-plugin-import@2.28.1)(eslint-plugin-n@16.1.0)(eslint-plugin-promise@6.1.1)(eslint@8.50.0) + eslint-plugin-import: + specifier: ^2.28.1 + version: 2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0) + eslint-plugin-n: + specifier: ^16.1.0 + version: 16.1.0(eslint@8.50.0) + eslint-plugin-perfectionist: + specifier: ^2.1.0 + version: 2.1.0(eslint@8.50.0)(typescript@5.2.2) + eslint-plugin-prefer-let: + specifier: ^3.0.1 + version: 3.0.1 + eslint-plugin-promise: + specifier: ^6.1.1 + version: 6.1.1(eslint@8.50.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.9.0 + version: 2.9.0 + size-limit: + specifier: ^9.0.0 + version: 9.0.0 + strip-ansi: + specifier: ^6.0.1 + version: 6.0.1 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.7.1)(typescript@5.2.2) + typescript: + specifier: ^5.2.2 + version: 5.2.2 + uvu: + specifier: ^0.5.6 + version: 0.5.6 + +packages: + + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@esbuild/android-arm64@0.19.4: + resolution: {integrity: sha512-mRsi2vJsk4Bx/AFsNBqOH2fqedxn5L/moT58xgg51DjX1la64Z3Npicut2VbhvDFO26qjWtPMsVxCd80YTFVeg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.19.4: + resolution: {integrity: sha512-uBIbiYMeSsy2U0XQoOGVVcpIktjLMEKa7ryz2RLr7L/vTnANNEsPVAh4xOv7ondGz6ac1zVb0F8Jx20rQikffQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.19.4: + resolution: {integrity: sha512-4iPufZ1TMOD3oBlGFqHXBpa3KFT46aLl6Vy7gwed0ZSYgHaZ/mihbYb4t7Z9etjkC9Al3ZYIoOaHrU60gcMy7g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.19.4: + resolution: {integrity: sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.19.4: + resolution: {integrity: sha512-YHbSFlLgDwglFn0lAO3Zsdrife9jcQXQhgRp77YiTDja23FrC2uwnhXMNkAucthsf+Psr7sTwYEryxz6FPAVqw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.4: + resolution: {integrity: sha512-vz59ijyrTG22Hshaj620e5yhs2dU1WJy723ofc+KUgxVCM6zxQESmWdMuVmUzxtGqtj5heHyB44PjV/HKsEmuQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.4: + resolution: {integrity: sha512-3sRbQ6W5kAiVQRBWREGJNd1YE7OgzS0AmOGjDmX/qZZecq8NFlQsQH0IfXjjmD0XtUYqr64e0EKNFjMUlPL3Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.4: + resolution: {integrity: sha512-ZWmWORaPbsPwmyu7eIEATFlaqm0QGt+joRE9sKcnVUG3oBbr/KYdNE2TnkzdQwX6EDRdg/x8Q4EZQTXoClUqqA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.4: + resolution: {integrity: sha512-z/4ArqOo9EImzTi4b6Vq+pthLnepFzJ92BnofU1jgNlcVb+UqynVFdoXMCFreTK7FdhqAzH0vmdwW5373Hm9pg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.4: + resolution: {integrity: sha512-EGc4vYM7i1GRUIMqRZNCTzJh25MHePYsnQfKDexD8uPTCm9mK56NIL04LUfX2aaJ+C9vyEp2fJ7jbqFEYgO9lQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.4: + resolution: {integrity: sha512-WVhIKO26kmm8lPmNrUikxSpXcgd6HDog0cx12BUfA2PkmURHSgx9G6vA19lrlQOMw+UjMZ+l3PpbtzffCxFDRg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.4: + resolution: {integrity: sha512-keYY+Hlj5w86hNp5JJPuZNbvW4jql7c1eXdBUHIJGTeN/+0QFutU3GrS+c27L+NTmzi73yhtojHk+lr2+502Mw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.4: + resolution: {integrity: sha512-tQ92n0WMXyEsCH4m32S21fND8VxNiVazUbU4IUGVXQpWiaAxOBvtOtbEt3cXIV3GEBydYsY8pyeRMJx9kn3rvw==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.4: + resolution: {integrity: sha512-tRRBey6fG9tqGH6V75xH3lFPpj9E8BH+N+zjSUCnFOX93kEzqS0WdyJHkta/mmJHn7MBaa++9P4ARiU4ykjhig==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.4: + resolution: {integrity: sha512-152aLpQqKZYhThiJ+uAM4PcuLCAOxDsCekIbnGzPKVBRUDlgaaAfaUl5NYkB1hgY6WN4sPkejxKlANgVcGl9Qg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.4: + resolution: {integrity: sha512-Mi4aNA3rz1BNFtB7aGadMD0MavmzuuXNTaYL6/uiYIs08U7YMPETpgNn5oue3ICr+inKwItOwSsJDYkrE9ekVg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.4: + resolution: {integrity: sha512-9+Wxx1i5N/CYo505CTT7T+ix4lVzEdz0uCoYGxM5JDVlP2YdDC1Bdz+Khv6IbqmisT0Si928eAxbmGkcbiuM/A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.4: + resolution: {integrity: sha512-MFsHleM5/rWRW9EivFssop+OulYVUoVcqkyOkjiynKBCGBj9Lihl7kh9IzrreDyXa4sNkquei5/DTP4uCk25xw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.4: + resolution: {integrity: sha512-6Xq8SpK46yLvrGxjp6HftkDwPP49puU4OF0hEL4dTxqCbfx09LyrbUj/D7tmIRMj5D5FCUPksBbxyQhp8tmHzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.4: + resolution: {integrity: sha512-PkIl7Jq4mP6ke7QKwyg4fD4Xvn8PXisagV/+HntWoDEdmerB2LTukRZg728Yd1Fj+LuEX75t/hKXE2Ppk8Hh1w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.4: + resolution: {integrity: sha512-ga676Hnvw7/ycdKB53qPusvsKdwrWzEyJ+AtItHGoARszIqvjffTwaaW3b2L6l90i7MO9i+dlAW415INuRhSGg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.4: + resolution: {integrity: sha512-HP0GDNla1T3ZL8Ko/SHAS2GgtjOg+VmWnnYLhuTksr++EnduYB0f3Y2LzHsUwb2iQ13JGoY6G3R8h6Du/WG6uA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.50.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.50.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.9.0: + resolution: {integrity: sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.22.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.50.0: + resolution: {integrity: sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.11: + resolution: {integrity: sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.19: + resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@logux/eslint-config@52.0.1(eslint-config-standard@17.1.0)(eslint-plugin-import@2.28.1)(eslint-plugin-n@16.1.0)(eslint-plugin-node-import@1.0.4)(eslint-plugin-perfectionist@2.1.0)(eslint-plugin-prefer-let@3.0.1)(eslint-plugin-promise@6.1.1)(eslint@8.50.0): + resolution: {integrity: sha512-VnphQAsUoP2gdlZScn0jESbeGXA3lyCTlPEPNpDGJU0/75Cmi6YVTQ6/ownBVN6ASAEcql2UcYroseQzv2t2dA==} + engines: {node: '>=10.0.0'} + peerDependencies: + eslint: ^8.48.0 + eslint-config-standard: ^17.1.0 + eslint-plugin-import: ^2.28.1 + eslint-plugin-n: ^16.0.2 + eslint-plugin-node-import: ^1.0.1 + eslint-plugin-perfectionist: ^2.0.0 + eslint-plugin-prefer-let: ^3.0.1 + eslint-plugin-promise: ^6.1.1 + dependencies: + eslint: 8.50.0 + eslint-config-standard: 17.1.0(eslint-plugin-import@2.28.1)(eslint-plugin-n@16.1.0)(eslint-plugin-promise@6.1.1)(eslint@8.50.0) + eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0) + eslint-plugin-n: 16.1.0(eslint@8.50.0) + eslint-plugin-node-import: 1.0.4(eslint@8.50.0) + eslint-plugin-perfectionist: 2.1.0(eslint@8.50.0)(typescript@5.2.2) + eslint-plugin-prefer-let: 3.0.1 + eslint-plugin-promise: 6.1.1(eslint@8.50.0) + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@size-limit/esbuild@9.0.0(size-limit@9.0.0): + resolution: {integrity: sha512-y3NY0inaFeLqV6SRXNVILhawQdQcODxF30qft6OalsrqtQtBjt++6ZeahYhUbrVexUEWRh6c7yPCe8RvHn8hlA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + size-limit: 9.0.0 + dependencies: + esbuild: 0.19.4 + nanoid: 3.3.6 + size-limit: 9.0.0 + dev: true + + /@size-limit/file@9.0.0(size-limit@9.0.0): + resolution: {integrity: sha512-oM2UaH2FRq4q22k+R+P6xCpzET10T94LFdSjb9svVu/vOD7NaB9LGcG6se8TW1BExXiyXO4GEhLsBt3uMKM3qA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + size-limit: 9.0.0 + dependencies: + semver: 7.5.4 + size-limit: 9.0.0 + dev: true + + /@size-limit/preset-small-lib@9.0.0(size-limit@9.0.0): + resolution: {integrity: sha512-nkbZxn12pTpABYVyX5nsjQuLFpn8wDmd2XKoq/MiqKOc3ocz5BBwXTruqTL5ZKDW1OxEAWZMQlxf2kg3kY3X1Q==} + peerDependencies: + size-limit: 9.0.0 + dependencies: + '@size-limit/esbuild': 9.0.0(size-limit@9.0.0) + '@size-limit/file': 9.0.0(size-limit@9.0.0) + size-limit: 9.0.0 + dev: true + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/json-schema@7.0.13: + resolution: {integrity: sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/node@20.7.1: + resolution: {integrity: sha512-LT+OIXpp2kj4E2S/p91BMe+VgGX2+lfO+XTpfXhh+bCk2LkQtHZSub8ewFBMGP5ClysPjTDFa4sMI8Q3n4T0wg==} + dev: true + + /@types/semver@7.5.3: + resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==} + dev: true + + /@types/unist@2.0.8: + resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==} + dev: true + + /@typescript-eslint/eslint-plugin@6.7.3(@typescript-eslint/parser@6.7.3)(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.9.0 + '@typescript-eslint/parser': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.7.3 + '@typescript-eslint/type-utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.7.3 + debug: 4.3.4 + eslint: 8.50.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@6.7.3(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.7.3 + '@typescript-eslint/types': 6.7.3 + '@typescript-eslint/typescript-estree': 6.7.3(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.7.3 + debug: 4.3.4 + eslint: 8.50.0 + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@6.7.3: + resolution: {integrity: sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.7.3 + '@typescript-eslint/visitor-keys': 6.7.3 + dev: true + + /@typescript-eslint/type-utils@6.7.3(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.7.3(typescript@5.2.2) + '@typescript-eslint/utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + debug: 4.3.4 + eslint: 8.50.0 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@6.7.3: + resolution: {integrity: sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: true + + /@typescript-eslint/typescript-estree@6.7.3(typescript@5.2.2): + resolution: {integrity: sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.7.3 + '@typescript-eslint/visitor-keys': 6.7.3 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@6.7.3(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + '@types/json-schema': 7.0.13 + '@types/semver': 7.5.3 + '@typescript-eslint/scope-manager': 6.7.3 + '@typescript-eslint/types': 6.7.3 + '@typescript-eslint/typescript-estree': 6.7.3(typescript@5.2.2) + eslint: 8.50.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@6.7.3: + resolution: {integrity: sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.7.3 + eslint-visitor-keys: 3.4.3 + dev: true + + /acorn-jsx@5.3.2(acorn@8.10.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.10.0 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + 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 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.findlastindex@1.2.3: + resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.2.1 + dev: true + + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + dev: true + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + + /bytes-iec@3.1.1: + resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} + engines: {node: '>= 0.8'} + dev: true + + /c8@8.0.1: + resolution: {integrity: sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==} + engines: {node: '>=12'} + hasBin: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@istanbuljs/schema': 0.1.3 + find-up: 5.0.0 + foreground-child: 2.0.0 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.1.6 + rimraf: 3.0.2 + test-exclude: 6.0.0 + v8-to-istanbul: 9.1.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /check-dts@0.7.2(typescript@5.2.2): + resolution: {integrity: sha512-ZflsEhv7SXlgNECrNIw1WmMJZ1787KtS62anWknLPI+k9g9OY2eA/UfT+Tsb0i0eWLUZHtFfznrNtGlQJrGaKw==} + engines: {node: '>=14.0.0'} + hasBin: true + peerDependencies: + typescript: '>=4.0.0' + dependencies: + fast-glob: 3.3.1 + nanospinner: 1.1.0 + picocolors: 1.0.0 + typescript: 5.2.2 + vfile-location: 4.1.0 + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /clean-publish@4.2.0: + resolution: {integrity: sha512-dqZF5y6KtlkYhbnJoXiOCP4L1TPdI7HtuDysslUrbI8vLPu65ZjVO3pu5xp4qH0X2cWdDN/La04woe6fg4LNSw==} + engines: {node: '>= 16.0.0'} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + fast-glob: 3.3.1 + lilconfig: 2.1.0 + micromatch: 4.0.5 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concat-with-sourcemaps@1.1.0: + resolution: {integrity: sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==} + dependencies: + source-map: 0.6.1 + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /define-data-property@1.1.0: + resolution: {integrity: sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + dev: true + + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.0 + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /es-abstract@1.22.2: + resolution: {integrity: sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.11 + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild@0.19.4: + resolution: {integrity: sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.19.4 + '@esbuild/android-arm64': 0.19.4 + '@esbuild/android-x64': 0.19.4 + '@esbuild/darwin-arm64': 0.19.4 + '@esbuild/darwin-x64': 0.19.4 + '@esbuild/freebsd-arm64': 0.19.4 + '@esbuild/freebsd-x64': 0.19.4 + '@esbuild/linux-arm': 0.19.4 + '@esbuild/linux-arm64': 0.19.4 + '@esbuild/linux-ia32': 0.19.4 + '@esbuild/linux-loong64': 0.19.4 + '@esbuild/linux-mips64el': 0.19.4 + '@esbuild/linux-ppc64': 0.19.4 + '@esbuild/linux-riscv64': 0.19.4 + '@esbuild/linux-s390x': 0.19.4 + '@esbuild/linux-x64': 0.19.4 + '@esbuild/netbsd-x64': 0.19.4 + '@esbuild/openbsd-x64': 0.19.4 + '@esbuild/sunos-x64': 0.19.4 + '@esbuild/win32-arm64': 0.19.4 + '@esbuild/win32-ia32': 0.19.4 + '@esbuild/win32-x64': 0.19.4 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-standard@17.1.0(eslint-plugin-import@2.28.1)(eslint-plugin-n@16.1.0)(eslint-plugin-promise@6.1.1)(eslint@8.50.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 + dependencies: + eslint: 8.50.0 + eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0) + eslint-plugin-n: 16.1.0(eslint@8.50.0) + eslint-plugin-promise: 6.1.1(eslint@8.50.0) + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.0 + resolve: 1.22.6 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.50.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + 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 + dependencies: + '@typescript-eslint/parser': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + debug: 3.2.7 + eslint: 8.50.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-es-x@7.2.0(eslint@8.50.0): + resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + '@eslint-community/regexpp': 4.9.0 + eslint: 8.50.0 + dev: true + + /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0): + resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.50.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.50.0) + has: 1.0.3 + is-core-module: 2.13.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-n@16.1.0(eslint@8.50.0): + resolution: {integrity: sha512-3wv/TooBst0N4ND+pnvffHuz9gNPmk/NkLwAxOt2JykTl/hcuECe6yhTtLJcZjIxtZwN+GX92ACp/QTLpHA3Hg==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + builtins: 5.0.1 + eslint: 8.50.0 + eslint-plugin-es-x: 7.2.0(eslint@8.50.0) + get-tsconfig: 4.7.2 + ignore: 5.2.4 + is-core-module: 2.13.0 + minimatch: 3.1.2 + resolve: 1.22.6 + semver: 7.5.4 + dev: true + + /eslint-plugin-node-import@1.0.4(eslint@8.50.0): + resolution: {integrity: sha512-nn6EkM7+vJCDCXZiM0FDpYSekbhlk5LNoHJm9DlVSucGrsT9WoK+qOxIEm+SwoFBeH73cMHMavioDaHsu22b0Q==} + engines: {node: ^14.18.0 || ^16.0.0 || >= 18.0.0} + peerDependencies: + eslint: '>=7' + dependencies: + eslint: 8.50.0 + dev: true + + /eslint-plugin-perfectionist@2.1.0(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-KVA7H6J/qfmZH/WopNKFgYbKoX+ozKAOIeQvo/+jibn6k9e71Et+giIHEHrMICZ043CeGpRKrCRRhlmD7pjeRg==} + peerDependencies: + astro-eslint-parser: ^0.14.0 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.32.0 + 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 + dependencies: + '@typescript-eslint/utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + eslint: 8.50.0 + minimatch: 9.0.3 + natural-compare-lite: 1.4.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-prefer-let@3.0.1: + resolution: {integrity: sha512-vbznkkBSXB63d4o1o0NIm5C2ey3V5wKr/25dAvPdydQXdowAcnr69cbLgxd2YAG81IV5eddCO55Lp6gL7wSE4w==} + engines: {node: '>=0.10.0'} + dependencies: + requireindex: 1.2.0 + dev: true + + /eslint-plugin-promise@6.1.1(eslint@8.50.0): + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.50.0 + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /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} + dev: true + + /eslint@8.50.0: + resolution: {integrity: sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + '@eslint-community/regexpp': 4.9.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.50.0 + '@humanwhocodes/config-array': 0.11.11 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.22.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.10.0 + acorn-jsx: 5.3.2(acorn@8.10.0) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + 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.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.1.0 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.1.0: + resolution: {integrity: sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==} + engines: {node: '>=12.0.0'} + dependencies: + flatted: 3.2.9 + keyv: 4.5.3 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.9: + resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@13.22.0: + resolution: {integrity: sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.1 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.1 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.13.0: + resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.11 + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /keyv@4.5.3: + resolution: {integrity: sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /nanodelay@1.0.8: + resolution: {integrity: sha512-mfVn7t26m4mVoUuWdUevZccq0saIh5T4Lu3cAzbZ6j03yc4sIDwM3Dof0LS70YwflPZtGJ92BGhNYV862wXRvg==} + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /nanospinner@1.1.0: + resolution: {integrity: sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA==} + dependencies: + picocolors: 1.0.0 + dev: true + + /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} + dev: true + + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + + /object.groupby@1.0.1: + resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + dev: true + + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /postcss-parser-tests@8.8.0: + resolution: {integrity: sha512-vAyVrBzp7YmfpmjCG3RGhilE9+oydj6oTZYWMBwkp/3FVOdUURerTRD0w/NVegOreAj51tCPqgCwbb4AW5f5SA==} + dependencies: + picocolors: 1.0.0 + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + set-function-name: 2.0.1 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true + + /resolve@1.22.6: + resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true + + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + dev: true + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /simple-git-hooks@2.9.0: + resolution: {integrity: sha512-waSQ5paUQtyGC0ZxlHmcMmD9I1rRXauikBwX31bX58l5vTOhCEcBC5Bi+ZDkPXTjDnZAF8TbCqKBY+9+sVPScw==} + hasBin: true + requiresBuild: true + dev: true + + /size-limit@9.0.0: + resolution: {integrity: sha512-DrA7o2DeRN3s+vwCA9nn7Ck9Y4pn9t0GNUwQRpKqBtBmNkl6LA2s/NlNCdtKHrEkRTeYA1ZQ65mnYveo9rUqgA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + bytes-iec: 3.1.1 + chokidar: 3.5.3 + globby: 11.1.0 + lilconfig: 2.1.0 + nanospinner: 1.1.0 + picocolors: 1.0.0 + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /ts-api-utils@1.0.3(typescript@5.2.2): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.2.2 + dev: true + + /ts-node@10.9.1(@types/node@20.7.1)(typescript@5.2.2): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + 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 + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.7.1 + acorn: 8.10.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.2.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.12 + dev: true + + /typescript@5.2.2: + resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + dependencies: + '@types/unist': 2.0.8 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + dequal: 2.0.3 + diff: 5.1.0 + kleur: 4.1.5 + sade: 1.8.1 + dev: true + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-to-istanbul@9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.19 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + + /vfile-location@4.1.0: + resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + dependencies: + '@types/unist': 2.0.8 + vfile: 5.3.7 + dev: true + + /vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + dependencies: + '@types/unist': 2.0.8 + unist-util-stringify-position: 3.0.3 + dev: true + + /vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + dependencies: + '@types/unist': 2.0.8 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + 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 + dev: true + + /which-typed-array@1.1.11: + resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + 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 + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/test/at-rule.test.js b/test/at-rule.test.js deleted file mode 100644 index 28cb3f5e6..000000000 --- a/test/at-rule.test.js +++ /dev/null @@ -1,45 +0,0 @@ -let AtRule = require('../lib/at-rule') -let parse = require('../lib/parse') - -it('initializes with properties', () => { - let rule = new AtRule({ name: 'encoding', params: '"utf-8"' }) - - expect(rule.name).toEqual('encoding') - expect(rule.params).toEqual('"utf-8"') - - expect(rule.toString()).toEqual('@encoding "utf-8"') -}) - -it('does not fall on childless at-rule', () => { - let rule = new AtRule() - expect(rule.each(i => i)).not.toBeDefined() -}) - -it('creates nodes property on prepend()', () => { - let rule = new AtRule() - expect(rule.nodes).not.toBeDefined() - - rule.prepend('color: black') - expect(rule.nodes).toHaveLength(1) -}) - -it('creates nodes property on append()', () => { - let rule = new AtRule() - expect(rule.nodes).not.toBeDefined() - - rule.append('color: black') - expect(rule.nodes).toHaveLength(1) -}) - -it('inserts default spaces', () => { - let rule = new AtRule({ name: 'page', params: 1, nodes: [] }) - expect(rule.toString()).toEqual('@page 1 {}') -}) - -it('clone spaces from another at-rule', () => { - let root = parse('@page{}a{}') - let rule = new AtRule({ name: 'page', params: 1, nodes: [] }) - root.append(rule) - - expect(rule.toString()).toEqual('@page 1{}') -}) diff --git a/test/at-rule.test.ts b/test/at-rule.test.ts new file mode 100755 index 000000000..10a23a871 --- /dev/null +++ b/test/at-rule.test.ts @@ -0,0 +1,51 @@ +import { 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.run() diff --git a/test/browser.test.js b/test/browser.test.js deleted file mode 100644 index 8198e287a..000000000 --- a/test/browser.test.js +++ /dev/null @@ -1,28 +0,0 @@ -jest.doMock('fs', () => ({ })) -jest.doMock('chalk', () => ({ })) -jest.doMock('supports-color', () => ({ })) - -let postcss = require('..') - -it('shows code without chalk', () => { - let error - try { - postcss.parse('a{') - } catch (e) { - if (e.name === 'CssSyntaxError') { - error = e - } else { - throw e - } - } - expect(error.showSourceCode(true)).toEqual('> 1 | a{\n' + - ' | ^') -}) - -it('generates source map without fs', () => { - expect(postcss([() => true]).process('a{}', { from: 'a.css', map: true }).css) - .toEqual('a{}\n/*# sourceMappingURL=data:application/json;base64,' + - 'eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImEuY3NzIl0sIm5hbWVzIjpbXSw' + - 'ibWFwcGluZ3MiOiJBQUFBLEVBQUUiLCJmaWxlIjoiYS5jc3MiLCJzb3VyY2' + - 'VzQ29udGVudCI6WyJhe30iXX0= */') -}) diff --git a/test/comment.test.js b/test/comment.test.js deleted file mode 100644 index 5f110e51e..000000000 --- a/test/comment.test.js +++ /dev/null @@ -1,15 +0,0 @@ -let Comment = require('../lib/comment') -let parse = require('../lib/parse') - -it('toString() inserts default spaces', () => { - let comment = new Comment({ text: 'hi' }) - expect(comment.toString()).toEqual('/* hi */') -}) - -it('toString() clones spaces from another comment', () => { - let root = parse('a{} /*hello*/') - let comment = new Comment({ text: 'world' }) - root.append(comment) - - expect(root.toString()).toEqual('a{} /*hello*/ /*world*/') -}) diff --git a/test/comment.test.ts b/test/comment.test.ts new file mode 100755 index 000000000..b25f8125e --- /dev/null +++ b/test/comment.test.ts @@ -0,0 +1,19 @@ +import { 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() diff --git a/test/container.test.js b/test/container.test.js deleted file mode 100644 index 65d44f544..000000000 --- a/test/container.test.js +++ /dev/null @@ -1,738 +0,0 @@ -let Declaration = require('../lib/declaration') -let parse = require('../lib/parse') -let Rule = require('../lib/rule') -let Root = require('../lib/root') - -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 */' + - '}' + - '}' - -it('throws error on declaration without value', () => { - expect(() => { - (new Rule()).append({ prop: 'color', vlaue: 'black' }) - }).toThrowError(/Value field is missed/) -}) - -it('throws error on unknown node type', () => { - expect(() => { - (new Rule()).append({ foo: 'bar' }) - }).toThrowError(/Unknown node type/) -}) - -it('push() adds child without checks', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.push(new Declaration({ prop: 'c', value: '3' })) - expect(rule.toString()).toEqual('a { a: 1; b: 2; c: 3 }') - expect(rule.nodes).toHaveLength(3) - expect(rule.last.raws.before).not.toBeDefined() -}) - -it('each() iterates', () => { - let rule = parse('a { a: 1; b: 2 }').first - let indexes = [] - - let result = rule.each((decl, i) => { - indexes.push(i) - expect(decl).toBe(rule.nodes[i]) - }) - - expect(result).not.toBeDefined() - expect(indexes).toEqual([0, 1]) -}) - -it('each() iterates with prepend', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each(() => { - rule.prepend({ prop: 'color', value: 'aqua' }) - size += 1 - }) - - expect(size).toEqual(2) -}) - -it('each() iterates with prepend insertBefore', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each(decl => { - if (decl.prop === 'a') { - rule.insertBefore(decl, { prop: 'c', value: '3' }) - } - size += 1 - }) - - expect(size).toEqual(2) -}) - -it('each() iterates with append insertBefore', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each((decl, i) => { - if (decl.prop === 'a') { - rule.insertBefore(i + 1, { prop: 'c', value: '3' }) - } - size += 1 - }) - - expect(size).toEqual(3) -}) - -it('each() iterates with prepend insertAfter', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each((decl, i) => { - rule.insertAfter(i - 1, { prop: 'c', value: '3' }) - size += 1 - }) - - expect(size).toEqual(2) -}) - -it('each() iterates with append insertAfter', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each((decl, i) => { - if (decl.prop === 'a') { - rule.insertAfter(i, { prop: 'c', value: '3' }) - } - size += 1 - }) - - expect(size).toEqual(3) -}) - -it('each() iterates with remove', () => { - let rule = parse('a { a: 1; b: 2 }').first - let size = 0 - - rule.each(() => { - rule.removeChild(0) - size += 1 - }) - - expect(size).toEqual(2) -}) - -it('each() breaks iteration', () => { - let rule = parse('a { a: 1; b: 2 }').first - let indexes = [] - - let result = rule.each((decl, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([0]) -}) - -it('each() allows to change children', () => { - let rule = parse('a { a: 1; b: 2 }').first - let props = [] - - rule.each(decl => { - props.push(decl.prop) - rule.nodes = [rule.last, rule.first] - }) - - expect(props).toEqual(['a', 'a']) -}) - -it('walk() iterates', () => { - let types = [] - let indexes = [] - - let result = parse(example).walk((node, i) => { - types.push(node.type) - indexes.push(i) - }) - - expect(result).not.toBeDefined() - expect(types).toEqual([ - 'rule', 'decl', 'decl', 'comment', 'atrule', 'comment', 'rule', 'decl', - 'atrule', 'rule', 'decl', 'atrule', 'decl', 'comment' - ]) - expect(indexes).toEqual([0, 0, 1, 1, 2, 0, 1, 0, 3, 0, 0, 1, 0, 1]) -}) - -it('walk() breaks iteration', () => { - let indexes = [] - - let result = parse(example).walk((decl, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([0]) -}) - -it('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 - try { - root.walk(() => { - throw error - }) - } catch (e) { - catched = e - } - expect(catched).toBe(error) - expect(catched.postcssNode.toString()).toEqual('a { a: 1; b: 2 }') - expect(catched.stack.replace(/.:\\/i, '/')).toEqual( - 'Error: T\n at /c.css:1:1\n at b (b.js:2:4)\n at a (a.js:2:1)') -}) - -it('walkDecls() iterates', () => { - let props = [] - let indexes = [] - - let result = parse(example).walkDecls((decl, i) => { - props.push(decl.prop) - indexes.push(i) - }) - - expect(result).not.toBeDefined() - expect(props).toEqual(['a', 'b', 'c', 'd', 'e']) - expect(indexes).toEqual([0, 1, 0, 0, 0]) -}) - -it('walkDecls() iterates with changes', () => { - let size = 0 - parse(example).walkDecls((decl, i) => { - decl.parent.removeChild(i) - size += 1 - }) - expect(size).toEqual(5) -}) - -it('walkDecls() breaks iteration', () => { - let indexes = [] - - let result = parse(example).walkDecls((decl, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([0]) -}) - -it('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 => { - expect(decl.prop).toEqual('one') - size += 1 - }) - - expect(size).toEqual(2) -}) - -it('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 - }) - - expect(size).toEqual(1) -}) - -it('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 - }) - - expect(size).toEqual(2) -}) - -it('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 - }) - - expect(size).toEqual(1) -}) - -it('walkComments() iterates', () => { - let texts = [] - let indexes = [] - - let result = parse(example).walkComments((comment, i) => { - texts.push(comment.text) - indexes.push(i) - }) - - expect(result).not.toBeDefined() - expect(texts).toEqual(['a', 'b', 'c']) - expect(indexes).toEqual([1, 0, 1]) -}) - -it('walkComments() iterates with changes', () => { - let size = 0 - parse(example).walkComments((comment, i) => { - comment.parent.removeChild(i) - size += 1 - }) - expect(size).toEqual(3) -}) - -it('walkComments() breaks iteration', () => { - let indexes = [] - - let result = parse(example).walkComments((comment, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([1]) -}) - -it('walkRules() iterates', () => { - let selectors = [] - let indexes = [] - - let result = parse(example).walkRules((rule, i) => { - selectors.push(rule.selector) - indexes.push(i) - }) - - expect(result).not.toBeDefined() - expect(selectors).toEqual(['a', 'to', 'em']) - expect(indexes).toEqual([0, 1, 0]) -}) - -it('walkRules() iterates with changes', () => { - let size = 0 - parse(example).walkRules((rule, i) => { - rule.parent.removeChild(i) - size += 1 - }) - expect(size).toEqual(3) -}) - -it('walkRules() breaks iteration', () => { - let indexes = [] - - let result = parse(example).walkRules((rule, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([0]) -}) - -it('walkRules() filters by selector', () => { - let size = 0 - parse('a{}b{}a{}').walkRules('a', rule => { - expect(rule.selector).toEqual('a') - size += 1 - }) - expect(size).toEqual(2) -}) - -it('walkRules() breaks selector filters', () => { - let size = 0 - parse('a{}b{}a{}').walkRules('a', () => { - size += 1 - return false - }) - expect(size).toEqual(1) -}) - -it('walkRules() filters by regexp', () => { - let size = 0 - parse('a{}a b{}b a{}').walkRules(/^a/, rule => { - expect(rule.selector).toMatch(/^a/) - size += 1 - }) - expect(size).toEqual(2) -}) - -it('walkRules() breaks selector regexp', () => { - let size = 0 - parse('a{}b a{}b a{}').walkRules(/^a/, () => { - size += 1 - return false - }) - expect(size).toEqual(1) -}) - -it('walkAtRules() iterates', () => { - let names = [] - let indexes = [] - - let result = parse(example).walkAtRules((atrule, i) => { - names.push(atrule.name) - indexes.push(i) - }) - - expect(result).not.toBeDefined() - expect(names).toEqual(['keyframes', 'media', 'page']) - expect(indexes).toEqual([2, 3, 1]) -}) - -it('walkAtRules() iterates with changes', () => { - let size = 0 - parse(example).walkAtRules((atrule, i) => { - atrule.parent.removeChild(i) - size += 1 - }) - expect(size).toEqual(3) -}) - -it('walkAtRules() breaks iteration', () => { - let indexes = [] - - let result = parse(example).walkAtRules((atrule, i) => { - indexes.push(i) - return false - }) - - expect(result).toBe(false) - expect(indexes).toEqual([2]) -}) - -it('walkAtRules() filters at-rules by name', () => { - let css = parse('@page{@page 2{}}@media print{@page{}}') - let size = 0 - - css.walkAtRules('page', atrule => { - expect(atrule.name).toEqual('page') - size += 1 - }) - - expect(size).toEqual(3) -}) - -it('walkAtRules() breaks name filter', () => { - let size = 0 - parse('@page{@page{@page{}}}').walkAtRules('page', () => { - size += 1 - return false - }) - expect(size).toEqual(1) -}) - -it('walkAtRules() filters at-rules by name regexp', () => { - let css = parse('@page{@page 2{}}@media print{@pages{}}') - let size = 0 - - css.walkAtRules(/page/, () => { - size += 1 - }) - - expect(size).toEqual(3) -}) - -it('walkAtRules() breaks regexp filter', () => { - let size = 0 - parse('@page{@pages{@page{}}}').walkAtRules(/page/, () => { - size += 1 - return false - }) - expect(size).toEqual(1) -}) - -it('append() appends child', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.append({ prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; b: 2; c: 3 }') - expect(rule.last.raws.before).toEqual(' ') -}) - -it('append() appends multiple children', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.append({ prop: 'c', value: '3' }, { prop: 'd', value: '4' }) - expect(rule.toString()).toEqual('a { a: 1; b: 2; c: 3; d: 4 }') - expect(rule.last.raws.before).toEqual(' ') -}) - -it('append() has declaration shortcut', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.append({ prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; b: 2; c: 3 }') -}) - -it('append() has rule shortcut', () => { - let root = new Root() - root.append({ selector: 'a' }) - expect(root.first.toString()).toEqual('a {}') -}) - -it('append() has at-rule shortcut', () => { - let root = new Root() - root.append({ name: 'encoding', params: '"utf-8"' }) - expect(root.first.toString()).toEqual('@encoding "utf-8"') -}) - -it('append() has comment shortcut', () => { - let root = new Root() - root.append({ text: 'ok' }) - expect(root.first.toString()).toEqual('/* ok */') -}) - -it('append() receives root', () => { - let css = parse('a {}') - css.append(parse('b {}')) - expect(css.toString()).toEqual('a {}b {}') -}) - -it('append() reveives string', () => { - let root = new Root() - root.append('a{}b{}') - root.first.append('color:black') - expect(root.toString()).toEqual('a{color:black}b{}') - expect(root.first.first.source).not.toBeDefined() -}) - -it('append() receives array', () => { - let a = parse('a{ z-index: 1 }') - let b = parse('b{ width: 1px; height: 2px }') - - a.first.append(b.first.nodes) - expect(a.toString()).toEqual('a{ z-index: 1; width: 1px; height: 2px }') - expect(b.toString()).toEqual('b{ }') -}) - -it('append() move node on insert', () => { - let a = parse('a{}') - let b = parse('b{}') - - b.append(a.first) - b.last.selector = 'b a' - - expect(a.toString()).toEqual('') - expect(b.toString()).toEqual('b{}b a{}') -}) - -it('prepend() prepends child', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.prepend({ prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { c: 3; a: 1; b: 2 }') - expect(rule.first.raws.before).toEqual(' ') -}) - -it('prepend() prepends multiple children', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.prepend({ prop: 'c', value: '3' }, { prop: 'd', value: '4' }) - expect(rule.toString()).toEqual('a { c: 3; d: 4; a: 1; b: 2 }') - expect(rule.first.raws.before).toEqual(' ') -}) - -it('prepend() receive hash instead of declaration', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.prepend({ prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { c: 3; a: 1; b: 2 }') -}) - -it('prepend() receives root', () => { - let css = parse('a {}') - css.prepend(parse('b {}')) - expect(css.toString()).toEqual('b {}\na {}') -}) - -it('prepend() receives string', () => { - let css = parse('a {}') - css.prepend('b {}') - expect(css.toString()).toEqual('b {}\na {}') -}) - -it('prepend() receives array', () => { - let a = parse('a{ z-index: 1 }') - let b = parse('b{ width: 1px; height: 2px }') - - a.first.prepend(b.first.nodes) - expect(a.toString()).toEqual('a{ width: 1px; height: 2px; z-index: 1 }') -}) - -it('prepend() works on empty container', () => { - let root = parse('') - root.prepend(new Rule({ selector: 'a' })) - expect(root.toString()).toEqual('a {}') -}) - -it('insertBefore() inserts child', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertBefore(1, { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') - expect(rule.nodes[1].raws.before).toEqual(' ') -}) - -it('insertBefore() works with nodes too', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertBefore(rule.nodes[1], { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') -}) - -it('insertBefore() receive hash instead of declaration', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertBefore(1, { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') -}) - -it('insertBefore() receives array', () => { - let a = parse('a{ color: red; z-index: 1 }') - let b = parse('b{ width: 1; height: 2 }') - - a.first.insertBefore(1, b.first.nodes) - expect(a.toString()) - .toEqual('a{ color: red; width: 1; height: 2; z-index: 1 }') -}) - -it('insertAfter() inserts child', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertAfter(0, { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') - expect(rule.nodes[1].raws.before).toEqual(' ') -}) - -it('insertAfter() works with nodes too', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertAfter(rule.first, { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') -}) - -it('insertAfter() receive hash instead of declaration', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.insertAfter(0, { prop: 'c', value: '3' }) - expect(rule.toString()).toEqual('a { a: 1; c: 3; b: 2 }') -}) - -it('insertAfter() receives array', () => { - let a = parse('a{ color: red; z-index: 1 }') - let b = parse('b{ width: 1; height: 2 }') - - a.first.insertAfter(0, b.first.nodes) - expect(a.toString()) - .toEqual('a{ color: red; width: 1; height: 2; z-index: 1 }') -}) - -it('removeChild() removes by index', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.removeChild(1) - expect(rule.toString()).toEqual('a { a: 1 }') -}) - -it('removeChild() removes by node', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.removeChild(rule.last) - expect(rule.toString()).toEqual('a { a: 1 }') -}) - -it('removeChild() cleans parent in removed node', () => { - let rule = parse('a { a: 1; b: 2 }').first - let decl = rule.first - rule.removeChild(decl) - expect(decl.parent).not.toBeDefined() -}) - -it('removeAll() removes all children', () => { - let rule = parse('a { a: 1; b: 2 }').first - let decl = rule.first - rule.removeAll() - - expect(decl.parent).not.toBeDefined() - expect(rule.toString()).toEqual('a { }') -}) - -it('replaceValues() replaces strings', () => { - let css = parse('a{one:1}b{two:1 2}') - let result = css.replaceValues('1', 'A') - - expect(result).toEqual(css) - expect(css.toString()).toEqual('a{one:A}b{two:A 2}') -}) - -it('replaceValues() replaces regpexp', () => { - let css = parse('a{one:1}b{two:1 2}') - css.replaceValues(/\d/g, i => i + 'A') - expect(css.toString()).toEqual('a{one:1A}b{two:1A 2A}') -}) - -it('replaceValues() filters properties', () => { - let css = parse('a{one:1}b{two:1 2}') - css.replaceValues('1', { props: ['one'] }, 'A') - expect(css.toString()).toEqual('a{one:A}b{two:1 2}') -}) - -it('replaceValues() uses fast check', () => { - let css = parse('a{one:1}b{two:1 2}') - css.replaceValues('1', { fast: '2' }, 'A') - expect(css.toString()).toEqual('a{one:1}b{two:A 2}') -}) - -it('any() return true if all children return true', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.every(i => i.prop.match(/a|b/))).toBe(true) - expect(rule.every(i => i.prop.match(/b/))).toBe(false) -}) - -it('some() return true if all children return true', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.some(i => i.prop === 'b')).toBe(true) - expect(rule.some(i => i.prop === 'c')).toBe(false) -}) - -it('index() returns child index', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.index(rule.nodes[1])).toEqual(1) -}) - -it('index() returns argument if it(is number', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.index(2)).toEqual(2) -}) - -it('returns first child', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.first.prop).toEqual('a') -}) - -it('returns last child', () => { - let rule = parse('a { a: 1; b: 2 }').first - expect(rule.last.prop).toEqual('b') -}) - -it('normalize() does not normalize new children with exists before', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.append({ prop: 'c', value: '3', raws: { before: '\n ' } }) - expect(rule.toString()).toEqual('a { a: 1; b: 2;\n c: 3 }') -}) - -it('forces Declaration#value to be string', () => { - let rule = parse('a { a: 1; b: 2 }').first - rule.append({ prop: 'c', value: 3 }) - expect(typeof rule.first.value).toEqual('string') - expect(typeof rule.last.value).toEqual('string') -}) diff --git a/test/container.test.ts b/test/container.test.ts new file mode 100755 index 000000000..567bda009 --- /dev/null +++ b/test/container.test.ts @@ -0,0 +1,902 @@ +import { 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.run() diff --git a/test/css-syntax-error.test.js b/test/css-syntax-error.test.js deleted file mode 100644 index 503d18536..000000000 --- a/test/css-syntax-error.test.js +++ /dev/null @@ -1,194 +0,0 @@ -let stripAnsi = require('strip-ansi') -let Concat = require('concat-with-sourcemaps') -let chalk = require('chalk') -let path = require('path') - -let CssSyntaxError = require('../lib/css-syntax-error') -let postcss = require('../lib/postcss') - -function parseError (css, opts) { - let error - try { - postcss.parse(css, opts) - } catch (e) { - if (e.name === 'CssSyntaxError') { - error = e - } else { - throw e - } - } - return error -} - -it('saves source', () => { - let error = parseError('a {\n content: "\n}') - - expect(error instanceof CssSyntaxError).toBeTruthy() - expect(error.name).toEqual('CssSyntaxError') - expect(error.message).toEqual(':2:12: Unclosed string') - expect(error.reason).toEqual('Unclosed string') - expect(error.line).toEqual(2) - expect(error.column).toEqual(12) - expect(error.source).toEqual('a {\n content: "\n}') - - expect(error.input).toEqual({ - line: error.line, - column: error.column, - source: error.source - }) -}) - -it('has stack trace', () => { - expect(parseError('a {\n content: "\n}').stack) - .toMatch(/css-syntax-error\.test\.js/) -}) - -it('highlights broken line with colors', () => { - let c = chalk - expect(parseError('#a .b {').showSourceCode(true)).toEqual( - c.red.bold('>') + c.gray(' 1 | ') + - c.magenta('#a') + ' ' + c.yellow('.b') + ' ' + - c.yellow('{') + '\n ' + - c.gray(' | ') + c.red.bold('^')) -}) - -it('highlights broken line', () => { - expect(parseError('a {\n content: "\n}').showSourceCode(false)) - .toEqual(' 1 | a {\n' + - '> 2 | content: "\n' + - ' | ^\n' + - ' 3 | }') -}) - -it('highlights broken line, when indented with tabs', () => { - expect(parseError('a {\n\t \t content:\t"\n}').showSourceCode(false)) - .toEqual(' 1 | a {\n' + - '> 2 | \t \t content:\t"\n' + - ' | \t \t \t^\n' + - ' 3 | }') -}) - -it('highlights small code example', () => { - expect(parseError('a {').showSourceCode(false)) - .toEqual('> 1 | a {\n' + - ' | ^') -}) - -it('add leading space for line numbers', () => { - let css = '\n\n\n\n\n\n\na {\n content: "\n}\n\n\n' - expect(parseError(css).showSourceCode(false)) - .toEqual(' 7 | \n' + - ' 8 | a {\n' + - '> 9 | content: "\n' + - ' | ^\n' + - ' 10 | }\n' + - ' 11 | ') -}) - -it('prints with highlight', () => { - expect(stripAnsi(parseError('a {').toString())) - .toEqual('CssSyntaxError: :1:1: Unclosed block\n' + - '\n' + - '> 1 | a {\n' + - ' | ^\n') -}) - -it('misses highlights without source content', () => { - let error = parseError('a {') - error.source = null - expect(error.toString()) - .toEqual('CssSyntaxError: :1:1: Unclosed block') -}) - -it('misses position without source', () => { - let decl = postcss.decl({ prop: 'color', value: 'black' }) - let error = decl.error('Test') - expect(error.toString()).toEqual('CssSyntaxError: : Test') -}) - -it('uses source map', () => { - let concat = new Concat(true, 'all.css') - concat.add('a.css', 'a { }\n') - concat.add('b.css', '\nb {\n') - - let error = parseError(concat.content, { - from: 'build/all.css', - map: { prev: concat.sourceMap } - }) - - expect(error.file).toEqual(path.resolve('b.css')) - expect(error.line).toEqual(2) - expect(error.source).not.toBeDefined() - - expect(error.input).toEqual({ - file: path.resolve('build/all.css'), - line: 3, - column: 1, - source: 'a { }\n\nb {\n' - }) -}) - -it('shows origin source', () => { - let input = postcss([() => true]).process('a{}', { - from: '/a.css', - to: '/b.css', - map: { inline: false } - }) - let error = parseError('a{', { - from: '/b.css', - to: '/c.css', - map: { prev: input.map } - }) - expect(error.source).toEqual('a{}') -}) - -it('does not uses wrong source map', () => { - let error = parseError('a { }\nb {', { - from: 'build/all.css', - map: { - prev: { - version: 3, - file: 'build/all.css', - sources: ['a.css', 'b.css'], - mappings: 'A' - } - } - }) - expect(error.file).toEqual(path.resolve('build/all.css')) -}) - -it('set source plugin', () => { - let error = postcss.parse('a{}').first.error('Error', { plugin: 'PL' }) - expect(error.plugin).toEqual('PL') - expect(error.toString()) - .toMatch(/^CssSyntaxError: PL: :1:1: Error/) -}) - -it('set source plugin automatically', () => { - let plugin = postcss.plugin('test-plugin', () => { - return css => { - throw css.first.error('Error') - } - }) - - return postcss([plugin]).process('a{}').catch(error => { - if (error.name !== 'CssSyntaxError') throw error - expect(error.plugin).toEqual('test-plugin') - expect(error.toString()).toMatch(/test-plugin/) - }) -}) - -it('set plugin automatically in async', () => { - let plugin = postcss.plugin('async-plugin', () => { - return css => { - return new Promise((resolve, reject) => { - reject(css.first.error('Error')) - }) - } - }) - - return postcss([plugin]).process('a{}').catch(error => { - if (error.name !== 'CssSyntaxError') throw error - expect(error.plugin).toEqual('async-plugin') - }) -}) diff --git a/test/css-syntax-error.test.ts b/test/css-syntax-error.test.ts new file mode 100755 index 000000000..3f1b076f2 --- /dev/null +++ b/test/css-syntax-error.test.ts @@ -0,0 +1,344 @@ +import Concat from 'concat-with-sourcemaps' +import { join, resolve as pathResolve } from 'path' +import * as pico from 'picocolors' +import stripAnsi = require('strip-ansi') +import { pathToFileURL } from 'url' +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('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() diff --git a/test/declaration.test.js b/test/declaration.test.js deleted file mode 100644 index 69c26fd60..000000000 --- a/test/declaration.test.js +++ /dev/null @@ -1,29 +0,0 @@ -let Declaration = require('../lib/declaration') -let parse = require('../lib/parse') -let Rule = require('../lib/rule') - -it('initializes with properties', () => { - let decl = new Declaration({ prop: 'color', value: 'black' }) - expect(decl.prop).toEqual('color') - expect(decl.value).toEqual('black') -}) - -it('returns boolean important', () => { - let decl = new Declaration({ prop: 'color', value: 'black' }) - decl.important = true - expect(decl.toString()).toEqual('color: black !important') -}) - -it('inserts default spaces', () => { - let decl = new Declaration({ prop: 'color', value: 'black' }) - let rule = new Rule({ selector: 'a' }) - rule.append(decl) - expect(rule.toString()).toEqual('a {\n color: black\n}') -}) - -it('clones spaces from another declaration', () => { - let root = parse('a{color:black}') - let decl = new Declaration({ prop: 'margin', value: '0' }) - root.first.append(decl) - expect(root.toString()).toEqual('a{color:black;margin:0}') -}) diff --git a/test/declaration.test.ts b/test/declaration.test.ts new file mode 100755 index 000000000..eacbb8735 --- /dev/null +++ b/test/declaration.test.ts @@ -0,0 +1,48 @@ +import { 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() diff --git a/test/document.test.ts b/test/document.test.ts new file mode 100755 index 000000000..a0a4a02d2 --- /dev/null +++ b/test/document.test.ts @@ -0,0 +1,31 @@ +import { 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() diff --git a/test/errors.ts b/test/errors.ts new file mode 100644 index 000000000..e5c07b7ae --- /dev/null +++ b/test/errors.ts @@ -0,0 +1,22 @@ +import { 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 diff --git a/test/fromJSON.test.ts b/test/fromJSON.test.ts new file mode 100755 index 000000000..132cc06a1 --- /dev/null +++ b/test/fromJSON.test.ts @@ -0,0 +1,59 @@ +import { 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() diff --git a/test/integration.js b/test/integration.js new file mode 100755 index 000000000..bce5cf670 --- /dev/null +++ b/test/integration.js @@ -0,0 +1,7 @@ +#!/usr/bin/env node + +let { testOnReal } = require('postcss-parser-tests') + +let { parse } = require('../') + +testOnReal(css => parse(css).toResult({ map: { annotation: false } })) diff --git a/test/lazy-result.test.js b/test/lazy-result.test.js deleted file mode 100644 index 4051c6da2..000000000 --- a/test/lazy-result.test.js +++ /dev/null @@ -1,59 +0,0 @@ -let mozilla = require('source-map') - -let LazyResult = require('../lib/lazy-result') -let Processor = require('../lib/processor') - -let processor = new Processor() - -it('contains AST', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect(result.root.type).toEqual('root') -}) - -it('will stringify css', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect(result.css).toEqual('a {}') -}) - -it('stringifies css', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect('' + result).toEqual(result.css) -}) - -it('has content alias for css', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect(result.content).toEqual('a {}') -}) - -it('has map only if necessary', () => { - let result1 = new LazyResult(processor, '', { }) - expect(result1.map).not.toBeDefined() - - let result2 = new LazyResult(processor, '', { }) - expect(result2.map).not.toBeDefined() - - let result3 = new LazyResult(processor, '', { map: { inline: false } }) - expect(result3.map instanceof mozilla.SourceMapGenerator).toBeTruthy() -}) - -it('contains options', () => { - let result = new LazyResult(processor, 'a {}', { to: 'a.css' }) - expect(result.opts).toEqual({ to: 'a.css' }) -}) - -it('contains warnings', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect(result.warnings()).toEqual([]) -}) - -it('contains messages', () => { - let result = new LazyResult(processor, 'a {}', { }) - expect(result.messages).toEqual([]) -}) - -it('executes on finally callback', () => { - let mockCallback = jest.fn() - return new LazyResult(processor, 'a {}', { }) - .finally(mockCallback) - .then(() => expect(mockCallback).toHaveBeenCalledTimes(1)) -}) diff --git a/test/lazy-result.test.ts b/test/lazy-result.test.ts new file mode 100755 index 000000000..aef717dcf --- /dev/null +++ b/test/lazy-result.test.ts @@ -0,0 +1,73 @@ +import { 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() diff --git a/test/list.test.js b/test/list.test.js deleted file mode 100644 index 9951ed7fa..000000000 --- a/test/list.test.js +++ /dev/null @@ -1,43 +0,0 @@ -let list = require('../lib/list') - -it('space() splits list by spaces', () => { - expect(list.space('a b')).toEqual(['a', 'b']) -}) - -it('space() trims values', () => { - expect(list.space(' a b ')).toEqual(['a', 'b']) -}) - -it('space() checks quotes', () => { - expect(list.space('"a b\\"" \'\'')).toEqual(['"a b\\""', '\'\'']) -}) - -it('space() checks functions', () => { - expect(list.space('f( )) a( () )')).toEqual(['f( ))', 'a( () )']) -}) - -it('space() works from variable', () => { - let space = list.space - expect(space('a b')).toEqual(['a', 'b']) -}) - -it('comma() splits list by spaces', () => { - expect(list.comma('a, b')).toEqual(['a', 'b']) -}) - -it('comma() adds last empty', () => { - expect(list.comma('a, b,')).toEqual(['a', 'b', '']) -}) - -it('comma() checks quotes', () => { - expect(list.comma('"a,b\\"", \'\'')).toEqual(['"a,b\\""', '\'\'']) -}) - -it('comma() checks functions', () => { - expect(list.comma('f(,)), a(,(),)')).toEqual(['f(,))', 'a(,(),)']) -}) - -it('comma() works from variable', () => { - let comma = list.comma - expect(comma('a, b')).toEqual(['a', 'b']) -}) diff --git a/test/list.test.ts b/test/list.test.ts new file mode 100755 index 000000000..f4575690e --- /dev/null +++ b/test/list.test.ts @@ -0,0 +1,56 @@ +import { 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() diff --git a/test/location.test.ts b/test/location.test.ts new file mode 100644 index 000000000..e74c895f0 --- /dev/null +++ b/test/location.test.ts @@ -0,0 +1,300 @@ +import { 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() diff --git a/test/map.test.js b/test/map.test.js deleted file mode 100644 index c488d0bd4..000000000 --- a/test/map.test.js +++ /dev/null @@ -1,577 +0,0 @@ -let mozilla = require('source-map') -let path = require('path') -let fs = require('fs-extra') - -let PreviousMap = require('../lib/previous-map') -let postcss = require('../lib/postcss') - -function consumer (map) { - return mozilla.SourceMapConsumer.fromSourceMap(map) -} - -function read (result) { - let prev = new PreviousMap(result.css, { }) - return prev.consumer() -} - -let dir = path.join(__dirname, 'map-fixtures') - -let doubler = postcss(css => { - css.walkDecls(decl => decl.parent.prepend(decl.clone())) -}) -let lighter = postcss(css => { - css.walkDecls(decl => { - decl.value = 'white' - }) -}) - -afterEach(() => { - if (fs.existsSync(dir)) fs.removeSync(dir) -}) - -it('adds map field only on request', () => { - expect(postcss([() => true]).process('a {}').map).not.toBeDefined() -}) - -it('return map generator', () => { - let map = postcss([() => true]).process('a {}', { - map: { inline: false } - }).map - expect(map instanceof mozilla.SourceMapGenerator).toBeTruthy() -}) - -it('generate right source map', () => { - let css = 'a {\n color: black;\n }' - let processor = postcss(root => { - root.walkRules(rule => { - rule.selector = 'strong' - }) - root.walkDecls(decl => { - decl.parent.prepend(decl.clone({ prop: 'background' })) - }) - }) - - let result = processor.process(css, { - from: 'a.css', - to: 'b.css', - map: true - }) - let map = read(result) - - expect(map.file).toEqual('b.css') - - expect(map.originalPositionFor({ line: 1, column: 0 })).toEqual({ - source: 'a.css', - line: 1, - column: 0, - name: null - }) - expect(map.originalPositionFor({ line: 1, column: 2 })).toEqual({ - source: 'a.css', - line: 1, - column: 0, - name: null - }) - expect(map.originalPositionFor({ line: 2, column: 2 })).toEqual({ - source: 'a.css', - line: 2, - column: 2, - name: null - }) - expect(map.originalPositionFor({ line: 3, column: 2 })).toEqual({ - source: 'a.css', - line: 2, - column: 2, - name: null - }) - expect(map.originalPositionFor({ line: 3, column: 14 })).toEqual({ - source: 'a.css', - line: 2, - column: 14, - name: null - }) - expect(map.originalPositionFor({ line: 4, column: 2 })).toEqual({ - source: 'a.css', - line: 3, - column: 2, - name: null - }) -}) - -it('changes previous source map', () => { - let css = 'a { color: black }' - - let doubled = doubler.process(css, { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - - let lighted = lighter.process(doubled.css, { - from: 'b.css', - to: 'c.css', - map: { prev: doubled.map } - }) - - let map = consumer(lighted.map) - expect(map.originalPositionFor({ line: 1, column: 18 })).toEqual({ - source: 'a.css', - line: 1, - column: 4, - name: null - }) -}) - -it('adds source map annotation', () => { - let css = 'a { }/*# sourceMappingURL=a.css.map */' - let result = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - - expect(result.css).toEqual('a { }\n/*# sourceMappingURL=b.css.map */') -}) - -it('misses source map annotation, if user ask', () => { - let css = 'a { }' - let result = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { annotation: false } - }) - - expect(result.css).toEqual(css) -}) - -it('misses source map annotation, if previous map missed it', () => { - let css = 'a { }' - - let step1 = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { annotation: false } - }) - - let step2 = postcss([() => true]).process(step1.css, { - from: 'b.css', - to: 'c.css', - map: { prev: step1.map } - }) - - expect(step2.css).toEqual(css) -}) - -it('uses user path in annotation, relative to options.to', () => { - let result = postcss([() => true]).process('a { }', { - from: 'source/a.css', - to: 'build/b.css', - map: { annotation: 'maps/b.map' } - }) - - expect(result.css).toEqual('a { }\n/*# sourceMappingURL=maps/b.map */') - let map = consumer(result.map) - - expect(map.file).toEqual('../b.css') - expect(map.originalPositionFor({ line: 1, column: 0 }).source) - .toEqual('../../source/a.css') -}) - -it('generates inline map', () => { - let css = 'a { }' - - let inline = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { inline: true } - }) - - expect(inline.map).not.toBeDefined() - expect(inline.css).toMatch(/# sourceMappingURL=data:/) - - let separated = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - - let base64 = Buffer.from(separated.map.toString()).toString('base64') - let end = inline.css.slice(-base64.length - 3) - expect(end).toEqual(base64 + ' */') -}) - -it('generates inline map by default', () => { - let inline = postcss([() => true]).process('a { }', { - from: 'a.css', - to: 'b.css', - map: true - }) - expect(inline.css).toMatch(/# sourceMappingURL=data:/) -}) - -it('generates separated map if previous map was not inlined', () => { - let step1 = doubler.process('a { color: black }', { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - let step2 = lighter.process(step1.css, { - from: 'b.css', - to: 'c.css', - map: { prev: step1.map } - }) - - expect(typeof step2.map).toEqual('object') -}) - -it('generates separated map on annotation option', () => { - let result = postcss([() => true]).process('a { }', { - from: 'a.css', - to: 'b.css', - map: { annotation: false } - }) - - expect(typeof result.map).toEqual('object') -}) - -it('allows change map type', () => { - let step1 = postcss([() => true]).process('a { }', { - from: 'a.css', - to: 'b.css', - map: { inline: true } - }) - - let step2 = postcss([() => true]).process(step1.css, { - from: 'b.css', - to: 'c.css', - map: { inline: false } - }) - - expect(typeof step2.map).toEqual('object') - expect(step2.css).toMatch(/# sourceMappingURL=c\.css\.map/) -}) - -it('misses check files on requires', () => { - let file = path.join(dir, 'a.css') - - let step1 = doubler.process('a { }', { - from: 'a.css', - to: file, - map: { inline: false } - }) - - fs.outputFileSync(file + '.map', step1.map.toString()) - let step2 = lighter.process(step1.css, { - from: file, - to: 'b.css', - map: false - }) - - expect(step2.map).not.toBeDefined() -}) - -it('works in subdirs', () => { - let result = doubler.process('a { }', { - from: 'from/a.css', - to: 'out/b.css', - map: { inline: false } - }) - - expect(result.css).toMatch(/sourceMappingURL=b.css.map/) - - let map = consumer(result.map) - expect(map.file).toEqual('b.css') - expect(map.sources).toEqual(['../from/a.css']) -}) - -it('uses map from subdir', () => { - let step1 = doubler.process('a { }', { - from: 'a.css', - to: 'out/b.css', - map: { inline: false } - }) - - let step2 = doubler.process(step1.css, { - from: 'out/b.css', - to: 'out/two/c.css', - map: { prev: step1.map } - }) - - let source = consumer(step2.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('../../a.css') - - let step3 = doubler.process(step2.css, { - from: 'c.css', - to: 'd.css', - map: { prev: step2.map } - }) - - source = consumer(step3.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('../../a.css') -}) - -it('uses map from subdir if it inlined', () => { - let step1 = doubler.process('a { }', { - from: 'a.css', - to: 'out/b.css', - map: true - }) - - let step2 = doubler.process(step1.css, { - from: 'out/b.css', - to: 'out/two/c.css', - map: { inline: false } - }) - - let source = consumer(step2.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('../../a.css') -}) - -it('uses map from subdir if it written as a file', () => { - let step1 = doubler.process('a { }', { - from: 'source/a.css', - to: 'one/b.css', - map: { annotation: 'maps/b.css.map', inline: false } - }) - - let source = consumer(step1.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('../../source/a.css') - - let file = path.join(dir, 'one', 'maps', 'b.css.map') - fs.outputFileSync(file, step1.map.toString()) - - let step2 = doubler.process(step1.css, { - from: path.join(dir, 'one', 'b.css'), - to: path.join(dir, 'two', 'c.css'), - map: true - }) - - source = consumer(step2.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('../source/a.css') -}) - -it('works with different types of maps', () => { - let step1 = doubler.process('a { }', { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - - 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', - to: 'c.css', - map: { prev: i } - }) - let source = consumer(step2.map) - .originalPositionFor({ line: 1, column: 0 }).source - expect(source).toEqual('a.css') - } -}) - -it('sets source content by default', () => { - let result = doubler.process('a { }', { - from: 'a.css', - to: 'out/b.css', - map: true - }) - - expect(read(result).sourceContentFor('../a.css')).toEqual('a { }') -}) - -it('misses source content on request', () => { - let result = doubler.process('a { }', { - from: 'a.css', - to: 'out/b.css', - map: { sourcesContent: false } - }) - - expect(read(result).sourceContentFor('../a.css')).toBeNull() -}) - -it('misses source content if previous not have', () => { - let step1 = doubler.process('a { }', { - from: 'a.css', - to: 'out/a.css', - map: { sourcesContent: false } - }) - - let file1 = postcss.parse(step1.css, { - from: 'a.css', - map: { prev: step1.map } - }) - let file2 = postcss.parse('b { }', { from: 'b.css', map: true }) - - file2.append(file1.first.clone()) - let step2 = file2.toResult({ to: 'c.css', map: true }) - - expect(read(step2).sourceContentFor('b.css')).toBeNull() -}) - -it('misses source content on request in multiple steps', () => { - let step1 = doubler.process('a { }', { - from: 'a.css', - to: 'out/a.css', - map: { sourcesContent: true } - }) - - let file1 = postcss.parse(step1.css, { - from: 'a.css', - map: { prev: step1.map } - }) - let file2 = postcss.parse('b { }', { from: 'b.css', map: true }) - - file2.append(file1.first.clone()) - let step2 = file2.toResult({ - to: 'c.css', - map: { sourcesContent: false } - }) - - let map = read(step2) - expect(map.sourceContentFor('b.css')).toBeNull() - expect(map.sourceContentFor('../a.css')).toBeNull() -}) - -it('detects input file name from map', () => { - let one = doubler.process('a { }', { to: 'a.css', map: true }) - let two = doubler.process(one.css, { map: { prev: one.map } }) - expect(two.root.first.source.input.file).toEqual(path.resolve('a.css')) -}) - -it('works without file names', () => { - let step1 = doubler.process('a { }', { map: true }) - let step2 = doubler.process(step1.css) - expect(step2.css).toMatch(/a \{ \}\n\/\*/) -}) - -it('supports UTF-8', () => { - let step1 = doubler.process('a { }', { - from: 'вход.css', - to: 'шаг1.css', - map: true - }) - let step2 = doubler.process(step1.css, { - from: 'шаг1.css', - to: 'выход.css' - }) - - expect(read(step2).file).toEqual('выход.css') -}) - -it('generates map for node created manually', () => { - let contenter = postcss(css => { - css.first.prepend({ prop: 'content', value: '""' }) - }) - let result = contenter.process('a:after{\n}', { map: true }) - let map = read(result) - expect(map.originalPositionFor({ line: 2, column: 5 })).toEqual({ - source: '', - column: 0, - line: 1, - name: null - }) -}) - -it('uses input file name as output file name', () => { - let result = doubler.process('a{}', { - from: 'a.css', - map: { inline: false } - }) - expect(result.map.toJSON().file).toEqual('a.css') -}) - -it('uses to.css as default output name', () => { - let result = doubler.process('a{}', { map: { inline: false } }) - expect(result.map.toJSON().file).toEqual('to.css') -}) - -it('supports annotation comment in any place', () => { - let css = '/*# sourceMappingURL=a.css.map */a { }' - let result = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - - expect(result.css).toEqual('a { }\n/*# sourceMappingURL=b.css.map */') -}) - -it('does not update annotation on request', () => { - let css = 'a { }/*# sourceMappingURL=a.css.map */' - let result = postcss([() => true]).process(css, { - from: 'a.css', - to: 'b.css', - map: { annotation: false, inline: false } - }) - - expect(result.css).toEqual('a { }/*# sourceMappingURL=a.css.map */') -}) - -it('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 - expect(css.match(/sourceMappingURL/g)).toHaveLength(1) -}) - -it('uses Windows line separation too', () => { - let result = postcss([() => true]).process('a {\r\n}', { map: true }) - expect(result.css).toMatch(/a \{\r\n\}\r\n\/\*# sourceMappingURL=/) -}) - -it('`map.from` should override the source map sources', () => { - let result = postcss([() => true]).process('a{}', { - map: { - inline: false, - from: 'file:///dir/a.css' - } - }) - expect(result.map.toJSON().sources).toEqual(['file:///dir/a.css']) -}) - -it('preserves absolute urls in `to`', () => { - let result = postcss([() => true]).process('a{}', { - from: '/dir/to/a.css', - to: 'http://example.com/a.css', - map: { inline: false } - }) - expect(result.map.toJSON().file).toEqual('http://example.com/a.css') -}) - -it('preserves absolute urls in sources', () => { - let result = postcss([() => true]).process('a{}', { - from: 'file:///dir/a.css', - to: 'http://example.com/a.css', - map: { inline: false } - }) - expect(result.map.toJSON().sources).toEqual(['file:///dir/a.css']) -}) - -it('preserves absolute urls in sources from previous map', () => { - let result1 = postcss([() => true]).process('a{}', { - from: 'http://example.com/a.css', - to: 'http://example.com/b.css', - map: true - }) - let result2 = postcss([() => true]).process(result1.css, { - to: 'http://example.com/c.css', - map: { - inline: false - } - }) - expect(result2.root.source.input.file).toEqual('http://example.com/b.css') - expect(result2.map.toJSON().sources).toEqual(['http://example.com/a.css']) -}) diff --git a/test/map.test.ts b/test/map.test.ts new file mode 100755 index 000000000..b2125e071 --- /dev/null +++ b/test/map.test.ts @@ -0,0 +1,780 @@ +import { + 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() diff --git a/test/no-work-result.test.ts b/test/no-work-result.test.ts new file mode 100644 index 000000000..f3b171fec --- /dev/null +++ b/test/no-work-result.test.ts @@ -0,0 +1,101 @@ +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 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.run() diff --git a/test/node.test.js b/test/node.test.js deleted file mode 100644 index 04653320b..000000000 --- a/test/node.test.js +++ /dev/null @@ -1,336 +0,0 @@ -let path = require('path') - -let CssSyntaxError = require('../lib/css-syntax-error') -let Declaration = require('../lib/declaration') -let postcss = require('../lib/postcss') -let AtRule = require('../lib/at-rule') -let parse = require('../lib/parse') -let Root = require('../lib/root') -let Rule = require('../lib/rule') - -function stringify (node, builder) { - return builder(node.selector) -} - -it('shows error on wrong constructor types', () => { - expect(() => { - new Rule('a') - }).toThrowError('PostCSS nodes constructor accepts object, not "a"') -}) - -it('error() generates custom error', () => { - let file = path.resolve('a.css') - let css = parse('a{}', { from: file }) - let error = css.first.error('Test') - expect(error instanceof CssSyntaxError).toBeTruthy() - expect(error.message).toEqual(file + ':1:1: Test') -}) - -it('error() generates custom error for nodes without source', () => { - let rule = new Rule({ selector: 'a' }) - let error = rule.error('Test') - expect(error.message).toEqual(': Test') -}) - -it('error() highlights index', () => { - let root = parse('a { b: c }') - let error = root.first.first.error('Bad semicolon', { index: 1 }) - expect(error.showSourceCode(false)).toEqual('> 1 | a { b: c }\n' + - ' | ^') -}) - -it('error() highlights word', () => { - let root = parse('a { color: x red }') - let error = root.first.first.error('Wrong color', { word: 'x' }) - expect(error.showSourceCode(false)).toEqual('> 1 | a { color: x red }\n' + - ' | ^') -}) - -it('error() highlights word in multiline string', () => { - let root = parse('a { color: red\n x }') - let error = root.first.first.error('Wrong color', { word: 'x' }) - expect(error.showSourceCode(false)).toEqual(' 1 | a { color: red\n' + - '> 2 | x }\n' + - ' | ^') -}) - -it('warn() attaches a warning to the result object', () => { - let warning - let warner = postcss.plugin('warner', () => { - return (css, result) => { - warning = css.first.warn(result, 'FIRST!') - } - }) - - return postcss([warner]).process('a{}', { from: undefined }).then(result => { - expect(warning.type).toEqual('warning') - expect(warning.text).toEqual('FIRST!') - expect(warning.plugin).toEqual('warner') - expect(result.warnings()).toEqual([warning]) - }) -}) - -it('warn() accepts options', () => { - let warner = postcss.plugin('warner', () => { - return (css, result) => { - css.first.warn(result, 'FIRST!', { index: 1 }) - } - }) - - let result = postcss([warner()]).process('a{}') - expect(result.warnings()).toHaveLength(1) - expect(result.warnings()[0].index).toEqual(1) -}) - -it('remove() removes node from parent', () => { - let rule = new Rule({ selector: 'a' }) - let decl = new Declaration({ prop: 'color', value: 'black' }) - rule.append(decl) - - decl.remove() - expect(rule.nodes).toHaveLength(0) - expect(decl.parent).not.toBeDefined() -}) - -it('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) - - expect(result).toEqual(width) - expect(rule.toString()).toEqual('a {\n' + - ' color: black;\n' + - ' min-width: 1px;\n' + - ' height: 1px\n' + - '}') -}) - -it('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) - expect(root.toString()).toEqual('a {}\nb {}') -}) - -it('replaceWith() replaces node', () => { - let css = parse('a{one:1;two:2}') - let decl = { prop: 'fix', value: 'fixed' } - let result = css.first.first.replaceWith(decl) - - expect(result.prop).toEqual('one') - expect(result.parent).not.toBeDefined() - expect(css.toString()).toEqual('a{fix:fixed;two:2}') -}) - -it('toString() accepts custom stringifier', () => { - expect(new Rule({ selector: 'a' }).toString(stringify)).toEqual('a') -}) - -it('toString() accepts custom syntax', () => { - expect(new Rule({ selector: 'a' }).toString({ stringify })).toEqual('a') -}) - -it('clone() clones nodes', () => { - let rule = new Rule({ selector: 'a' }) - rule.append({ prop: 'color', value: '/**/black' }) - - let clone = rule.clone() - - expect(clone.parent).not.toBeDefined() - - expect(rule.first.parent).toBe(rule) - expect(clone.first.parent).toBe(clone) - - clone.append({ prop: 'z-index', value: '1' }) - expect(rule.nodes).toHaveLength(1) -}) - -it('clone() overrides properties', () => { - let rule = new Rule({ selector: 'a' }) - let clone = rule.clone({ selector: 'b' }) - expect(clone.selector).toEqual('b') -}) - -it('clone() keeps code style', () => { - let css = parse('@page 1{a{color:black;}}') - expect(css.clone().toString()).toEqual('@page 1{a{color:black;}}') -}) - -it('clone() works with null in raws', () => { - let decl = new Declaration({ - prop: 'color', - value: 'black', - raws: { value: null } - }) - let clone = decl.clone() - expect(Object.keys(clone.raws)).toEqual(['value']) -}) - -it('cloneBefore() clones and insert before current node', () => { - let rule = new Rule({ selector: 'a', raws: { after: '' } }) - rule.append({ prop: 'z-index', value: '1', raws: { before: '' } }) - - let result = rule.first.cloneBefore({ value: '2' }) - - expect(result).toBe(rule.first) - expect(rule.toString()).toEqual('a {z-index: 2;z-index: 1}') -}) - -it('cloneAfter() clones and insert after current node', () => { - let rule = new Rule({ selector: 'a', raws: { after: '' } }) - rule.append({ prop: 'z-index', value: '1', raws: { before: '' } }) - - let result = rule.first.cloneAfter({ value: '2' }) - - expect(result).toBe(rule.last) - expect(rule.toString()).toEqual('a {z-index: 1;z-index: 2}') -}) - -it('before() insert before current node', () => { - let rule = new Rule({ selector: 'a', raws: { after: '' } }) - rule.append({ prop: 'z-index', value: '1', raws: { before: '' } }) - - let result = rule.first.before('color: black') - - expect(result).toBe(rule.last) - expect(rule.toString()).toEqual('a {color: black;z-index: 1}') -}) - -it('after() insert after current node', () => { - let rule = new Rule({ selector: 'a', raws: { after: '' } }) - rule.append({ prop: 'z-index', value: '1', raws: { before: '' } }) - - let result = rule.first.after('color: black') - - expect(result).toBe(rule.first) - expect(rule.toString()).toEqual('a {z-index: 1;color: black}') -}) - -it('next() returns next node', () => { - let css = parse('a{one:1;two:2}') - expect(css.first.first.next()).toBe(css.first.last) - expect(css.first.last.next()).not.toBeDefined() -}) - -it('next() returns undefined on no parent', () => { - let css = parse('') - expect(css.next()).not.toBeDefined() -}) - -it('prev() returns previous node', () => { - let css = parse('a{one:1;two:2}') - expect(css.first.last.prev()).toBe(css.first.first) - expect(css.first.first.prev()).not.toBeDefined() -}) - -it('prev() returns undefined on no parent', () => { - let css = parse('') - expect(css.prev()).not.toBeDefined() -}) - -it('toJSON() cleans parents inside', () => { - let rule = new Rule({ selector: 'a' }) - rule.append({ prop: 'color', value: 'b' }) - - let json = rule.toJSON() - expect(json.parent).not.toBeDefined() - expect(json.nodes[0].parent).not.toBeDefined() - - expect(JSON.stringify(rule)) - .toEqual('{"raws":{},"selector":"a","type":"rule","nodes":[' + - '{"raws":{},"prop":"color","value":"b","type":"decl"}' + - ']}') -}) - -it('toJSON() converts custom properties', () => { - let root = new Root() - root._cache = [1] - root._hack = { - toJSON () { - return 'hack' - } - } - - expect(root.toJSON()).toEqual({ - type: 'root', - nodes: [], - raws: { }, - _hack: 'hack', - _cache: [1] - }) -}) - -it('raw() has shortcut to stringifier', () => { - let rule = new Rule({ selector: 'a' }) - expect(rule.raw('before')).toEqual('') -}) - -it('root() returns root', () => { - let css = parse('@page{a{color:black}}') - expect(css.first.first.first.root()).toBe(css) -}) - -it('root() returns parent of parents', () => { - let rule = new Rule({ selector: 'a' }) - rule.append({ prop: 'color', value: 'black' }) - expect(rule.first.root()).toBe(rule) -}) - -it('root() returns self on root', () => { - let rule = new Rule({ selector: 'a' }) - expect(rule.root()).toBe(rule) -}) - -it('cleanRaws() cleans style recursivelly', () => { - let css = parse('@page{a{color:black}}') - css.cleanRaws() - - expect(css.toString()) - .toEqual('@page {\n a {\n color: black\n }\n}') - expect(css.first.raws.before).not.toBeDefined() - expect(css.first.first.first.raws.before).not.toBeDefined() - expect(css.first.raws.between).not.toBeDefined() - expect(css.first.first.first.raws.between).not.toBeDefined() - expect(css.first.raws.after).not.toBeDefined() -}) - -it('cleanRaws() keeps between on request', () => { - let css = parse('@page{a{color:black}}') - css.cleanRaws(true) - - expect(css.toString()) - .toEqual('@page{\n a{\n color:black\n }\n}') - expect(css.first.raws.between).toBeDefined() - expect(css.first.first.first.raws.between).toBeDefined() - expect(css.first.raws.before).not.toBeDefined() - expect(css.first.first.first.raws.before).not.toBeDefined() - expect(css.first.raws.after).not.toBeDefined() -}) - -it('positionInside() returns position when node starts mid-line', () => { - let css = parse('a { one: X }') - let one = css.first.first - expect(one.positionInside(6)).toEqual({ line: 1, column: 12 }) -}) - -it('positionInside() returns position when before contains newline', () => { - let css = parse('a {\n one: X}') - let one = css.first.first - expect(one.positionInside(6)).toEqual({ line: 2, column: 9 }) -}) - -it('positionInside() returns position when node contains newlines', () => { - let css = parse('a {\n\tone: 1\n\t\tX\n3}') - let one = css.first.first - expect(one.positionInside(10)).toEqual({ line: 3, column: 4 }) -}) diff --git a/test/node.test.ts b/test/node.test.ts new file mode 100755 index 000000000..e847c031c --- /dev/null +++ b/test/node.test.ts @@ -0,0 +1,449 @@ +import { 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('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 }) +}) + +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('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 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.run() diff --git a/test/old-node.js b/test/old-node.js new file mode 100644 index 000000000..43357955c --- /dev/null +++ b/test/old-node.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line +globalThis = Function('return this')() diff --git a/test/parse.test.js b/test/parse.test.js deleted file mode 100644 index 0cca893a5..000000000 --- a/test/parse.test.js +++ /dev/null @@ -1,201 +0,0 @@ -let cases = require('postcss-parser-tests') -let path = require('path') -let fs = require('fs') - -let parse = require('../lib/parse') -let Root = require('../lib/root') - -it('works with file reads', () => { - let stream = fs.readFileSync(cases.path('atrule-empty.css')) - expect(parse(stream) instanceof Root).toBeTruthy() -}) - -cases.each((name, css, json) => { - if (name !== 'custom-properties.css') { - it('parses ' + name, () => { - let parsed = cases.jsonify(parse(css, { from: name })) - expect(parsed).toEqual(json) - }) - } -}) - -it('parses UTF-8 BOM', () => { - let css = parse('\uFEFF@host { a {\f} }') - expect(css.nodes[0].raws.before).toEqual('') -}) - -it('should has true at `hasBOM` property', () => { - let css = parse('\uFEFF@host { a {\f} }') - expect(css.first.source.input.hasBOM).toBeTruthy() -}) - -it('should has false at `hasBOM` property', () => { - let css = parse('@host { a {\f} }') - expect(css.first.source.input.hasBOM).toBeFalsy() -}) - -it('saves source file', () => { - let css = parse('a {}', { from: 'a.css' }) - expect(css.first.source.input.css).toEqual('a {}') - expect(css.first.source.input.file).toEqual(path.resolve('a.css')) - expect(css.first.source.input.from).toEqual(path.resolve('a.css')) -}) - -it('keeps absolute path in source', () => { - let css = parse('a {}', { from: 'http://example.com/a.css' }) - expect(css.first.source.input.file).toEqual('http://example.com/a.css') - expect(css.first.source.input.from).toEqual('http://example.com/a.css') -}) - -it('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) - expect(root2.first.source.input.file).toEqual(path.resolve('to.css')) -}) - -it('sets unique ID for file without name', () => { - let css1 = parse('a {}') - let css2 = parse('a {}') - expect(css1.first.source.input.id).toMatch(/^$/) - expect(css1.first.source.input.from).toMatch(/^$/) - expect(css2.first.source.input.id).not.toEqual(css1.first.source.input.id) -}) - -it('sets parent node', () => { - let file = cases.path('atrule-rules.css') - let css = parse(fs.readFileSync(file)) - - let support = css.first - let keyframes = support.first - let from = keyframes.first - let decl = from.first - - expect(decl.parent).toBe(from) - expect(from.parent).toBe(keyframes) - expect(support.parent).toBe(css) - expect(keyframes.parent).toBe(support) -}) - -it('ignores wrong close bracket', () => { - let root = parse('a { p: ()) }') - expect(root.first.first.value).toEqual('())') -}) - -it('parses unofficial --mixins', () => { - let root = parse(':root { --x { color: pink; }; }') - expect(root.first.first.selector).toEqual('--x') -}) - -it('ignores symbols before declaration', () => { - let root = parse('a { :one: 1 }') - expect(root.first.first.raws.before).toEqual(' :') -}) - -it('parses double semicolon after rule', () => { - expect(parse('a { };;').toString()).toEqual('a { };;') -}) - -it('throws on unclosed blocks', () => { - expect(() => { - parse('\na {\n') - }).toThrowError(/:2:1: Unclosed block/) -}) - -it('throws on unnecessary block close', () => { - expect(() => { - parse('a {\n} }') - }).toThrowError(/:2:3: Unexpected }/) -}) - -it('throws on unclosed comment', () => { - expect(() => { - parse('\n/*\n ') - }).toThrowError(/:2:1: Unclosed comment/) -}) - -it('throws on unclosed quote', () => { - expect(() => { - parse('\n"\n\na ') - }).toThrowError(/:2:1: Unclosed string/) -}) - -it('throws on unclosed bracket', () => { - expect(() => { - parse(':not(one() { }') - }).toThrowError(/:1:5: Unclosed bracket/) -}) - -it('throws on property without value', () => { - expect(() => { - parse('a { b;}') - }).toThrowError(/:1:5: Unknown word/) - expect(() => { - parse('a { b b }') - }).toThrowError(/:1:5: Unknown word/) -}) - -it('throws on nameless at-rule', () => { - expect(() => { - parse('@') - }).toThrowError(/:1:1: At-rule without name/) -}) - -it('throws on property without semicolon', () => { - expect(() => { - parse('a { one: filter(a:"") two: 2 }') - }).toThrowError(/:1:21: Missed semicolon/) -}) - -it('throws on double colon', () => { - expect(() => { - parse('a { one:: 1 }') - }).toThrowError(/:1:9: Double colon/) -}) - -it('do not throws on comment in between', () => { - parse('a { b/* c */: 1 }') -}) - -it('throws on two words in between', () => { - expect(() => { - parse('a { b c: 1 }') - }).toThrowError(/:1:7: Unknown word/) -}) - -it('throws on just colon', () => { - expect(() => { - parse(':') - }).toThrowError(/:1:1: Unknown word/) - expect(() => { - parse(' : ') - }).toThrowError(/:1:2: Unknown word/) -}) - -it('does not suggest different parsers for CSS', () => { - let error - try { - parse('a { one:: 1 }', { from: 'app.css' }) - } catch (e) { - error = e - } - expect(error.message).not.toMatch(/postcss-less|postcss-scss/) -}) - -it('suggests postcss-scss for SCSS sources', () => { - expect(() => { - parse('a { #{var}: 1 }', { from: 'app.scss' }) - }).toThrowError(/postcss-scss/) -}) - -it('suggests postcss-sass for Sass sources', () => { - expect(() => { - parse('a\n #{var}: 1', { from: 'app.sass' }) - }).toThrowError(/postcss-sass/) -}) - -it('suggests postcss-less for Less sources', () => { - expect(() => { - parse('.@{my-selector} { }', { from: 'app.less' }) - }).toThrowError(/postcss-less/) -}) diff --git a/test/parse.test.ts b/test/parse.test.ts new file mode 100755 index 000000000..13de89851 --- /dev/null +++ b/test/parse.test.ts @@ -0,0 +1,254 @@ +import { 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() diff --git a/test/postcss.test.js b/test/postcss.test.js deleted file mode 100644 index ef8026f5c..000000000 --- a/test/postcss.test.js +++ /dev/null @@ -1,148 +0,0 @@ -let Processor = require('../lib/processor') -let postcss = require('../lib/postcss') - -it('creates plugins list', () => { - let processor = postcss() - expect(processor instanceof Processor).toBeTruthy() - expect(processor.plugins).toEqual([]) -}) - -it('saves plugins list', () => { - let a = () => 1 - let b = () => 2 - expect(postcss(a, b).plugins).toEqual([a, b]) -}) - -it('saves plugins list as array', () => { - let a = () => 1 - let b = () => 2 - expect(postcss([a, b]).plugins).toEqual([a, b]) -}) - -it('takes plugin from other processor', () => { - let a = () => 1 - let b = () => 2 - let c = () => 3 - let other = postcss([a, b]) - expect(postcss([other, c]).plugins).toEqual([a, b, c]) -}) - -it('supports injecting additional processors at runtime', () => { - let plugin1 = postcss.plugin('one', () => { - return css => { - css.walkDecls(decl => { - decl.value = 'world' - }) - } - }) - let plugin2 = postcss.plugin('two', () => { - return (css, result) => { - result.processor.use(plugin1()) - } - }) - - return postcss([plugin2]).process('a{hello: bob}', { from: undefined }) - .then(result => { - expect(result.css).toEqual('a{hello: world}') - }) -}) - -it('creates plugin', () => { - let plugin = postcss.plugin('test', filter => { - return root => { - root.walkDecls(filter || 'two', i => i.remove()) - } - }) - - let func1 = postcss(plugin).plugins[0] - expect(func1.postcssPlugin).toEqual('test') - expect(func1.postcssVersion).toMatch(/\d+.\d+.\d+/) - - let func2 = postcss(plugin()).plugins[0] - expect(func2.postcssPlugin).toEqual(func1.postcssPlugin) - expect(func2.postcssVersion).toEqual(func1.postcssVersion) - - let result1 = postcss(plugin('one')).process('a{ one: 1; two: 2 }') - expect(result1.css).toEqual('a{ two: 2 }') - - let result2 = postcss(plugin).process('a{ one: 1; two: 2 }') - expect(result2.css).toEqual('a{ one: 1 }') -}) - -it('does not call plugin constructor', () => { - let calls = 0 - let plugin = postcss.plugin('test', () => { - calls += 1 - return () => { } - }) - expect(calls).toBe(0) - - postcss(plugin).process('a{}') - expect(calls).toBe(1) - - postcss(plugin()).process('a{}') - expect(calls).toBe(2) -}) - -it('creates a shortcut to process css', () => { - let plugin = postcss.plugin('test', str => { - return root => { - root.walkDecls(i => { - i.value = str || 'bar' - }) - } - }) - - let result1 = plugin.process('a{value:foo}') - expect(result1.css).toEqual('a{value:bar}') - - let result2 = plugin.process('a{value:foo}', { }, 'baz') - expect(result2.css).toEqual('a{value:baz}') - - return plugin.process('a{value:foo}', { from: 'a' }, 'baz').then(result => { - expect(result.opts).toEqual({ from: 'a' }) - expect(result.css).toEqual('a{value:baz}') - }) -}) - -it('contains parser', () => { - expect(postcss.parse('').type).toEqual('root') -}) - -it('contains stringifier', () => { - expect(typeof postcss.stringify).toEqual('function') -}) - -it('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) - - expect(root.toString()).toEqual('/* Example */\n' + - '@media screen {\n' + - ' a {\n' + - ' color: black\n' + - ' }\n' + - '}\n') -}) - -it('contains vendor module', () => { - expect(postcss.vendor.prefix('-moz-tab')).toEqual('-moz-') -}) - -it('contains list module', () => { - expect(postcss.list.space('a b')).toEqual(['a', 'b']) -}) - -it('works with null', () => { - expect(() => { - postcss([() => true]).process(null).css - }).toThrowError(/PostCSS received null instead of CSS string/) -}) diff --git a/test/postcss.test.ts b/test/postcss.test.ts new file mode 100755 index 000000000..683aef570 --- /dev/null +++ b/test/postcss.test.ts @@ -0,0 +1,192 @@ +import 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() diff --git a/test/previous-map.test.js b/test/previous-map.test.js deleted file mode 100644 index cded1e2dc..000000000 --- a/test/previous-map.test.js +++ /dev/null @@ -1,209 +0,0 @@ -let mozilla = require('source-map') -let path = require('path') -let fs = require('fs-extra') - -let parse = require('../lib/parse') - -let dir = path.join(__dirname, 'prevmap-fixtures') -let mapObj = { - version: 3, - file: null, - sources: [], - names: [], - mappings: '' -} -let map = JSON.stringify(mapObj) - -afterEach(() => { - if (fs.existsSync(dir)) fs.removeSync(dir) -}) - -it('misses property if no map', () => { - expect(parse('a{}').source.input.map).not.toBeDefined() -}) - -it('creates property if map present', () => { - let root = parse('a{}', { map: { prev: map } }) - expect(root.source.input.map.text).toEqual(map) -}) - -it('returns consumer', () => { - let obj = parse('a{}', { map: { prev: map } }).source.input.map.consumer() - expect(obj instanceof mozilla.SourceMapConsumer).toBeTruthy() -}) - -it('sets annotation property', () => { - let mapOpts = { map: { prev: map } } - - let root1 = parse('a{}', mapOpts) - expect(root1.source.input.map.annotation).not.toBeDefined() - - let root2 = parse('a{}/*# sourceMappingURL=a.css.map */', mapOpts) - expect(root2.source.input.map.annotation).toEqual('a.css.map') -}) - -it('checks previous sources content', () => { - let map2 = { - version: 3, - file: 'b', - sources: ['a'], - names: [], - mappings: '' - } - - let opts = { map: { prev: map2 } } - expect(parse('a{}', opts).source.input.map.withContent()).toBe(false) - - map2.sourcesContent = ['a{}'] - expect(parse('a{}', opts).source.input.map.withContent()).toBe(true) -}) - -it('decodes base64 maps', () => { - let b64 = Buffer.from(map).toString('base64') - let css = 'a{}\n' + - `/*# sourceMappingURL=data:application/json;base64,${ b64 } */` - - expect(parse(css).source.input.map.text).toEqual(map) -}) - -it('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 + ' */' - - expect(parse(css).source.input.map.text).toEqual(map) -}) - -it('accepts different name for UTF-8 encoding', () => { - let b64 = Buffer.from(map).toString('base64') - let css = 'a{}\n/*# sourceMappingURL=data:application/json;' + - 'charset=utf8;base64,' + b64 + ' */' - - expect(parse(css).source.input.map.text).toEqual(map) -}) - -it('decodes URI maps', () => { - let uri = 'data:application/json,' + decodeURI(map) - let css = `a{}\n/*# sourceMappingURL=${ uri } */` - - expect(parse(css).source.input.map.text).toEqual(map) -}) - -it('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 - expect(input.map).not.toBeDefined() -}) - -it('raises on unknown inline encoding', () => { - let css = 'a { }\n/*# sourceMappingURL=data:application/json;' + - 'md5,68b329da9893e34099c7d8ad5cb9c940*/' - - expect(() => { - parse(css) - }).toThrowError('Unsupported source map encoding md5') -}) - -it('raises on unknown map format', () => { - expect(() => { - parse('a{}', { map: { prev: 1 } }) - }).toThrowError('Unsupported previous source map format: 1') -}) - -it('reads map from annotation', () => { - let file = path.join(dir, 'a.map') - fs.outputFileSync(file, map) - let root = parse('a{}\n/*# sourceMappingURL=a.map */', { from: file }) - - expect(root.source.input.map.text).toEqual(map) - expect(root.source.input.map.root).toEqual(dir) -}) - -it('reads only the last map from annotation', () => { - let file = path.join(dir, 'c.map') - fs.outputFileSync(file, map) - let root = parse('a{}' + - '\n/*# sourceMappingURL=a.map */' + - '\n/*# sourceMappingURL=b.map */' + - '\n/*# sourceMappingURL=c.map */', - { from: file }) - - expect(root.source.input.map.text).toEqual(map) - expect(root.source.input.map.root).toEqual(dir) -}) - -it('sets unique name for inline map', () => { - let map2 = { - version: 3, - sources: ['a'], - names: [], - mappings: '' - } - - let opts = { map: { prev: map2 } } - let file1 = parse('a{}', opts).source.input.map.file - let file2 = parse('a{}', opts).source.input.map.file - - expect(file1).toMatch(/^$/) - expect(file1).not.toEqual(file2) -}) - -it('accepts an empty mappings string', () => { - expect(() => { - let emptyMap = { - version: 3, - sources: [], - names: [], - mappings: '' - } - parse('body{}', { map: { prev: emptyMap } }) - }).not.toThrowError() -}) - -it('accepts a function', () => { - let css = 'body{}\n/*# sourceMappingURL=a.map */' - let file = path.join(dir, 'previous-sourcemap-function.map') - fs.outputFileSync(file, map) - let opts = { - map: { - prev: () => file - } - } - let root = parse(css, opts) - expect(root.source.input.map.text).toEqual(map) - expect(root.source.input.map.annotation).toEqual('a.map') -}) - -it('calls function with opts.from', () => { - expect.assertions(1) - - let css = 'body{}\n/*# sourceMappingURL=a.map */' - let file = path.join(dir, 'previous-sourcemap-function.map') - fs.outputFileSync(file, map) - let opts = { - from: 'a.css', - map: { - prev: from => { - expect(from).toEqual('a.css') - return file - } - } - } - parse(css, opts) -}) - -it('raises when function returns invalid path', () => { - let css = 'body{}\n/*# sourceMappingURL=a.map */' - let fakeMap = Number.MAX_SAFE_INTEGER.toString() + '.map' - let fakePath = path.join(dir, fakeMap) - let opts = { - map: { - prev: () => fakePath - } - } - expect(() => { - parse(css, opts) - }).toThrowError('Unable to load previous source map: ' + fakePath) -}) diff --git a/test/previous-map.test.ts b/test/previous-map.test.ts new file mode 100755 index 000000000..0f97abca8 --- /dev/null +++ b/test/previous-map.test.ts @@ -0,0 +1,365 @@ +import { + 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() diff --git a/test/processor.test.js b/test/processor.test.js deleted file mode 100644 index 50c7f3979..000000000 --- a/test/processor.test.js +++ /dev/null @@ -1,476 +0,0 @@ -let path = require('path') - -let LazyResult = require('../lib/lazy-result') -let Processor = require('../lib/processor') -let postcss = require('../lib/postcss') -let Result = require('../lib/result') -let parse = require('../lib/parse') -let Root = require('../lib/root') - -function prs () { - return new Root({ raws: { after: 'ok' } }) -} - -function str (node, builder) { - builder(node.raws.after + '!') -} - -let beforeFix = new Processor([css => { - css.walkRules(rule => { - if (!rule.selector.match(/::(before|after)/)) return - if (!rule.some(i => i.prop === 'content')) { - rule.prepend({ prop: 'content', value: '""' }) - } - }) -}]) - -it('adds new plugins', () => { - let a = () => 1 - let processor = new Processor() - processor.use(a) - expect(processor.plugins).toEqual([a]) -}) - -it('adds new plugin by object', () => { - let a = () => 1 - let processor = new Processor() - processor.use({ postcss: a }) - expect(processor.plugins).toEqual([a]) -}) - -it('adds new plugin by object-function', () => { - let a = () => 1 - let obj = () => 2 - obj.postcss = a - let processor = new Processor() - processor.use(obj) - expect(processor.plugins).toEqual([a]) -}) - -it('adds new processors of another postcss instance', () => { - let a = () => 1 - let processor = new Processor() - let other = new Processor([a]) - processor.use(other) - expect(processor.plugins).toEqual([a]) -}) - -it('adds new processors from object', () => { - let a = () => 1 - let processor = new Processor() - let other = new Processor([a]) - processor.use({ postcss: other }) - expect(processor.plugins).toEqual([a]) -}) - -it('returns itself', () => { - let a = () => 1 - let b = () => 2 - let processor = new Processor() - expect(processor.use(a).use(b).plugins).toEqual([a, b]) -}) - -it('throws on wrong format', () => { - let pr = new Processor() - expect(() => { - pr.use(1) - }).toThrowError(/1 is not a PostCSS plugin/) -}) - -it('processes CSS', () => { - let result = beforeFix.process('a::before{top:0}') - expect(result.css).toEqual('a::before{content:"";top:0}') -}) - -it('processes parsed AST', () => { - let root = parse('a::before{top:0}') - let result = beforeFix.process(root) - expect(result.css).toEqual('a::before{content:"";top:0}') -}) - -it('processes previous result', () => { - let result = (new Processor([() => true])).process('a::before{top:0}') - result = beforeFix.process(result) - expect(result.css).toEqual('a::before{content:"";top:0}') -}) - -it('takes maps from previous result', () => { - let one = (new Processor([() => true])).process('a{}', { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - let two = (new Processor([() => true])).process(one, { to: 'c.css' }) - expect(two.map.toJSON().sources).toEqual(['a.css']) -}) - -it('inlines maps from previous result', () => { - let one = (new Processor([() => true])).process('a{}', { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - let two = (new Processor([() => true])).process(one, { - to: 'c.css', - map: { inline: true } - }) - expect(two.map).not.toBeDefined() -}) - -it('throws with file name', () => { - let error - try { - (new Processor([() => true])).process('a {', { from: 'a.css' }).css - } catch (e) { - if (e.name === 'CssSyntaxError') { - error = e - } else { - throw e - } - } - - expect(error.file).toEqual(path.resolve('a.css')) - expect(error.message).toMatch(/a.css:1:1: Unclosed block$/) -}) - -it('allows to replace Root', () => { - let plugin = (css, result) => { - result.root = new Root() - } - let processor = new Processor([plugin]) - expect(processor.process('a {}').css).toEqual('') -}) - -it('returns LazyResult object', () => { - let result = (new Processor([() => true])).process('a{}') - expect(result instanceof LazyResult).toBeTruthy() - expect(result.css).toEqual('a{}') - expect(result.toString()).toEqual('a{}') -}) - -it('calls all plugins once', () => { - expect.assertions(1) - - let calls = '' - let a = () => { - calls += 'a' - } - let b = () => { - calls += 'b' - } - - let result = new Processor([a, b]).process('', { from: undefined }) - result.css - result.map - result.root - return result.then(() => { - expect(calls).toEqual('ab') - }) -}) - -it('parses, converts and stringifies CSS', () => { - let a = css => expect(css instanceof Root).toBeTruthy() - expect(typeof (new Processor([a])).process('a {}').css).toEqual('string') -}) - -it('send result to plugins', () => { - expect.assertions(4) - let processor = new Processor([() => true]) - let a = (css, result) => { - expect(result instanceof Result).toBeTruthy() - expect(result.processor).toEqual(processor) - expect(result.opts).toEqual({ map: true }) - expect(result.root).toEqual(css) - } - return processor.use(a).process('a {}', { map: true, from: undefined }) -}) - -it('accepts source map from PostCSS', () => { - let one = (new Processor([() => true])).process('a{}', { - from: 'a.css', - to: 'b.css', - map: { inline: false } - }) - let two = (new Processor([() => true])).process(one.css, { - from: 'b.css', - to: 'c.css', - map: { prev: one.map, inline: false } - }) - expect(two.map.toJSON().sources).toEqual(['a.css']) -}) - -it('supports async plugins', () => { - let starts = 0 - let finish = 0 - let async1 = css => { - return new Promise(resolve => { - starts += 1 - setTimeout(() => { - expect(starts).toEqual(1) - - css.append('a {}') - finish += 1 - resolve() - }, 1) - }) - } - let async2 = css => { - return new Promise(resolve => { - expect(starts).toEqual(1) - expect(finish).toEqual(1) - - starts += 1 - setTimeout(() => { - css.append('b {}') - finish += 1 - resolve() - }, 1) - }) - } - return (new Processor([async1, async2])).process('', { from: undefined }) - .then(result => { - expect(starts).toEqual(2) - expect(finish).toEqual(2) - expect(result.css).toEqual('a {}b {}') - }) -}) - -it('works async without plugins', () => { - return (new Processor([() => true])).process('a {}', { from: undefined }) - .then(result => { - expect(result.css).toEqual('a {}') - }) -}) - -it('runs async plugin only once', () => { - expect.assertions(1) - - let calls = 0 - let async = () => { - return new Promise(resolve => { - setTimeout(() => { - calls += 1 - resolve() - }, 1) - }) - } - - let result = (new Processor([async])).process('a {}', { from: undefined }) - result.then(() => { }) - return result.then(() => { - return result.then(() => { - expect(calls).toEqual(1) - }) - }) -}) - -it('supports async errors', done => { - let error = new Error('Async') - let async = () => { - return new Promise((resolve, reject) => { - reject(error) - }) - } - let result = (new Processor([async])).process('', { from: undefined }) - result.then(() => { - done.fail() - }).catch(err => { - expect(err).toEqual(error) - return result.catch(err2 => { - expect(err2).toEqual(error) - done() - }) - }) -}) - -it('supports sync errors in async mode', done => { - let error = new Error('Async') - let async = () => { - throw error - }; - (new Processor([async])).process('', { from: undefined }).then(() => { - done.fail() - }).catch(err => { - expect(err).toEqual(error) - done() - }) -}) - -it('throws parse error in async', () => { - return (new Processor([() => true])).process('a{').catch(err => { - expect(err.message).toEqual(':1:1: Unclosed block') - }) -}) - -it('throws error on sync method to async plugin', () => { - let async = () => { - return new Promise(resolve => resolve()) - } - expect(() => { - (new Processor([async])).process('a{}').css - }).toThrowError(/async/) -}) - -it('throws a sync call in async running', () => { - let async = () => new Promise(resolve => setTimeout(resolve, 1)) - - let processor = (new Processor([async])).process('a{}') - processor.async() - - expect(() => { - processor.sync() - }).toThrowError(/then/) -}) - -it('checks plugin compatibility', () => { - let plugin = postcss.plugin('test', () => { - return () => { - throw new Error('Er') - } - }) - let func = plugin() - func.postcssVersion = '2.1.5' - - let processBy = version => { - let processor = new Processor([func]) - processor.version = version - processor.process('a{}').css - } - - jest.spyOn(console, 'error').mockImplementation(() => true) - - expect(() => { - processBy('1.0.0') - }).toThrowError('Er') - expect(console.error.mock.calls).toHaveLength(1) - expect(console.error.mock.calls[0][0]).toEqual( - '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.' - ) - - expect(() => { - processBy('3.0.0') - }).toThrowError('Er') - expect(console.error.mock.calls).toHaveLength(2) - - expect(() => { - processBy('2.0.0') - }).toThrowError('Er') - expect(console.error.mock.calls).toHaveLength(3) - - expect(() => { - processBy('2.1.0') - }).toThrowError('Er') - expect(console.error.mock.calls).toHaveLength(3) -}) - -it('sets last plugin to result', () => { - let plugin1 = function (css, result) { - expect(result.lastPlugin).toBe(plugin1) - } - let plugin2 = function (css, result) { - expect(result.lastPlugin).toBe(plugin2) - } - - let processor = new Processor([plugin1, plugin2]) - return processor.process('a{}', { from: undefined }).then(result => { - expect(result.lastPlugin).toBe(plugin2) - }) -}) - -it('uses custom parsers', () => { - jest.spyOn(console, 'warn').mockImplementation(() => true) - let processor = new Processor([]) - return processor.process('a{}', { parser: prs, from: undefined }) - .then(result => { - expect(console.warn).not.toHaveBeenCalled() - expect(result.css).toEqual('ok') - }) -}) - -it('uses custom parsers from object', () => { - let processor = new Processor([]) - let syntax = { parse: prs, stringify: str } - return processor.process('a{}', { parser: syntax, from: undefined }) - .then(result => { - expect(result.css).toEqual('ok') - }) -}) - -it('uses custom stringifier', () => { - jest.spyOn(console, 'warn').mockImplementation(() => true) - let processor = new Processor([]) - return processor.process('a{}', { stringifier: str, from: undefined }) - .then(result => { - expect(console.warn).not.toHaveBeenCalled() - expect(result.css).toEqual('!') - }) -}) - -it('uses custom stringifier from object', () => { - let processor = new Processor([]) - let syntax = { parse: prs, stringify: str } - return processor.process('', { stringifier: syntax, from: undefined }) - .then(result => { - expect(result.css).toEqual('!') - }) -}) - -it('uses custom stringifier with source maps', () => { - let processor = new Processor([]) - return processor.process('a{}', { - map: true, stringifier: str, from: undefined - }).then(result => { - expect(result.css).toMatch(/!\n\/\*# sourceMap/) - }) -}) - -it('uses custom syntax', () => { - let processor = new Processor([() => true]) - return processor.process('a{}', { - syntax: { parse: prs, stringify: str }, from: undefined - }).then(result => { - expect(result.css).toEqual('ok!') - }) -}) - -it('contains PostCSS version', () => { - expect((new Processor()).version).toMatch(/\d+.\d+.\d+/) -}) - -it('throws on syntax as plugin', () => { - let processor = new Processor([() => true]) - expect(() => { - processor.use({ - parse () { } - }) - }).toThrowError(/syntax/) -}) - -it('warns about missed from', () => { - jest.spyOn(console, 'warn').mockImplementation(() => true) - let processor = new Processor([() => true]) - - processor.process('a{}').css - expect(console.warn).not.toBeCalled() - - return processor.process('a{}').then(() => { - expect(console.warn).toBeCalledWith( - '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.' - ) - }) -}) - -it('warns about missed plugins', () => { - jest.spyOn(console, 'warn').mockImplementation(() => true) - return (new Processor()).process('a{}').then(() => { - expect(console.warn).toBeCalledWith( - 'You did not set any plugins, parser, or stringifier. ' + - 'Right now, PostCSS does nothing. Pick plugins for your case ' + - 'on https://www.postcss.parts/ and use them in postcss.config.js.' - ) - }) -}) diff --git a/test/processor.test.ts b/test/processor.test.ts new file mode 100755 index 000000000..f1ed61831 --- /dev/null +++ b/test/processor.test.ts @@ -0,0 +1,640 @@ +// @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() diff --git a/test/result.test.js b/test/result.test.js deleted file mode 100644 index b580e78ce..000000000 --- a/test/result.test.js +++ /dev/null @@ -1,58 +0,0 @@ -let Warning = require('../lib/warning') -let postcss = require('../lib/postcss') -let Result = require('../lib/result') - -it('stringifies', () => { - let result = new Result() - result.css = 'a{}' - expect('' + result).toEqual(result.css) -}) - -it('adds warning', () => { - let warning - let plugin = postcss.plugin('test-plugin', () => { - return (css, res) => { - warning = res.warn('test', { node: css.first }) - } - }) - let result = postcss([plugin]).process('a{}').sync() - - expect(warning).toEqual(new Warning('test', { - plugin: 'test-plugin', - node: result.root.first - })) - - expect(result.messages).toEqual([warning]) -}) - -it('allows to override plugin', () => { - let plugin = postcss.plugin('test-plugin', () => { - return (css, res) => { - res.warn('test', { plugin: 'test-plugin#one' }) - } - }) - let result = postcss([plugin]).process('a{}').sync() - - expect(result.messages[0].plugin).toEqual('test-plugin#one') -}) - -it('allows Root', () => { - let result = new Result() - let root = postcss.parse('a{}') - result.warn('TT', { node: root }) - - expect(result.messages[0].toString()).toEqual(':1:1: TT') -}) - -it('returns only warnings', () => { - let result = new Result() - result.messages = [ - { type: 'warning', text: 'a' }, - { type: 'custom' }, - { type: 'warning', text: 'b' } - ] - expect(result.warnings()).toEqual([ - { type: 'warning', text: 'a' }, - { type: 'warning', text: 'b' } - ]) -}) diff --git a/test/result.test.ts b/test/result.test.ts new file mode 100755 index 000000000..e163e1787 --- /dev/null +++ b/test/result.test.ts @@ -0,0 +1,70 @@ +import { 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() diff --git a/test/root.test.js b/test/root.test.js deleted file mode 100644 index 532ca2a0f..000000000 --- a/test/root.test.js +++ /dev/null @@ -1,62 +0,0 @@ -let Result = require('../lib/result') -let parse = require('../lib/parse') - -it('prepend() fixes spaces on insert before first', () => { - let css = parse('a {} b {}') - css.prepend({ selector: 'em' }) - expect(css.toString()).toEqual('em {} a {} b {}') -}) - -it('prepend() fixes spaces on multiple inserts before first', () => { - let css = parse('a {} b {}') - css.prepend({ selector: 'em' }, { selector: 'strong' }) - expect(css.toString()).toEqual('em {} strong {} a {} b {}') -}) - -it('prepend() uses default spaces on only first', () => { - let css = parse('a {}') - css.prepend({ selector: 'em' }) - expect(css.toString()).toEqual('em {}\na {}') -}) - -it('append() sets new line between rules in multiline files', () => { - let a = parse('a {}\n\na {}\n') - let b = parse('b {}\n') - expect(a.append(b).toString()).toEqual('a {}\n\na {}\n\nb {}\n') -}) - -it('insertAfter() does not use before of first rule', () => { - let css = parse('a{} b{}') - css.insertAfter(0, { selector: '.a' }) - css.insertAfter(2, { selector: '.b' }) - - expect(css.nodes[1].raws.before).not.toBeDefined() - expect(css.nodes[3].raws.before).toEqual(' ') - expect(css.toString()).toEqual('a{} .a{} b{} .b{}') -}) - -it('fixes spaces on removing first rule', () => { - let css = parse('a{}\nb{}\n') - css.first.remove() - expect(css.toString()).toEqual('b{}\n') -}) - -it('keeps spaces on moving root', () => { - let css1 = parse('a{}\nb{}\n') - - let css2 = parse('') - css2.append(css1) - expect(css2.toString()).toEqual('a{}\nb{}') - - let css3 = parse('\n') - css3.append(css2.nodes) - expect(css3.toString()).toEqual('a{}\nb{}\n') -}) - -it('generates result with map', () => { - let root = parse('a {}') - let result = root.toResult({ map: true }) - - expect(result instanceof Result).toBeTruthy() - expect(result.css).toMatch(/a \{\}\n\/\*# sourceMappingURL=/) -}) diff --git a/test/root.test.ts b/test/root.test.ts new file mode 100755 index 000000000..fdf312329 --- /dev/null +++ b/test/root.test.ts @@ -0,0 +1,67 @@ +import { 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() diff --git a/test/rule.test.js b/test/rule.test.js deleted file mode 100644 index a394f1d2c..000000000 --- a/test/rule.test.js +++ /dev/null @@ -1,80 +0,0 @@ -let parse = require('../lib/parse') -let Rule = require('../lib/rule') - -it('initializes with properties', () => { - let rule = new Rule({ selector: 'a' }) - expect(rule.selector).toEqual('a') -}) - -it('returns array in selectors', () => { - let rule = new Rule({ selector: 'a,b' }) - expect(rule.selectors).toEqual(['a', 'b']) -}) - -it('trims selectors', () => { - let rule = new Rule({ selector: '.a\n, .b , .c' }) - expect(rule.selectors).toEqual(['.a', '.b', '.c']) -}) - -it('is smart about selectors commas', () => { - let rule = new Rule({ - selector: '[foo=\'a, b\'], a:-moz-any(:focus, [href*=\',\'])' - }) - expect(rule.selectors).toEqual([ - '[foo=\'a, b\']', - 'a:-moz-any(:focus, [href*=\',\'])' - ]) -}) - -it('receive array in selectors', () => { - let rule = new Rule({ selector: 'i, b' }) - rule.selectors = ['em', 'strong'] - expect(rule.selector).toEqual('em, strong') -}) - -it('saves separator in selectors', () => { - let rule = new Rule({ selector: 'i,\nb' }) - rule.selectors = ['em', 'strong'] - expect(rule.selector).toEqual('em,\nstrong') -}) - -it('uses between to detect separator in selectors', () => { - let rule = new Rule({ selector: 'b', raws: { between: '' } }) - rule.selectors = ['b', 'strong'] - expect(rule.selector).toEqual('b,strong') -}) - -it('uses space in separator be default in selectors', () => { - let rule = new Rule({ selector: 'b' }) - rule.selectors = ['b', 'strong'] - expect(rule.selector).toEqual('b, strong') -}) - -it('selectors works in constructor', () => { - let rule = new Rule({ selectors: ['a', 'b'] }) - expect(rule.selector).toEqual('a, b') -}) - -it('inserts default spaces', () => { - let rule = new Rule({ selector: 'a' }) - expect(rule.toString()).toEqual('a {}') - rule.append({ prop: 'color', value: 'black' }) - expect(rule.toString()).toEqual('a {\n color: black\n}') -}) - -it('clones spaces from another rule', () => { - let root = parse('b{\n }') - let rule = new Rule({ selector: 'em' }) - root.append(rule) - expect(root.toString()).toEqual('b{\n }\nem{\n }') -}) - -it('uses different spaces for empty rules', () => { - let root = parse('a{}\nb{\n a:1\n}') - let rule = new Rule({ selector: 'em' }) - root.append(rule) - expect(root.toString()).toEqual('a{}\nb{\n a:1\n}\nem{}') - - rule.append({ prop: 'top', value: '0' }) - expect(root.toString()).toEqual('a{}\nb{\n a:1\n}\nem{\n top:0\n}') -}) diff --git a/test/rule.test.ts b/test/rule.test.ts new file mode 100755 index 000000000..c2887a093 --- /dev/null +++ b/test/rule.test.ts @@ -0,0 +1,81 @@ +import { 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() diff --git a/test/stringifier.test.js b/test/stringifier.test.js old mode 100644 new mode 100755 index ba2a166a5..86ddf2b9c --- a/test/stringifier.test.js +++ b/test/stringifier.test.js @@ -1,173 +1,288 @@ +let { 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 Declaration = require('../lib/declaration') -let AtRule = require('../lib/at-rule') -let parse = require('../lib/parse') -let Node = require('../lib/node') -let Root = require('../lib/root') -let Rule = require('../lib/rule') let str -beforeAll(() => { + +test.before.each(() => { str = new Stringifier() }) -it('creates trimmed/raw property', () => { +test('creates trimmed/raw property', () => { let b = new Node({ one: 'trim' }) - b.raws.one = { value: 'trim', raw: 'raw' } - expect(str.rawValue(b, 'one')).toEqual('raw') + b.raws.one = { raw: 'raw', value: 'trim' } + is(str.rawValue(b, 'one'), 'raw') b.one = 'trim1' - expect(str.rawValue(b, 'one')).toEqual('trim1') + is(str.rawValue(b, 'one'), 'trim1') }) -it('works without rawValue magic', () => { +test('works without rawValue magic', () => { let b = new Node() b.one = '1' - expect(b.one).toEqual('1') - expect(str.rawValue(b, 'one')).toEqual('1') + is(b.one, '1') + is(str.rawValue(b, 'one'), '1') }) -it('uses node raw', () => { - let rule = new Rule({ selector: 'a', raws: { between: '\n' } }) - expect(str.raw(rule, 'between', 'beforeOpen')).toEqual('\n') +test('uses node raw', () => { + let rule = new Rule({ raws: { between: '\n' }, selector: 'a' }) + is(str.raw(rule, 'between', 'beforeOpen'), '\n') }) -it('hacks before for nodes without parent', () => { +test('hacks before for nodes without parent', () => { let rule = new Rule({ selector: 'a' }) - expect(str.raw(rule, 'before')).toEqual('') + is(str.raw(rule, 'before'), '') }) -it('hacks before for first node', () => { +test('hacks before for first node', () => { let root = new Root() root.append(new Rule({ selector: 'a' })) - expect(str.raw(root.first, 'before')).toEqual('') + is(str.raw(root.first, 'before'), '') }) -it('hacks before for first decl', () => { +test('hacks before for first decl', () => { let decl = new Declaration({ prop: 'color', value: 'black' }) - expect(str.raw(decl, 'before')).toEqual('') + is(str.raw(decl, 'before'), '') let rule = new Rule({ selector: 'a' }) rule.append(decl) - expect(str.raw(decl, 'before')).toEqual('\n ') + is(str.raw(decl, 'before'), '\n ') }) -it('detects after raw', () => { +test('detects after raw', () => { let root = new Root() - root.append({ selector: 'a', raws: { after: ' ' } }) + root.append({ raws: { after: ' ' }, selector: 'a' }) root.first.append({ prop: 'color', value: 'black' }) root.append({ selector: 'a' }) - expect(str.raw(root.last, 'after')).toEqual(' ') + is(str.raw(root.last, 'after'), ' ') }) -it('uses defaults without parent', () => { +test('uses defaults without parent', () => { let rule = new Rule({ selector: 'a' }) - expect(str.raw(rule, 'between', 'beforeOpen')).toEqual(' ') + is(str.raw(rule, 'between', 'beforeOpen'), ' ') }) -it('uses defaults for unique node', () => { +test('uses defaults for unique node', () => { let root = new Root() root.append(new Rule({ selector: 'a' })) - expect(str.raw(root.first, 'between', 'beforeOpen')).toEqual(' ') + is(str.raw(root.first, 'between', 'beforeOpen'), ' ') }) -it('clones raw from first node', () => { +test('clones raw from first node', () => { let root = new Root() - root.append(new Rule({ selector: 'a', raws: { between: '' } })) + root.append(new Rule({ raws: { between: '' }, selector: 'a' })) root.append(new Rule({ selector: 'b' })) - expect(str.raw(root.last, 'between', 'beforeOpen')).toEqual('') + is(str.raw(root.last, 'between', 'beforeOpen'), '') }) -it('indents by default', () => { +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' }) - expect(root.toString()).toEqual('@page {\n' + - ' a {\n' + - ' color: black\n' + - ' }\n' + - '}') + is( + root.toString(), + '@page {\n' + ' a {\n' + ' color: black\n' + ' }\n' + '}' + ) }) -it('clones style', () => { +test('clones style', () => { let compress = parse('@page{ a{ } }') let spaces = parse('@page {\n a {\n }\n}') compress.first.first.append({ prop: 'color', value: 'black' }) - expect(compress.toString()).toEqual('@page{ a{ color: black } }') + is(compress.toString(), '@page{ a{ color: black } }') spaces.first.first.append({ prop: 'color', value: 'black' }) - expect(spaces.toString()) - .toEqual('@page {\n a {\n color: black\n }\n}') + is(spaces.toString(), '@page {\n a {\n color: black\n }\n}') }) -it('clones indent', () => { +test('clones indent', () => { let root = parse('a{\n}') root.first.append({ text: 'a' }) - root.first.append({ text: 'b', raws: { before: '\n\n ' } }) - expect(root.toString()).toEqual('a{\n\n /* a */\n\n /* b */\n}') + root.first.append({ raws: { before: '\n\n ' }, text: 'b' }) + is(root.toString(), 'a{\n\n /* a */\n\n /* b */\n}') }) -it('clones declaration before for comment', () => { +test('clones declaration before for comment', () => { let root = parse('a{\n}') root.first.append({ text: 'a' }) root.first.append({ prop: 'a', - value: '1', - raws: { before: '\n\n ' } + raws: { before: '\n\n ' }, + value: '1' }) - expect(root.toString()).toEqual('a{\n\n /* a */\n\n a: 1\n}') + is(root.toString(), 'a{\n\n /* a */\n\n a: 1\n}') }) -it('clones indent by types', () => { +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' }) - expect(css.last.first.raw('before')).toEqual('\n ') + is(css.last.first.raw('before'), '\n ') }) -it('ignores non-space symbols in indent cloning', () => { +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' }) - expect(css.last.raw('before')).toEqual('\n\n') - expect(css.last.first.raw('before')).toEqual('\n ') + is(css.last.raw('before'), '\n\n') + is(css.last.first.raw('before'), '\n ') }) -it('clones indent by before and after', () => { +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' }) - expect(css.first.last.raw('before')).toEqual('\n\n ') - expect(css.first.last.raw('after')).toEqual('') + is(css.first.last.raw('before'), '\n\n ') + is(css.first.last.raw('after'), '') }) -it('clones semicolon only from rules with children', () => { +test('clones semicolon only from rules with children', () => { let css = parse('a{}b{one:1;}') - expect(str.raw(css.first, 'semicolon')).toBeTruthy() + is(str.raw(css.first, 'semicolon'), true) }) -it('clones only spaces in before', () => { +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' }) - expect(css.toString()).toEqual('a{*one:1;two:2}\n@keyframes a{\nfrom{}}') + is(css.toString(), 'a{*one:1;two:2}\n@keyframes a{\nfrom{}}') }) -it('clones only spaces in between', () => { +test('clones only spaces in between', () => { let css = parse('a{one/**/:1}') css.first.append({ prop: 'two', value: '2' }) - expect(css.toString()).toEqual('a{one/**/:1;two:2}') + is(css.toString(), 'a{one/**/:1;two:2}') }) -it('uses optional raws.indent', () => { - let rule = new Rule({ selector: 'a', raws: { indent: ' ' } }) +test('uses optional raws.indent', () => { + let rule = new Rule({ raws: { indent: ' ' }, selector: 'a' }) rule.append({ prop: 'color', value: 'black' }) - expect(rule.toString()).toEqual('a {\n color: black\n}') + 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() diff --git a/test/stringify.test.js b/test/stringify.test.js deleted file mode 100644 index 6aac68a19..000000000 --- a/test/stringify.test.js +++ /dev/null @@ -1,18 +0,0 @@ -let cases = require('postcss-parser-tests') - -let stringify = require('../lib/stringify') -let parse = require('../lib/parse') - -cases.each((name, css) => { - if (name === 'bom.css') return - if (name === 'apply.css') return - - it('stringifies ' + name, () => { - let root = parse(css) - let result = '' - stringify(root, i => { - result += i - }) - expect(result).toEqual(css) - }) -}) diff --git a/test/stringify.test.ts b/test/stringify.test.ts new file mode 100755 index 000000000..784d15031 --- /dev/null +++ b/test/stringify.test.ts @@ -0,0 +1,20 @@ +import { 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() diff --git a/test/tokenize.test.js b/test/tokenize.test.js old mode 100644 new mode 100755 index 31e23c005..4b0a6702c --- a/test/tokenize.test.js +++ b/test/tokenize.test.js @@ -1,7 +1,10 @@ +let { test } = require('uvu') +let { equal, is, throws } = require('uvu/assert') + let tokenizer = require('../lib/tokenize') -let Input = require('../lib/input') +let { Input } = require('../lib/postcss') -function tokenize (css, opts) { +function tokenize(css, opts) { let processor = tokenizer(new Input(css), opts) let tokens = [] while (!processor.endOfFile()) { @@ -10,268 +13,286 @@ function tokenize (css, opts) { return tokens } -function run (css, tokens, opts) { - expect(tokenize(css, opts)).toEqual(tokens) +function run(css, tokens, opts) { + equal(tokenize(css, opts), tokens) } -it('tokenizes empty file', () => { +test('tokenizes empty file', () => { run('', []) }) -it('tokenizes space', () => { +test('tokenizes space', () => { run('\r\n \f\t', [['space', '\r\n \f\t']]) }) -it('tokenizes word', () => { - run('ab', [['word', 'ab', 1, 1, 1, 2]]) +test('tokenizes word', () => { + run('ab', [['word', 'ab', 0, 1]]) }) -it('splits word by !', () => { +test('splits word by !', () => { run('aa!bb', [ - ['word', 'aa', 1, 1, 1, 2], - ['word', '!bb', 1, 3, 1, 5] + ['word', 'aa', 0, 1], + ['word', '!bb', 2, 4] ]) }) -it('changes lines in spaces', () => { +test('changes lines in spaces', () => { run('a \n b', [ - ['word', 'a', 1, 1, 1, 1], + ['word', 'a', 0, 0], ['space', ' \n '], - ['word', 'b', 2, 2, 2, 2] + ['word', 'b', 4, 4] ]) }) -it('tokenizes control chars', () => { +test('tokenizes control chars', () => { run('{:;}', [ - ['{', '{', 1, 1], - [':', ':', 1, 2], - [';', ';', 1, 3], - ['}', '}', 1, 4] + ['{', '{', 0], + [':', ':', 1], + [';', ';', 2], + ['}', '}', 3] ]) }) -it('escapes control symbols', () => { +test('escapes control symbols', () => { run('\\(\\{\\"\\@\\\\""', [ - ['word', '\\(', 1, 1, 1, 2], - ['word', '\\{', 1, 3, 1, 4], - ['word', '\\"', 1, 5, 1, 6], - ['word', '\\@', 1, 7, 1, 8], - ['word', '\\\\', 1, 9, 1, 10], - ['string', '""', 1, 11, 1, 12] + ['word', '\\(', 0, 1], + ['word', '\\{', 2, 3], + ['word', '\\"', 4, 5], + ['word', '\\@', 6, 7], + ['word', '\\\\', 8, 9], + ['string', '""', 10, 11] ]) }) -it('escapes backslash', () => { +test('escapes backslash', () => { run('\\\\\\\\{', [ - ['word', '\\\\\\\\', 1, 1, 1, 4], - ['{', '{', 1, 5] + ['word', '\\\\\\\\', 0, 3], + ['{', '{', 4] ]) }) -it('tokenizes simple brackets', () => { - run('(ab)', [['brackets', '(ab)', 1, 1, 1, 4]]) +test('tokenizes simple brackets', () => { + run('(ab)', [['brackets', '(ab)', 0, 3]]) }) -it('tokenizes square brackets', () => { +test('tokenizes square brackets', () => { run('a[bc]', [ - ['word', 'a', 1, 1, 1, 1], - ['[', '[', 1, 2], - ['word', 'bc', 1, 3, 1, 4], - [']', ']', 1, 5] + ['word', 'a', 0, 0], + ['[', '[', 1], + ['word', 'bc', 2, 3], + [']', ']', 4] ]) }) -it('tokenizes complicated brackets', () => { +test('tokenizes complicated brackets', () => { run('(())("")(/**/)(\\\\)(\n)(', [ - ['(', '(', 1, 1], - ['brackets', '()', 1, 2, 1, 3], - [')', ')', 1, 4], - ['(', '(', 1, 5], - ['string', '""', 1, 6, 1, 7], - [')', ')', 1, 8], - ['(', '(', 1, 9], - ['comment', '/**/', 1, 10, 1, 13], - [')', ')', 1, 14], - ['(', '(', 1, 15], - ['word', '\\\\', 1, 16, 1, 17], - [')', ')', 1, 18], - ['(', '(', 1, 19], + ['(', '(', 0], + ['brackets', '()', 1, 2], + [')', ')', 3], + ['(', '(', 4], + ['string', '""', 5, 6], + [')', ')', 7], + ['(', '(', 8], + ['comment', '/**/', 9, 12], + [')', ')', 13], + ['(', '(', 14], + ['word', '\\\\', 15, 16], + [')', ')', 17], + ['(', '(', 18], ['space', '\n'], - [')', ')', 2, 1], - ['(', '(', 2, 2] + [')', ')', 20], + ['(', '(', 21] ]) }) -it('tokenizes string', () => { +test('tokenizes string', () => { run('\'"\'"\\""', [ - ['string', '\'"\'', 1, 1, 1, 3], - ['string', '"\\""', 1, 4, 1, 7] + ['string', "'\"'", 0, 2], + ['string', '"\\""', 3, 6] ]) }) -it('tokenizes escaped string', () => { - run('"\\\\"', [['string', '"\\\\"', 1, 1, 1, 4]]) +test('tokenizes escaped string', () => { + run('"\\\\"', [['string', '"\\\\"', 0, 3]]) }) -it('changes lines in strings', () => { +test('changes lines in strings', () => { run('"\n\n""\n\n"', [ - ['string', '"\n\n"', 1, 1, 3, 1], - ['string', '"\n\n"', 3, 2, 5, 1] + ['string', '"\n\n"', 0, 3], + ['string', '"\n\n"', 4, 7] ]) }) -it('tokenizes at-word', () => { - run('@word ', [['at-word', '@word', 1, 1, 1, 5], ['space', ' ']]) +test('tokenizes at-word', () => { + run('@word ', [ + ['at-word', '@word', 0, 4], + ['space', ' '] + ]) }) -it('tokenizes at-word end', () => { +test('tokenizes at-word end', () => { run('@one{@two()@three""@four;', [ - ['at-word', '@one', 1, 1, 1, 4], - ['{', '{', 1, 5], - ['at-word', '@two', 1, 6, 1, 9], - ['brackets', '()', 1, 10, 1, 11], - ['at-word', '@three', 1, 12, 1, 17], - ['string', '""', 1, 18, 1, 19], - ['at-word', '@four', 1, 20, 1, 24], - [';', ';', 1, 25] + ['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] ]) }) -it('tokenizes urls', () => { +test('tokenizes urls', () => { run('url(/*\\))', [ - ['word', 'url', 1, 1, 1, 3], - ['brackets', '(/*\\))', 1, 4, 1, 9] + ['word', 'url', 0, 2], + ['brackets', '(/*\\))', 3, 8] ]) }) -it('tokenizes quoted urls', () => { +test('tokenizes quoted urls', () => { run('url(")")', [ - ['word', 'url', 1, 1, 1, 3], - ['(', '(', 1, 4], - ['string', '")"', 1, 5, 1, 7], - [')', ')', 1, 8] + ['word', 'url', 0, 2], + ['(', '(', 3], + ['string', '")"', 4, 6], + [')', ')', 7] ]) }) -it('tokenizes at-symbol', () => { - run('@', [['at-word', '@', 1, 1, 1, 1]]) +test('tokenizes at-symbol', () => { + run('@', [['at-word', '@', 0, 0]]) }) -it('tokenizes comment', () => { - run('/* a\nb */', [['comment', '/* a\nb */', 1, 1, 2, 4]]) +test('tokenizes comment', () => { + run('/* a\nb */', [['comment', '/* a\nb */', 0, 8]]) }) -it('changes lines in comments', () => { +test('changes lines in comments', () => { run('a/* \n */b', [ - ['word', 'a', 1, 1, 1, 1], - ['comment', '/* \n */', 1, 2, 2, 3], - ['word', 'b', 2, 4, 2, 4] + ['word', 'a', 0, 0], + ['comment', '/* \n */', 1, 7], + ['word', 'b', 8, 8] ]) }) -it('supports line feed', () => { +test('supports line feed', () => { run('a\fb', [ - ['word', 'a', 1, 1, 1, 1], + ['word', 'a', 0, 0], ['space', '\f'], - ['word', 'b', 2, 1, 2, 1] + ['word', 'b', 2, 2] ]) }) -it('supports carriage return', () => { +test('supports carriage return', () => { run('a\rb\r\nc', [ - ['word', 'a', 1, 1, 1, 1], + ['word', 'a', 0, 0], ['space', '\r'], - ['word', 'b', 2, 1, 2, 1], + ['word', 'b', 2, 2], ['space', '\r\n'], - ['word', 'c', 3, 1, 3, 1] + ['word', 'c', 5, 5] ]) }) -it('tokenizes CSS', () => { - let css = 'a {\n' + - ' content: "a";\n' + - ' width: calc(1px;)\n' + - ' }\n' + - '/* small screen */\n' + - '@media screen {}' +test('tokenizes CSS', () => { + let css = + 'a {\n' + + ' content: "a";\n' + + ' width: calc(1px;)\n' + + ' }\n' + + '/* small screen */\n' + + '@media screen {}' run(css, [ - ['word', 'a', 1, 1, 1, 1], + ['word', 'a', 0, 0], ['space', ' '], - ['{', '{', 1, 3], + ['{', '{', 2], ['space', '\n '], - ['word', 'content', 2, 3, 2, 9], - [':', ':', 2, 10], + ['word', 'content', 6, 12], + [':', ':', 13], ['space', ' '], - ['string', '"a"', 2, 12, 2, 14], - [';', ';', 2, 15], + ['string', '"a"', 15, 17], + [';', ';', 18], ['space', '\n '], - ['word', 'width', 3, 3, 3, 7], - [':', ':', 3, 8], + ['word', 'width', 22, 26], + [':', ':', 27], ['space', ' '], - ['word', 'calc', 3, 10, 3, 13], - ['brackets', '(1px;)', 3, 14, 3, 19], + ['word', 'calc', 29, 32], + ['brackets', '(1px;)', 33, 38], ['space', '\n '], - ['}', '}', 4, 3], + ['}', '}', 42], ['space', '\n'], - ['comment', '/* small screen */', 5, 1, 5, 18], + ['comment', '/* small screen */', 44, 61], ['space', '\n'], - ['at-word', '@media', 6, 1, 6, 6], + ['at-word', '@media', 63, 68], ['space', ' '], - ['word', 'screen', 6, 8, 6, 13], + ['word', 'screen', 70, 75], ['space', ' '], - ['{', '{', 6, 15], - ['}', '}', 6, 16] + ['{', '{', 77], + ['}', '}', 78] ]) }) -it('throws error on unclosed string', () => { - expect(() => { +test('throws error on unclosed string', () => { + throws(() => { tokenize(' "') - }).toThrowError(/:1:2: Unclosed string/) + }, /:1:2: Unclosed string/) }) -it('throws error on unclosed comment', () => { - expect(() => { +test('throws error on unclosed comment', () => { + throws(() => { tokenize(' /*') - }).toThrowError(/:1:2: Unclosed comment/) + }, /:1:2: Unclosed comment/) }) -it('throws error on unclosed url', () => { - expect(() => { +test('throws error on unclosed url', () => { + throws(() => { tokenize('url(') - }).toThrowError(/:1:4: Unclosed bracket/) -}) - -it('ignores unclosing string on request', () => { - run(' "', [ - ['space', ' '], ['string', '"', 1, 2, 1, 3] - ], { ignoreErrors: true }) -}) - -it('ignores unclosing comment on request', () => { - run(' /*', [ - ['space', ' '], ['comment', '/*', 1, 2, 1, 4] - ], { ignoreErrors: true }) -}) - -it('ignores unclosing function on request', () => { - run('url(', [ - ['word', 'url', 1, 1, 1, 3], - ['brackets', '(', 1, 4, 1, 4] - ], { ignoreErrors: true }) -}) - -it('tokenizes hexadecimal escape', () => { + }, /: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 ', 1, 1, 1, 4], - ['word', '\\09 ', 1, 5, 1, 8], - ['word', '\\z', 1, 9, 1, 10], + ['word', '\\0a ', 0, 3], + ['word', '\\09 ', 4, 7], + ['word', '\\z', 8, 9], ['space', ' '] ]) }) -it('ignore unclosed per token request', () => { - function tokn (css, opts) { +test('ignore unclosed per token request', () => { + function token(css, opts) { let processor = tokenizer(new Input(css), opts) let tokens = [] while (!processor.endOfFile()) { @@ -280,30 +301,34 @@ it('ignore unclosed per token request', () => { return tokens } - let css = `How's it going (` - let tokens = tokn(css, {}) - let expected = [['word', 'How', 1, 1, 1, 3], - ['string', "'s", 1, 4, 1, 5], + let css = "How's it going (" + let tokens = token(css, {}) + let expected = [ + ['word', 'How', 0, 2], + ['string', "'s", 3, 4], ['space', ' '], - ['word', 'it', 1, 7, 1, 8], + ['word', 'it', 6, 7], ['space', ' '], - ['word', 'going', 1, 10, 1, 14], + ['word', 'going', 9, 13], ['space', ' '], - ['(', '(', 1, 16]] + ['(', '(', 15] + ] - expect(tokens).toEqual(expected) + equal(tokens, expected) }) -it('provides correct position', () => { - let css = `Three tokens` +test('provides correct position', () => { + let css = 'Three tokens' let processor = tokenizer(new Input(css)) - expect(processor.position()).toEqual(0) + is(processor.position(), 0) processor.nextToken() - expect(processor.position()).toEqual(5) + is(processor.position(), 5) processor.nextToken() - expect(processor.position()).toEqual(6) + is(processor.position(), 6) processor.nextToken() - expect(processor.position()).toEqual(12) + is(processor.position(), 12) processor.nextToken() - expect(processor.position()).toEqual(12) + is(processor.position(), 12) }) + +test.run() diff --git a/test/types.ts b/test/types.ts new file mode 100644 index 000000000..4b7cbccf1 --- /dev/null +++ b/test/types.ts @@ -0,0 +1,33 @@ +import 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`) + 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 diff --git a/test/vendor.test.js b/test/vendor.test.js deleted file mode 100644 index 466d0c7a6..000000000 --- a/test/vendor.test.js +++ /dev/null @@ -1,15 +0,0 @@ -let vendor = require('../lib/vendor') - -const VALUE = '-1px -1px 1px rgba(0, 0, 0, 0.2) inset' - -it('returns prefix', () => { - expect(vendor.prefix('-moz-color')).toEqual('-moz-') - expect(vendor.prefix('color')).toEqual('') - expect(vendor.prefix(VALUE)).toEqual('') -}) - -it('returns unprefixed version', () => { - expect(vendor.unprefixed('-moz-color')).toEqual('color') - expect(vendor.unprefixed('color')).toEqual('color') - expect(vendor.unprefixed(VALUE)).toEqual(VALUE) -}) diff --git a/test/version.js b/test/version.js new file mode 100755 index 000000000..0934db2c8 --- /dev/null +++ b/test/version.js @@ -0,0 +1,9 @@ +#!/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') +} diff --git a/test/visitor.test.ts b/test/visitor.test.ts new file mode 100755 index 000000000..251a64ca2 --- /dev/null +++ b/test/visitor.test.ts @@ -0,0 +1,1604 @@ +// @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) + }) +} + +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() diff --git a/test/warning.test.js b/test/warning.test.js deleted file mode 100644 index 4c8a579ab..000000000 --- a/test/warning.test.js +++ /dev/null @@ -1,86 +0,0 @@ -let path = require('path') - -let Declaration = require('../lib/declaration') -let Warning = require('../lib/warning') -let parse = require('../lib/parse') - -it('outputs simple warning', () => { - let warning = new Warning('text') - expect(warning.toString()).toEqual('text') -}) - -it('outputs warning with plugin', () => { - let warning = new Warning('text', { plugin: 'plugin' }) - expect(warning.toString()).toEqual('plugin: text') -}) - -it('outputs warning with position', () => { - let root = parse('a{}') - let warning = new Warning('text', { node: root.first }) - expect(warning.toString()).toEqual(':1:1: text') -}) - -it('outputs warning with plugin and node', () => { - let file = path.resolve('a.css') - let root = parse('a{}', { from: file }) - let warning = new Warning('text', { - plugin: 'plugin', - node: root.first - }) - expect(warning.toString()).toEqual(`plugin: ${ file }:1:1: text`) -}) - -it('outputs warning with index', () => { - let file = path.resolve('a.css') - let root = parse('@rule param {}', { from: file }) - let warning = new Warning('text', { - plugin: 'plugin', - node: root.first, - index: 7 - }) - expect(warning.toString()).toEqual(`plugin: ${ file }:1:8: text`) -}) - -it('outputs warning with word', () => { - let file = path.resolve('a.css') - let root = parse('@rule param {}', { from: file }) - let warning = new Warning('text', { - plugin: 'plugin', - node: root.first, - word: 'am' - }) - expect(warning.toString()).toEqual(`plugin: ${ file }:1:10: text`) -}) - -it('generates warning without source', () => { - let decl = new Declaration({ prop: 'color', value: 'black' }) - let warning = new Warning('text', { node: decl }) - expect(warning.toString()).toEqual(': text') -}) - -it('has line and column is undefined by default', () => { - let warning = new Warning('text') - expect(warning.line).not.toBeDefined() - expect(warning.column).not.toBeDefined() -}) - -it('gets position from node', () => { - let root = parse('a{}') - let warning = new Warning('text', { node: root.first }) - expect(warning.line).toEqual(1) - expect(warning.column).toEqual(1) -}) - -it('gets position from word', () => { - let root = parse('a b{}') - let warning = new Warning('text', { node: root.first, word: 'b' }) - expect(warning.line).toEqual(1) - expect(warning.column).toEqual(3) -}) - -it('gets position from index', () => { - let root = parse('a b{}') - let warning = new Warning('text', { node: root.first, index: 2 }) - expect(warning.line).toEqual(1) - expect(warning.column).toEqual(3) -}) diff --git a/test/warning.test.ts b/test/warning.test.ts new file mode 100644 index 000000000..be3e6a58d --- /dev/null +++ b/test/warning.test.ts @@ -0,0 +1,170 @@ +import { 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 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() diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..8341d6de1 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "lib": ["es2018"], + "target": "es2018", + "module": "commonjs", + "strict": true, + "noEmit": true + } +} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 1a309fca1..000000000 --- a/yarn.lock +++ /dev/null @@ -1,7483 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" - integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== - dependencies: - browserslist "^4.12.0" - invariant "^2.2.4" - semver "^5.5.0" - -"@babel/core@^7.1.0": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.3.tgz#198d6d3af4567be3989550d97e068de94503074f" - integrity sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.4.0" - "@babel/helpers" "^7.4.3" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.11" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/core@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.0.0", "@babel/generator@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.0.tgz#c230e79589ae7a729fd4631b9ded4dc220418196" - integrity sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ== - dependencies: - "@babel/types" "^7.4.0" - jsesc "^2.5.1" - lodash "^4.17.11" - source-map "^0.5.0" - trim-right "^1.0.1" - -"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== - dependencies: - "@babel/types" "^7.11.5" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" - integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-compilation-targets@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" - integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== - dependencies: - "@babel/compat-data" "^7.10.4" - browserslist "^4.12.0" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/helper-create-class-features-plugin@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" - integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.10.5" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - -"@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" - -"@babel/helper-define-map@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" - integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/types" "^7.10.5" - lodash "^4.17.19" - -"@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-function-name@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" - integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== - dependencies: - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-get-function-arity@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" - integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-hoist-variables@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" - integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/template" "^7.10.4" - "@babel/types" "^7.11.0" - lodash "^4.17.19" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== - -"@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" - -"@babel/helper-remap-async-to-generator@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" - integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-wrap-function" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" - integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-split-export-declaration@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz#571bfd52701f492920d63b7f735030e9a3e10b55" - integrity sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw== - dependencies: - "@babel/types" "^7.4.0" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helper-wrap-function@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" - integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helpers@^7.4.3": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.3.tgz#7b1d354363494b31cb9a2417ae86af32b7853a3b" - integrity sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q== - dependencies: - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - -"@babel/highlight@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" - integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.0", "@babel/parser@^7.4.3": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.3.tgz#eb3ac80f64aa101c907d4ce5406360fe75b7895b" - integrity sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ== - -"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.7.0": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - -"@babel/plugin-proposal-async-generator-functions@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" - integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - -"@babel/plugin-proposal-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" - integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-dynamic-import@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" - integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - -"@babel/plugin-proposal-export-namespace-from@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" - integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - -"@babel/plugin-proposal-json-strings@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" - integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.0" - -"@babel/plugin-proposal-logical-assignment-operators@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" - integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" - integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - -"@babel/plugin-proposal-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" - integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-proposal-object-rest-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" - integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.4" - -"@babel/plugin-proposal-optional-catch-binding@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" - integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - -"@babel/plugin-proposal-optional-chaining@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" - integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - -"@babel/plugin-proposal-private-methods@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" - integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" - integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-async-generators@^7.8.0": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" - integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-dynamic-import@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-json-strings@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-object-rest-spread@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" - integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-arrow-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" - integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-async-to-generator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" - integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - -"@babel/plugin-transform-block-scoped-functions@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" - integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-block-scoping@^7.10.4": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" - integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-classes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" - integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-define-map" "^7.10.4" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" - integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-destructuring@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" - integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" - integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-duplicate-keys@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" - integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-exponentiation-operator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-for-of@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" - integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" - integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" - integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-member-expression-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" - integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-modules-amd@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" - integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== - dependencies: - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-commonjs@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" - integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-systemjs@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" - integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== - dependencies: - "@babel/helper-hoist-variables" "^7.10.4" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helper-plugin-utils" "^7.10.4" - babel-plugin-dynamic-import-node "^2.3.3" - -"@babel/plugin-transform-modules-umd@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" - integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== - dependencies: - "@babel/helper-module-transforms" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" - integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - -"@babel/plugin-transform-new-target@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" - integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-object-super@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" - integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - -"@babel/plugin-transform-parameters@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" - integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-property-literals@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" - integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-regenerator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== - dependencies: - regenerator-transform "^0.14.2" - -"@babel/plugin-transform-reserved-words@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" - integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-shorthand-properties@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" - integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-spread@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" - integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" - -"@babel/plugin-transform-sticky-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" - integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - -"@babel/plugin-transform-template-literals@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" - integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-typeof-symbol@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" - integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-unicode-escapes@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" - integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-unicode-regex@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" - integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/preset-env@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" - integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== - dependencies: - "@babel/compat-data" "^7.11.0" - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-proposal-async-generator-functions" "^7.10.4" - "@babel/plugin-proposal-class-properties" "^7.10.4" - "@babel/plugin-proposal-dynamic-import" "^7.10.4" - "@babel/plugin-proposal-export-namespace-from" "^7.10.4" - "@babel/plugin-proposal-json-strings" "^7.10.4" - "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" - "@babel/plugin-proposal-numeric-separator" "^7.10.4" - "@babel/plugin-proposal-object-rest-spread" "^7.11.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" - "@babel/plugin-proposal-optional-chaining" "^7.11.0" - "@babel/plugin-proposal-private-methods" "^7.10.4" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.4" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.4" - "@babel/plugin-transform-arrow-functions" "^7.10.4" - "@babel/plugin-transform-async-to-generator" "^7.10.4" - "@babel/plugin-transform-block-scoped-functions" "^7.10.4" - "@babel/plugin-transform-block-scoping" "^7.10.4" - "@babel/plugin-transform-classes" "^7.10.4" - "@babel/plugin-transform-computed-properties" "^7.10.4" - "@babel/plugin-transform-destructuring" "^7.10.4" - "@babel/plugin-transform-dotall-regex" "^7.10.4" - "@babel/plugin-transform-duplicate-keys" "^7.10.4" - "@babel/plugin-transform-exponentiation-operator" "^7.10.4" - "@babel/plugin-transform-for-of" "^7.10.4" - "@babel/plugin-transform-function-name" "^7.10.4" - "@babel/plugin-transform-literals" "^7.10.4" - "@babel/plugin-transform-member-expression-literals" "^7.10.4" - "@babel/plugin-transform-modules-amd" "^7.10.4" - "@babel/plugin-transform-modules-commonjs" "^7.10.4" - "@babel/plugin-transform-modules-systemjs" "^7.10.4" - "@babel/plugin-transform-modules-umd" "^7.10.4" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" - "@babel/plugin-transform-new-target" "^7.10.4" - "@babel/plugin-transform-object-super" "^7.10.4" - "@babel/plugin-transform-parameters" "^7.10.4" - "@babel/plugin-transform-property-literals" "^7.10.4" - "@babel/plugin-transform-regenerator" "^7.10.4" - "@babel/plugin-transform-reserved-words" "^7.10.4" - "@babel/plugin-transform-shorthand-properties" "^7.10.4" - "@babel/plugin-transform-spread" "^7.11.0" - "@babel/plugin-transform-sticky-regex" "^7.10.4" - "@babel/plugin-transform-template-literals" "^7.10.4" - "@babel/plugin-transform-typeof-symbol" "^7.10.4" - "@babel/plugin-transform-unicode-escapes" "^7.10.4" - "@babel/plugin-transform-unicode-regex" "^7.10.4" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.5" - browserslist "^4.12.0" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" - -"@babel/preset-modules@^0.1.3": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/runtime@7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0.tgz#adeb78fedfc855aa05bc041640f3f6f98e85424c" - integrity sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA== - dependencies: - regenerator-runtime "^0.12.0" - -"@babel/runtime@^7.8.4": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b" - integrity sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.4.0" - "@babel/types" "^7.4.0" - -"@babel/template@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.3.tgz#1a01f078fc575d589ff30c0f71bf3c3d9ccbad84" - integrity sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.4.0" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/types" "^7.4.0" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.11" - -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.7.0": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0": - version "7.4.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.0.tgz#670724f77d24cce6cc7d8cf64599d511d164894c" - integrity sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA== - dependencies: - esutils "^2.0.2" - lodash "^4.17.11" - to-fast-properties "^2.0.0" - -"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@cnakazawa/watch@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef" - integrity sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@gulp-sourcemaps/identity-map@1.X": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz#1e6fe5d8027b1f285dc0d31762f566bccd73d5a9" - integrity sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ== - dependencies: - acorn "^5.0.3" - css "^2.2.1" - normalize-path "^2.1.1" - source-map "^0.6.0" - through2 "^2.0.3" - -"@gulp-sourcemaps/map-sources@1.X": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" - integrity sha1-iQrnxdjId/bThIYCFazp1+yUW9o= - dependencies: - normalize-path "^2.0.1" - through2 "^2.0.3" - -"@jest/console@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" - integrity sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg== - dependencies: - "@jest/source-map" "^24.3.0" - chalk "^2.0.1" - slash "^2.0.0" - -"@jest/core@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.7.1.tgz#6707f50db238d0c5988860680e2e414df0032024" - integrity sha512-ivlZ8HX/FOASfHcb5DJpSPFps8ydfUYzLZfgFFqjkLijYysnIEOieg72YRhO4ZUB32xu40hsSMmaw+IGYeKONA== - dependencies: - "@jest/console" "^24.7.1" - "@jest/reporters" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-changed-files "^24.7.0" - jest-config "^24.7.1" - jest-haste-map "^24.7.1" - jest-message-util "^24.7.1" - jest-regex-util "^24.3.0" - jest-resolve-dependencies "^24.7.1" - jest-runner "^24.7.1" - jest-runtime "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - jest-watcher "^24.7.1" - micromatch "^3.1.10" - p-each-series "^1.0.0" - pirates "^4.0.1" - realpath-native "^1.1.0" - rimraf "^2.5.4" - strip-ansi "^5.0.0" - -"@jest/environment@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.7.1.tgz#9b9196bc737561f67ac07817d4c5ece772e33135" - integrity sha512-wmcTTYc4/KqA+U5h1zQd5FXXynfa7VGP2NfF+c6QeGJ7c+2nStgh65RQWNX62SC716dTtqheTRrZl0j+54oGHw== - dependencies: - "@jest/fake-timers" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - -"@jest/fake-timers@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.7.1.tgz#56e5d09bdec09ee81050eaff2794b26c71d19db2" - integrity sha512-4vSQJDKfR2jScOe12L9282uiwuwQv9Lk7mgrCSZHA9evB9efB/qx8i0KJxsAKtp8fgJYBJdYY7ZU6u3F4/pyjA== - dependencies: - "@jest/types" "^24.7.0" - jest-message-util "^24.7.1" - jest-mock "^24.7.0" - -"@jest/reporters@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.7.1.tgz#38ac0b096cd691bbbe3051ddc25988d42e37773a" - integrity sha512-bO+WYNwHLNhrjB9EbPL4kX/mCCG4ZhhfWmO3m4FSpbgr7N83MFejayz30kKjgqr7smLyeaRFCBQMbXpUgnhAJw== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.2" - istanbul-api "^2.1.1" - istanbul-lib-coverage "^2.0.2" - istanbul-lib-instrument "^3.0.1" - istanbul-lib-source-maps "^3.0.1" - jest-haste-map "^24.7.1" - jest-resolve "^24.7.1" - jest-runtime "^24.7.1" - jest-util "^24.7.1" - jest-worker "^24.6.0" - node-notifier "^5.2.1" - slash "^2.0.0" - source-map "^0.6.0" - string-length "^2.0.0" - -"@jest/source-map@^24.3.0": - version "24.3.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.3.0.tgz#563be3aa4d224caf65ff77edc95cd1ca4da67f28" - integrity sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.1.15" - source-map "^0.6.0" - -"@jest/test-result@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.7.1.tgz#19eacdb29a114300aed24db651e5d975f08b6bbe" - integrity sha512-3U7wITxstdEc2HMfBX7Yx3JZgiNBubwDqQMh+BXmZXHa3G13YWF3p6cK+5g0hGkN3iufg/vGPl3hLxQXD74Npg== - dependencies: - "@jest/console" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/istanbul-lib-coverage" "^2.0.0" - -"@jest/test-sequencer@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.7.1.tgz#9c18e428e1ad945fa74f6233a9d35745ca0e63e0" - integrity sha512-84HQkCpVZI/G1zq53gHJvSmhUer4aMYp9tTaffW28Ih5OxfCg8hGr3nTSbL1OhVDRrFZwvF+/R9gY6JRkDUpUA== - dependencies: - "@jest/test-result" "^24.7.1" - jest-haste-map "^24.7.1" - jest-runner "^24.7.1" - jest-runtime "^24.7.1" - -"@jest/transform@^24.7.1": - version "24.7.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.7.1.tgz#872318f125bcfab2de11f53b465ab1aa780789c2" - integrity sha512-EsOUqP9ULuJ66IkZQhI5LufCHlTbi7hrcllRMUEV/tOgqBVQi93+9qEvkX0n8mYpVXQ8VjwmICeRgg58mrtIEw== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^24.7.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.7.1" - jest-regex-util "^24.3.0" - jest-util "^24.7.1" - micromatch "^3.1.10" - realpath-native "^1.1.0" - slash "^2.0.0" - source-map "^0.6.1" - write-file-atomic "2.4.1" - -"@jest/types@^24.7.0": - version "24.7.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.7.0.tgz#c4ec8d1828cdf23234d9b4ee31f5482a3f04f48b" - integrity sha512-ipJUa2rFWiKoBqMKP63Myb6h9+iT3FHRTF2M8OR6irxWzItisa8i4dcSg14IbvmXUnBlHBlUQPYUHWyX3UPpYA== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/yargs" "^12.0.9" - -"@logux/eslint-config@^28.1.0": - version "28.1.0" - resolved "https://registry.yarnpkg.com/@logux/eslint-config/-/eslint-config-28.1.0.tgz#11a502ada9c716548f3e0d7a83134df056c78c94" - integrity sha512-EnrjA+L6gWsWIfsPQZa4zuUqaxRdXCaNuk2vbREQLrPqq+UqW0WKBCbCDeuEFIlX/b8Khb1I2usOgeXC9ZrEjw== - dependencies: - globals "^11.11.0" - -"@samverschueren/stream-to-observable@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" - integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== - dependencies: - any-observable "^0.3.0" - -"@types/babel__core@^7.1.0": - version "7.1.1" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.1.tgz#ce9a9e5d92b7031421e1d0d74ae59f572ba48be6" - integrity sha512-+hjBtgcFPYyCTo0A15+nxrCVJL7aC6Acg87TXd5OW3QhHswdrOLoles+ldL2Uk8q++7yIfl4tURtztccdeeyOw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" - integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" - integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.6.tgz#328dd1a8fc4cfe3c8458be9477b219ea158fd7b2" - integrity sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw== - dependencies: - "@babel/types" "^7.3.0" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/istanbul-lib-coverage@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85" - integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== - -"@types/yargs@^12.0.2", "@types/yargs@^12.0.9": - version "12.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" - integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== - -abab@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" - integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-globals@^4.1.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.1.tgz#deb149c59276657ebd40ba2ba849ddd529763ccf" - integrity sha512-gJSiKY8dBIjV/0jagZIFBdVMtfQyA5QHCvAT48H2q8REQoW8Fs5AOjqBql1LgSXgrMWdevcE+8cdZ33NtVbIBA== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - -acorn-jsx@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" - integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== - -acorn-walk@^6.0.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" - integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== - -acorn@5.X, acorn@^5.0.3, acorn@^5.5.3: - version "5.7.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" - integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== - -acorn@^6.0.1, acorn@^6.0.7: - version "6.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" - integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== - -ajv@^6.5.5, ajv@^6.9.1: - version "6.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" - integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== - dependencies: - fast-deep-equal "^2.0.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-colors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" - integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== - dependencies: - ansi-wrap "^0.1.0" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" - -ansi-escapes@^3.0.0, ansi-escapes@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0, ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -any-observable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" - integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -append-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" - integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= - dependencies: - buffer-equal "^1.0.0" - -append-transform@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" - integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== - dependencies: - default-require-extensions "^2.0.0" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-filter@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" - integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4= - dependencies: - make-iterator "^1.0.0" - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-map@^2.0.0, arr-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" - integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ= - dependencies: - make-iterator "^1.0.0" - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-each@^1.0.0, array-each@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" - integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= - -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - -array-initial@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" - integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U= - dependencies: - array-slice "^1.0.0" - is-number "^4.0.0" - -array-last@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" - integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== - dependencies: - is-number "^4.0.0" - -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= - -array-slice@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" - integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== - -array-sort@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" - integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== - dependencies: - default-compare "^1.0.0" - get-value "^2.0.6" - kind-of "^5.0.2" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async-done@^1.2.0, async-done@^1.2.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.1.tgz#14b7b73667b864c8f02b5b253fc9c6eddb777f3e" - integrity sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.2" - process-nextick-args "^1.0.7" - stream-exhaust "^1.0.1" - -async-each@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.2.tgz#8b8a7ca2a658f927e9f307d6d1a42f4199f0f735" - integrity sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg== - -async-limiter@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" - integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== - -async-settle@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" - integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs= - dependencies: - async-done "^1.2.2" - -async@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" - integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== - dependencies: - lodash "^4.17.11" - -async@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" - integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== - -babel-eslint@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" - integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - -babel-jest@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.7.1.tgz#73902c9ff15a7dfbdc9994b0b17fcefd96042178" - integrity sha512-GPnLqfk8Mtt0i4OemjWkChi73A3ALs4w2/QbG64uAj8b5mmwzxc7jbJVRZt8NJkxi6FopVHog9S3xX6UJKb2qg== - dependencies: - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/babel__core" "^7.1.0" - babel-plugin-istanbul "^5.1.0" - babel-preset-jest "^24.6.0" - chalk "^2.4.2" - slash "^2.0.0" - -babel-plugin-add-module-exports@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz#6caa4ddbe1f578c6a5264d4d3e6c8a2720a7ca2b" - integrity sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg== - -babel-plugin-dynamic-import-node@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" - integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-istanbul@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893" - integrity sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ== - dependencies: - find-up "^3.0.0" - istanbul-lib-instrument "^3.0.0" - test-exclude "^5.0.0" - -babel-plugin-jest-hoist@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz#f7f7f7ad150ee96d7a5e8e2c5da8319579e78019" - integrity sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w== - dependencies: - "@types/babel__traverse" "^7.0.6" - -babel-preset-jest@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz#66f06136eefce87797539c0d63f1769cc3915984" - integrity sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw== - dependencies: - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - babel-plugin-jest-hoist "^24.6.0" - -bach@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" - integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= - dependencies: - arr-filter "^1.1.1" - arr-flatten "^1.0.1" - arr-map "^2.0.0" - array-each "^1.0.0" - array-initial "^1.0.0" - array-last "^1.1.1" - async-done "^1.2.2" - async-settle "^1.0.0" - now-and-later "^2.0.0" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -browser-process-hrtime@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" - integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== - -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - -browserslist@^4.12.0, browserslist@^4.8.5: - version "4.14.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" - integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== - dependencies: - caniuse-lite "^1.0.30001125" - electron-to-chromium "^1.3.564" - escalade "^3.0.2" - node-releases "^1.1.61" - -bser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" - integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= - dependencies: - node-int64 "^0.4.0" - -buffer-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" - integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= - -camelcase@^5.0.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-lite@^1.0.30001125: - version "1.0.30001131" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001131.tgz" - integrity sha512-4QYi6Mal4MMfQMSqGIRPGbKIbZygeN83QsWq1ixpUwvtfgAZot5BrCKzGygvZaV+CnELdTwD0S4cqUNozq7/Cw== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.0.0, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -chokidar@^2.0.0: - version "2.1.5" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" - integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chownr@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" - integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-job-number@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/ci-job-number/-/ci-job-number-0.3.0.tgz#34bdd114b0dece1960287bd40a57051041a2a800" - integrity sha1-NL3RFLDezhlgKHvUClcFEEGiqAA= - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-cursor@^2.0.0, cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-truncate@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" - integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= - dependencies: - slice-ansi "0.0.4" - string-width "^1.0.1" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= - -clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= - -clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= - -cloneable-readable@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" - integrity sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-map@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" - integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw= - dependencies: - arr-map "^2.0.2" - for-own "^1.0.0" - make-iterator "^1.0.0" - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" - integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== - dependencies: - delayed-stream "~1.0.0" - -commander@^2.14.1, commander@^2.19.0, commander@^2.9.0: - version "2.20.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" - integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== - -commander@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@~2.20.3: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -compare-versions@^3.2.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.4.0.tgz#e0747df5c9cb7f054d6d3dc3e1dbc444f9e92b26" - integrity sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg== - -component-emitter@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -concat-with-sourcemaps@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" - integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== - dependencies: - source-map "^0.6.1" - -config-chain@^1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" - integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - -convert-source-map@1.X, convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== - dependencies: - safe-buffer "~5.1.1" - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-props@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.4.tgz#93bb1cadfafd31da5bb8a9d4b41f471ec3a72dfe" - integrity sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A== - dependencies: - each-props "^1.3.0" - is-plain-object "^2.0.1" - -core-js-compat@^3.6.2: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== - dependencies: - browserslist "^4.8.5" - semver "7.0.0" - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.2, cosmiconfig@^5.0.7: - version "5.2.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.0.tgz#45038e4d28a7fe787203aede9c25bca4a08b12c8" - integrity sha512-nxt+Nfc3JAqf4WIWd0jXLjTJZmsPLrA9DDc4nRw2KFJQJK7DNooqSXrNI7tzLG50CF8axczly5UV929tBmh/7g== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.0" - parse-json "^4.0.0" - -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -css@2.X, css@^2.2.1: - version "2.2.4" - resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" - integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== - dependencies: - inherits "^2.0.3" - source-map "^0.6.1" - source-map-resolve "^0.5.2" - urix "^0.1.0" - -cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": - version "0.3.6" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" - integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== - -cssstyle@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077" - integrity sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow== - dependencies: - cssom "0.3.x" - -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= - dependencies: - es5-ext "^0.10.9" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - -date-fns@^1.27.2: - version "1.30.1" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" - integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== - -debug-fabulous@1.X: - version "1.1.0" - resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e" - integrity sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg== - dependencies: - debug "3.X" - memoizee "0.4.X" - object-assign "4.X" - -debug@3.X, debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deepmerge@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e" - integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow== - -default-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" - integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== - dependencies: - kind-of "^5.0.2" - -default-require-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" - integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= - dependencies: - strip-bom "^3.0.0" - -default-resolution@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" - integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -del@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" - integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= - dependencies: - globby "^6.1.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - p-map "^1.1.1" - pify "^3.0.0" - rimraf "^2.2.8" - -del@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.0.tgz#049543b8290e1a9293e2bd150ab3a06f637322b8" - integrity sha512-C4kvKNlYrwXhKxz97BuohF8YoGgQ23Xm9lvoHmgT7JaPGprSEjk3+XFled74Yt/x0ZABUHg2D67covzAPUKx5Q== - dependencies: - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-file@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" - integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= - -detect-libc@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= - -detect-newline@2.X, detect-newline@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= - -diff-sequences@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975" - integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw== - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - -duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -each-props@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" - integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== - dependencies: - is-plain-object "^2.0.1" - object.defaults "^1.1.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -editorconfig@^0.15.2: - version "0.15.3" - resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.3.tgz#bef84c4e75fb8dcb0ce5cee8efd51c15999befc5" - integrity sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g== - dependencies: - commander "^2.19.0" - lru-cache "^4.1.5" - semver "^5.6.0" - sigmund "^1.0.1" - -electron-to-chromium@^1.3.564: - version "1.3.570" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f" - integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg== - -elegant-spinner@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" - integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" - integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== - dependencies: - once "^1.4.0" - -entities@^2.0.0, entities@~2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" - integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.0: - version "1.18.0-next.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc" - integrity sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.5.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.49" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.49.tgz#059a239de862c94494fec28f8150c977028c6c5e" - integrity sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.1" - next-tick "^1.0.0" - -es6-iterator@^2.0.1, es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - -escalade@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" - integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== - -escape-html@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escodegen@^1.9.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" - integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== - dependencies: - esprima "^3.1.3" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-ci@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-ci/-/eslint-ci-1.0.0.tgz#6bcb238c45d2bf522fad50ad190bc00a206fe2df" - integrity sha512-8Itb/739gpX11nqvWg6kkpge7NwS1o+SkhfFAItfvH9/i5IoY6NLKKKzIagHakT2WmMdnq4HfcymYh/0NGvAVA== - dependencies: - ci-job-number "^0.3.0" - -eslint-config-postcss@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/eslint-config-postcss/-/eslint-config-postcss-3.0.7.tgz#390d97d5ac08db9dc57630153cc0c1821559659b" - integrity sha512-5SCkmybZjQhOiFX8FNuqBo9SvCWH6inGXLHQ+BigXUiOGDhBNJuHp6JaF2qKMv+ti6kdk3J1ZFM3NurLww7Nxw== - -eslint-config-standard@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" - integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== - -eslint-import-resolver-node@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== - dependencies: - debug "^2.6.9" - resolve "^1.5.0" - -eslint-module-utils@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" - integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w== - dependencies: - debug "^2.6.8" - pkg-dir "^2.0.0" - -eslint-plugin-es@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" - integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== - dependencies: - eslint-utils "^1.3.0" - regexpp "^2.0.1" - -eslint-plugin-import-helpers@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-import-helpers/-/eslint-plugin-import-helpers-0.1.4.tgz#91b61713c382ec4b1ca6ca2e71e7a8024f6b963b" - integrity sha512-nJRmndV2GENl+PheYwReeau1qfq+RtsjxhopU4pmoEsBr1I8/DQZNkEUdKEFhQRfxTec9R/85Qmn3UMFzByjBg== - dependencies: - builtin-modules "^1.1.1" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.3.0" - lodash.cond "^4.5.2" - -eslint-plugin-import@^2.16.0: - version "2.16.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f" - integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A== - dependencies: - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.3.0" - has "^1.0.3" - lodash "^4.17.11" - minimatch "^3.0.4" - read-pkg-up "^2.0.0" - resolve "^1.9.0" - -eslint-plugin-jest@^22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.4.1.tgz#a5fd6f7a2a41388d16f527073b778013c5189a9c" - integrity sha512-gcLfn6P2PrFAVx3AobaOzlIEevpAEf9chTpFZz7bYfc7pz8XRv7vuKTIE4hxPKZSha6XWKKplDQ0x9Pq8xX2mg== - -eslint-plugin-node@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" - integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== - dependencies: - eslint-plugin-es "^1.3.1" - eslint-utils "^1.3.1" - ignore "^5.0.2" - minimatch "^3.0.4" - resolve "^1.8.1" - semver "^5.5.0" - -eslint-plugin-prefer-let@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prefer-let/-/eslint-plugin-prefer-let-1.0.1.tgz#ef7216bcabf6d4cb0a7b7b5ecf55e85e9ee58067" - integrity sha1-73IWvKv21MsKe3tez1XoXp7lgGc= - dependencies: - requireindex "~1.1.0" - -eslint-plugin-promise@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.1.1.tgz#1e08cb68b5b2cd8839f8d5864c796f56d82746db" - integrity sha512-faAHw7uzlNPy7b45J1guyjazw28M+7gJokKUjC5JSFoYfUEyy6Gw/i7YQvmv2Yk00sUjWcmzXQLpU1Ki/C2IZQ== - -eslint-plugin-security@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-security/-/eslint-plugin-security-1.4.0.tgz#d4f314484a80b1b613b8c8886e84f52efe1526c2" - integrity sha512-xlS7P2PLMXeqfhyf3NpqbvbnW04kN8M9NtmhpR3XGyOvt/vNKS7XPXT5EDbwKW9vCjWH4PpfQvgD/+JgN0VJKA== - dependencies: - safe-regex "^1.1.0" - -eslint-plugin-standard@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c" - integrity sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA== - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.0, eslint-utils@^1.3.1: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - -eslint@^5.16.0: - version "5.16.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" - integrity sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.9.1" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^4.0.3" - eslint-utils "^1.3.1" - eslint-visitor-keys "^1.0.0" - espree "^5.0.1" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.7.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^6.2.2" - js-yaml "^3.13.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.11" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^5.5.1" - strip-ansi "^4.0.0" - strip-json-comments "^2.0.1" - table "^5.2.3" - text-table "^0.2.0" - -espree@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" - integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== - dependencies: - acorn "^6.0.7" - acorn-jsx "^5.0.0" - eslint-visitor-keys "^1.0.0" - -esprima@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= - -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= - dependencies: - d "1" - es5-ext "~0.10.14" - -exec-sh@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.2.tgz#6738de2eb7c8e671d0366aea0b0db8c6f7d7391b" - integrity sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg== - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-tilde@^2.0.0, expand-tilde@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" - integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= - dependencies: - homedir-polyfill "^1.0.1" - -expect@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-24.7.1.tgz#d91defbab4e627470a152feaf35b3c31aa1c7c14" - integrity sha512-mGfvMTPduksV3xoI0xur56pQsg2vJjNf5+a+bXOjqCkiCBbmCayrBbHS/75y9K430cfqyocPr2ZjiNiRx4SRKw== - dependencies: - "@jest/types" "^24.7.0" - ansi-styles "^3.2.0" - jest-get-type "^24.3.0" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-regex-util "^24.3.0" - -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= - dependencies: - kind-of "^1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" - integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -eyo-kernel@^2.5.6: - version "2.5.6" - resolved "https://registry.yarnpkg.com/eyo-kernel/-/eyo-kernel-2.5.6.tgz#aedd0e971943db3f5f282b4081f75b2983e7b606" - integrity sha512-lAcX7HdPLlNB8Ia6Uvq2hFMx9S5VQSfAXkjBZJi9OXzFC1exDvX9lzk2YeQVB9EKufhlHlgeiD26mzg5q42Rgg== - -fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fb-watchman@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" - integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= - dependencies: - bser "^2.0.0" - -figures@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -fileset@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" - integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= - dependencies: - glob "^7.0.3" - minimatch "^3.0.3" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -find-parent-dir@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" - integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -findup-sync@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" - integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= - dependencies: - detect-file "^1.0.0" - is-glob "^3.1.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -findup-sync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - -fined@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.1.tgz#95d88ff329123dd1a6950fdfcd321f746271e01f" - integrity sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g== - dependencies: - expand-tilde "^2.0.2" - is-plain-object "^2.0.3" - object.defaults "^1.1.0" - object.pick "^1.2.0" - parse-filepath "^1.0.1" - -flagged-respawn@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" - integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" - integrity sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg== - -flush-write-stream@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -fn-name@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" - integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= - -for-in@^1.0.1, for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -for-own@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" - integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= - dependencies: - for-in "^1.0.1" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-minipass@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" - integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== - dependencies: - minipass "^2.2.1" - -fs-mkdirp-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" - integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= - dependencies: - graceful-fs "^4.1.11" - through2 "^2.0.3" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" - integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== - dependencies: - nan "^2.9.2" - node-pre-gyp "^0.10.0" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -g-status@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" - integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== - dependencies: - arrify "^1.0.1" - matcher "^1.0.0" - simple-git "^1.85.0" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" - integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== - -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-stream@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" - integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= - dependencies: - extend "^3.0.0" - glob "^7.1.1" - glob-parent "^3.1.0" - is-negated-glob "^1.0.0" - ordered-read-streams "^1.0.0" - pumpify "^1.3.5" - readable-stream "^2.1.5" - remove-trailing-separator "^1.0.1" - to-absolute-glob "^2.0.0" - unique-stream "^2.0.2" - -glob-watcher@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.3.tgz#88a8abf1c4d131eb93928994bc4a593c2e5dd626" - integrity sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg== - dependencies: - anymatch "^2.0.0" - async-done "^1.2.0" - chokidar "^2.0.0" - is-negated-glob "^1.0.0" - just-debounce "^1.0.0" - object.defaults "^1.1.0" - -glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-modules@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" - integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== - dependencies: - global-prefix "^1.0.1" - is-windows "^1.0.1" - resolve-dir "^1.0.0" - -global-prefix@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" - integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= - dependencies: - expand-tilde "^2.0.2" - homedir-polyfill "^1.0.1" - ini "^1.3.4" - is-windows "^1.0.1" - which "^1.2.14" - -globals@^11.1.0, globals@^11.11.0, globals@^11.7.0: - version "11.11.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.11.0.tgz#dcf93757fa2de5486fbeed7118538adf789e9c2e" - integrity sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw== - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -glogg@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" - integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== - dependencies: - sparkles "^1.0.0" - -graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -gulp-babel@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-8.0.0.tgz#e0da96f4f2ec4a88dd3a3030f476e38ab2126d87" - integrity sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ== - dependencies: - plugin-error "^1.0.1" - replace-ext "^1.0.0" - through2 "^2.0.0" - vinyl-sourcemaps-apply "^0.2.0" - -gulp-changed@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/gulp-changed/-/gulp-changed-3.2.0.tgz#cee9866d949e09187522523d6c65565f6e32bd7c" - integrity sha1-zumGbZSeCRh1IlI9bGVWX24yvXw= - dependencies: - make-dir "^1.1.0" - pify "^3.0.0" - plugin-error "^0.1.2" - replace-ext "^1.0.0" - through2 "^2.0.0" - touch "^3.1.0" - -gulp-cli@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.1.0.tgz#2705143ae744c9e10d894ca621ce0a3933aa2e89" - integrity sha512-txzgdFVlEPShBZus6JJyGyKJoBVDq6Do0ZQgIgx5RAsmhNVTDjymmOxpQvo3c20m66FldilS68ZXj2Q9w5dKbA== - dependencies: - ansi-colors "^1.0.1" - archy "^1.0.0" - array-sort "^1.0.0" - color-support "^1.1.3" - concat-stream "^1.6.0" - copy-props "^2.0.1" - fancy-log "^1.3.2" - gulplog "^1.0.0" - interpret "^1.1.0" - isobject "^3.0.1" - liftoff "^3.1.0" - matchdep "^2.0.0" - mute-stdout "^1.0.0" - pretty-hrtime "^1.0.0" - replace-homedir "^1.0.0" - semver-greatest-satisfied-range "^1.1.0" - v8flags "^3.0.1" - yargs "^7.1.0" - -gulp-json-editor@^2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/gulp-json-editor/-/gulp-json-editor-2.5.1.tgz#96a3051bfeecdf7f58b240bbdc10ec19b3eed28d" - integrity sha512-YxioAmHLQlbw2tYAtJ8TKc1ljgcBwdC16h+ImHKFgbWHFMG0LhMfHWgtliRPGnSMleSQfDLoolWsVha254HdVw== - dependencies: - deepmerge "^3.2.0" - detect-indent "^5.0.0" - js-beautify "^1.9.0" - plugin-error "^1.0.1" - through2 "^3.0.1" - -gulp-sourcemaps@^2.6.5: - version "2.6.5" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz#a3f002d87346d2c0f3aec36af7eb873f23de8ae6" - integrity sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg== - dependencies: - "@gulp-sourcemaps/identity-map" "1.X" - "@gulp-sourcemaps/map-sources" "1.X" - acorn "5.X" - convert-source-map "1.X" - css "2.X" - debug-fabulous "1.X" - detect-newline "2.X" - graceful-fs "4.X" - source-map "~0.6.0" - strip-bom-string "1.X" - through2 "2.X" - -gulp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.0.tgz#95766c601dade4a77ed3e7b2b6dc03881b596366" - integrity sha1-lXZsYB2t5Kd+0+eyttwDiBtZY2Y= - dependencies: - glob-watcher "^5.0.0" - gulp-cli "^2.0.0" - undertaker "^1.0.0" - vinyl-fs "^3.0.0" - -gulplog@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" - integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= - dependencies: - glogg "^1.0.0" - -handlebars@^4.1.0: - version "4.4.5" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.5.tgz#1b1f94f9bfe7379adda86a8b73fb570265a0dddd" - integrity sha512-0Ce31oWVB7YidkaTq33ZxEbN+UDxMMgThvCe8ptgQViymL5DPis9uLdTA13MiRPhgvqyxIegugrP97iK3JeBHg== - dependencies: - neo-async "^2.6.0" - optimist "^0.6.1" - source-map "^0.6.1" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" - integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= - -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.1, has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -homedir-polyfill@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" - integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== - dependencies: - parse-passwd "^1.0.0" - -hosted-git-info@^2.1.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" - integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== - -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -husky@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/husky/-/husky-1.3.1.tgz#26823e399300388ca2afff11cfa8a86b0033fae0" - integrity sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg== - dependencies: - cosmiconfig "^5.0.7" - execa "^1.0.0" - find-up "^3.0.0" - get-stdin "^6.0.0" - is-ci "^2.0.0" - pkg-dir "^3.0.0" - please-upgrade-node "^3.1.1" - read-pkg "^4.0.1" - run-node "^1.0.0" - slash "^2.0.0" - -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore-walk@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" - integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== - dependencies: - minimatch "^3.0.4" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.6.tgz#562dacc7ec27d672dde433aa683c543b24c17694" - integrity sha512-/+hp3kUf/Csa32ktIaj0OlRqQxrgs30n62M90UBpNd9k+ENEch5S+hmbW3DtcJGz3sYFTh4F3A6fQ0q7KWsp4w== - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" - integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-fresh@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" - integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== - dependencies: - ansi-escapes "^3.2.0" - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^2.0.0" - lodash "^4.17.11" - mute-stream "0.0.7" - run-async "^2.2.0" - rxjs "^6.4.0" - string-width "^2.1.0" - strip-ansi "^5.0.0" - through "^2.3.6" - -interpret@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== - -invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -is-absolute@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" - integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== - dependencies: - is-relative "^1.0.0" - is-windows "^1.0.1" - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== - -is-callable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" - integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-negated-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" - integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= - -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-number@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" - integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== - -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-observable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" - integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== - dependencies: - symbol-observable "^1.1.0" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= - -is-path-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.0.0.tgz#d4777a8e227a00096a31f030db3770f84b116c02" - integrity sha512-m5dHHzpOXEiv18JEORttBO64UgTEypx99vCxQLjbBvGhOJxnTNglYoFXxwo6AbsQb79sqqycQEHv2hWkHZAijA== - -is-path-in-cwd@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" - integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== - dependencies: - is-path-inside "^1.0.0" - -is-path-in-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.0.0.tgz#68e452a6eec260500cec21e029c0a44cc0dcd2ea" - integrity sha512-6Vz5Gc9s/sDA3JBVu0FzWufm8xaBsqy1zn8Q6gmvGP6nSDMw78aS4poBNeatWjaRpTpxxLn1WOndAiOlk+qY8A== - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= - dependencies: - path-is-inside "^1.0.1" - -is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-promise@^2.1, is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= - dependencies: - has "^1.0.1" - -is-regex@^1.1.0, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - -is-relative@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" - integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== - dependencies: - is-unc-path "^1.0.0" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-symbol@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" - integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== - dependencies: - has-symbols "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-unc-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" - integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== - dependencies: - unc-path-regex "^0.1.2" - -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-valid-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" - integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= - -is-windows@^1.0.1, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-api@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.1.1.tgz#194b773f6d9cbc99a9258446848b0f988951c4d0" - integrity sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw== - dependencies: - async "^2.6.1" - compare-versions "^3.2.1" - fileset "^2.0.3" - istanbul-lib-coverage "^2.0.3" - istanbul-lib-hook "^2.0.3" - istanbul-lib-instrument "^3.1.0" - istanbul-lib-report "^2.0.4" - istanbul-lib-source-maps "^3.0.2" - istanbul-reports "^2.1.1" - js-yaml "^3.12.0" - make-dir "^1.3.0" - minimatch "^3.0.4" - once "^1.4.0" - -istanbul-lib-coverage@^2.0.2, istanbul-lib-coverage@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#0b891e5ad42312c2b9488554f603795f9a2211ba" - integrity sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw== - -istanbul-lib-hook@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz#e0e581e461c611be5d0e5ef31c5f0109759916fb" - integrity sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA== - dependencies: - append-transform "^1.0.0" - -istanbul-lib-instrument@^3.0.0, istanbul-lib-instrument@^3.0.1, istanbul-lib-instrument@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz#a2b5484a7d445f1f311e93190813fa56dfb62971" - integrity sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA== - dependencies: - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - istanbul-lib-coverage "^2.0.3" - semver "^5.5.0" - -istanbul-lib-report@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz#bfd324ee0c04f59119cb4f07dab157d09f24d7e4" - integrity sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA== - dependencies: - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" - supports-color "^6.0.0" - -istanbul-lib-source-maps@^3.0.1, istanbul-lib-source-maps@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz#f1e817229a9146e8424a28e5d69ba220fda34156" - integrity sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^2.0.3" - make-dir "^1.3.0" - rimraf "^2.6.2" - source-map "^0.6.1" - -istanbul-reports@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.1.1.tgz#72ef16b4ecb9a4a7bd0e2001e00f95d1eec8afa9" - integrity sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw== - dependencies: - handlebars "^4.1.0" - -isutf8@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isutf8/-/isutf8-2.1.0.tgz#b6d08a02d4ce43bf3b4be39b9b60231b88dfeb2b" - integrity sha512-rEMU6f82evtJNtYMrtVODUbf+C654mos4l+9noOueesUMipSWK6x3tpt8DiXhcZh/ZOBWYzJ9h9cNAlcQQnMiQ== - -jest-changed-files@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.7.0.tgz#39d723a11b16ed7b373ac83adc76a69464b0c4fa" - integrity sha512-33BgewurnwSfJrW7T5/ZAXGE44o7swLslwh8aUckzq2e17/2Os1V0QU506ZNik3hjs8MgnEMKNkcud442NCDTw== - dependencies: - "@jest/types" "^24.7.0" - execa "^1.0.0" - throat "^4.0.0" - -jest-cli@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.7.1.tgz#6093a539073b6f4953145abeeb9709cd621044f1" - integrity sha512-32OBoSCVPzcTslGFl6yVCMzB2SqX3IrWwZCY5mZYkb0D2WsogmU3eV2o8z7+gRQa4o4sZPX/k7GU+II7CxM6WQ== - dependencies: - "@jest/core" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" - exit "^0.1.2" - import-local "^2.0.0" - is-ci "^2.0.0" - jest-config "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - prompts "^2.0.1" - realpath-native "^1.1.0" - yargs "^12.0.2" - -jest-config@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.7.1.tgz#6c1dd4db82a89710a3cf66bdba97827c9a1cf052" - integrity sha512-8FlJNLI+X+MU37j7j8RE4DnJkvAghXmBWdArVzypW6WxfGuxiL/CCkzBg0gHtXhD2rxla3IMOSUAHylSKYJ83g== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^24.7.1" - "@jest/types" "^24.7.0" - babel-jest "^24.7.1" - chalk "^2.0.1" - glob "^7.1.1" - jest-environment-jsdom "^24.7.1" - jest-environment-node "^24.7.1" - jest-get-type "^24.3.0" - jest-jasmine2 "^24.7.1" - jest-regex-util "^24.3.0" - jest-resolve "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - micromatch "^3.1.10" - pretty-format "^24.7.0" - realpath-native "^1.1.0" - -jest-diff@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.7.0.tgz#5d862899be46249754806f66e5729c07fcb3580f" - integrity sha512-ULQZ5B1lWpH70O4xsANC4tf4Ko6RrpwhE3PtG6ERjMg1TiYTC2Wp4IntJVGro6a8HG9luYHhhmF4grF0Pltckg== - dependencies: - chalk "^2.0.1" - diff-sequences "^24.3.0" - jest-get-type "^24.3.0" - pretty-format "^24.7.0" - -jest-docblock@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.3.0.tgz#b9c32dac70f72e4464520d2ba4aec02ab14db5dd" - integrity sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg== - dependencies: - detect-newline "^2.1.0" - -jest-each@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.7.1.tgz#fcc7dda4147c28430ad9fb6dc7211cd17ab54e74" - integrity sha512-4fsS8fEfLa3lfnI1Jw6NxjhyRTgfpuOVTeUZZFyVYqeTa4hPhr2YkToUhouuLTrL2eMGOfpbdMyRx0GQ/VooKA== - dependencies: - "@jest/types" "^24.7.0" - chalk "^2.0.1" - jest-get-type "^24.3.0" - jest-util "^24.7.1" - pretty-format "^24.7.0" - -jest-environment-jsdom@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-24.7.1.tgz#a40e004b4458ebeb8a98082df135fd501b9fbbd6" - integrity sha512-Gnhb+RqE2JuQGb3kJsLF8vfqjt3PHKSstq4Xc8ic+ax7QKo4Z0RWGucU3YV+DwKR3T9SYc+3YCUQEJs8r7+Jxg== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - jest-util "^24.7.1" - jsdom "^11.5.1" - -jest-environment-node@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.7.1.tgz#fa2c047a31522a48038d26ee4f7c8fd9c1ecfe12" - integrity sha512-GJJQt1p9/C6aj6yNZMvovZuxTUd+BEJprETdvTKSb4kHcw4mFj8777USQV0FJoJ4V3djpOwA5eWyPwfq//PFBA== - dependencies: - "@jest/environment" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/types" "^24.7.0" - jest-mock "^24.7.0" - jest-util "^24.7.1" - -jest-get-type@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.3.0.tgz#582cfd1a4f91b5cdad1d43d2932f816d543c65da" - integrity sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow== - -jest-haste-map@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.7.1.tgz#772e215cd84080d4bbcb759cfb668ad649a21471" - integrity sha512-g0tWkzjpHD2qa03mTKhlydbmmYiA2KdcJe762SbfFo/7NIMgBWAA0XqQlApPwkWOF7Cxoi/gUqL0i6DIoLpMBw== - dependencies: - "@jest/types" "^24.7.0" - anymatch "^2.0.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.4.0" - jest-util "^24.7.1" - jest-worker "^24.6.0" - micromatch "^3.1.10" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^1.2.7" - -jest-jasmine2@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.7.1.tgz#01398686dabe46553716303993f3be62e5d9d818" - integrity sha512-Y/9AOJDV1XS44wNwCaThq4Pw3gBPiOv/s6NcbOAkVRRUEPu+36L2xoPsqQXsDrxoBerqeyslpn2TpCI8Zr6J2w== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.0.1" - co "^4.6.0" - expect "^24.7.1" - is-generator-fn "^2.0.0" - jest-each "^24.7.1" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-runtime "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - pretty-format "^24.7.0" - throat "^4.0.0" - -jest-leak-detector@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.7.0.tgz#323ff93ed69be12e898f5b040952f08a94288ff9" - integrity sha512-zV0qHKZGXtmPVVzT99CVEcHE9XDf+8LwiE0Ob7jjezERiGVljmqKFWpV2IkG+rkFIEUHFEkMiICu7wnoPM/RoQ== - dependencies: - pretty-format "^24.7.0" - -jest-matcher-utils@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.7.0.tgz#bbee1ff37bc8b2e4afcaabc91617c1526af4bcd4" - integrity sha512-158ieSgk3LNXeUhbVJYRXyTPSCqNgVXOp/GT7O94mYd3pk/8+odKTyR1JLtNOQSPzNi8NFYVONtvSWA/e1RDXg== - dependencies: - chalk "^2.0.1" - jest-diff "^24.7.0" - jest-get-type "^24.3.0" - pretty-format "^24.7.0" - -jest-message-util@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.7.1.tgz#f1dc3a6c195647096a99d0f1dadbc447ae547018" - integrity sha512-dk0gqVtyqezCHbcbk60CdIf+8UHgD+lmRHifeH3JRcnAqh4nEyPytSc9/L1+cQyxC+ceaeP696N4ATe7L+omcg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - -jest-mock@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.7.0.tgz#e49ce7262c12d7f5897b0d8af77f6db8e538023b" - integrity sha512-6taW4B4WUcEiT2V9BbOmwyGuwuAFT2G8yghF7nyNW1/2gq5+6aTqSPcS9lS6ArvEkX55vbPAS/Jarx5LSm4Fng== - dependencies: - "@jest/types" "^24.7.0" - -jest-pnp-resolver@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" - integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== - -jest-regex-util@^24.3.0: - version "24.3.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.3.0.tgz#d5a65f60be1ae3e310d5214a0307581995227b36" - integrity sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg== - -jest-resolve-dependencies@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.7.1.tgz#cf93bbef26999488a96a2b2012f9fe7375aa378f" - integrity sha512-2Eyh5LJB2liNzfk4eo7bD1ZyBbqEJIyyrFtZG555cSWW9xVHxII2NuOkSl1yUYTAYCAmM2f2aIT5A7HzNmubyg== - dependencies: - "@jest/types" "^24.7.0" - jest-regex-util "^24.3.0" - jest-snapshot "^24.7.1" - -jest-resolve@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.7.1.tgz#e4150198299298380a75a9fd55043fa3b9b17fde" - integrity sha512-Bgrc+/UUZpGJ4323sQyj85hV9d+ANyPNu6XfRDUcyFNX1QrZpSoM0kE4Mb2vZMAYTJZsBFzYe8X1UaOkOELSbw== - dependencies: - "@jest/types" "^24.7.0" - browser-resolve "^1.11.3" - chalk "^2.0.1" - jest-pnp-resolver "^1.2.1" - realpath-native "^1.1.0" - -jest-runner@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.7.1.tgz#41c8a02a06aa23ea82d8bffd69d7fa98d32f85bf" - integrity sha512-aNFc9liWU/xt+G9pobdKZ4qTeG/wnJrJna3VqunziDNsWT3EBpmxXZRBMKCsNMyfy+A/XHiV+tsMLufdsNdgCw== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.7.1" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - chalk "^2.4.2" - exit "^0.1.2" - graceful-fs "^4.1.15" - jest-config "^24.7.1" - jest-docblock "^24.3.0" - jest-haste-map "^24.7.1" - jest-jasmine2 "^24.7.1" - jest-leak-detector "^24.7.0" - jest-message-util "^24.7.1" - jest-resolve "^24.7.1" - jest-runtime "^24.7.1" - jest-util "^24.7.1" - jest-worker "^24.6.0" - source-map-support "^0.5.6" - throat "^4.0.0" - -jest-runtime@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.7.1.tgz#2ffd70b22dd03a5988c0ab9465c85cdf5d25c597" - integrity sha512-0VAbyBy7tll3R+82IPJpf6QZkokzXPIS71aDeqh+WzPRXRCNz6StQ45otFariPdJ4FmXpDiArdhZrzNAC3sj6A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/environment" "^24.7.1" - "@jest/source-map" "^24.3.0" - "@jest/transform" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/yargs" "^12.0.2" - chalk "^2.0.1" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.1.15" - jest-config "^24.7.1" - jest-haste-map "^24.7.1" - jest-message-util "^24.7.1" - jest-mock "^24.7.0" - jest-regex-util "^24.3.0" - jest-resolve "^24.7.1" - jest-snapshot "^24.7.1" - jest-util "^24.7.1" - jest-validate "^24.7.0" - realpath-native "^1.1.0" - slash "^2.0.0" - strip-bom "^3.0.0" - yargs "^12.0.2" - -jest-serializer@^24.4.0: - version "24.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" - integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== - -jest-snapshot@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.7.1.tgz#bd5a35f74aedff070975e9e9c90024f082099568" - integrity sha512-8Xk5O4p+JsZZn4RCNUS3pxA+ORKpEKepE+a5ejIKrId9CwrVN0NY+vkqEkXqlstA5NMBkNahXkR/4qEBy0t5yA== - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^24.7.0" - chalk "^2.0.1" - expect "^24.7.1" - jest-diff "^24.7.0" - jest-matcher-utils "^24.7.0" - jest-message-util "^24.7.1" - jest-resolve "^24.7.1" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - pretty-format "^24.7.0" - semver "^5.5.0" - -jest-util@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.7.1.tgz#b4043df57b32a23be27c75a2763d8faf242038ff" - integrity sha512-/KilOue2n2rZ5AnEBYoxOXkeTu6vi7cjgQ8MXEkih0oeAXT6JkS3fr7/j8+engCjciOU1Nq5loMSKe0A1oeX0A== - dependencies: - "@jest/console" "^24.7.1" - "@jest/fake-timers" "^24.7.1" - "@jest/source-map" "^24.3.0" - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - -jest-validate@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.7.0.tgz#70007076f338528ee1b1c8a8258b1b0bb982508d" - integrity sha512-cgai/gts9B2chz1rqVdmLhzYxQbgQurh1PEQSvSgPZ8KGa1AqXsqC45W5wKEwzxKrWqypuQrQxnF4+G9VejJJA== - dependencies: - "@jest/types" "^24.7.0" - camelcase "^5.0.0" - chalk "^2.0.1" - jest-get-type "^24.3.0" - leven "^2.1.0" - pretty-format "^24.7.0" - -jest-watcher@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-24.7.1.tgz#e161363d7f3f4e1ef3d389b7b3a0aad247b673f5" - integrity sha512-Wd6TepHLRHVKLNPacEsBwlp9raeBIO+01xrN24Dek4ggTS8HHnOzYSFnvp+6MtkkJ3KfMzy220KTi95e2rRkrw== - dependencies: - "@jest/test-result" "^24.7.1" - "@jest/types" "^24.7.0" - "@types/yargs" "^12.0.9" - ansi-escapes "^3.0.0" - chalk "^2.0.1" - jest-util "^24.7.1" - string-length "^2.0.0" - -jest-worker@^24.6.0: - version "24.6.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" - integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== - dependencies: - merge-stream "^1.0.1" - supports-color "^6.1.0" - -jest@^24.7.1: - version "24.7.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-24.7.1.tgz#0d94331cf510c75893ee32f87d7321d5bf8f2501" - integrity sha512-AbvRar5r++izmqo5gdbAjTeA6uNRGoNRuj5vHB0OnDXo2DXWZJVuaObiGgtlvhKb+cWy2oYbQSfxv7Q7GjnAtA== - dependencies: - import-local "^2.0.0" - jest-cli "^24.7.1" - -js-beautify@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.9.1.tgz#6f9ef915f5d8d92b9f907606fce63795884c8040" - integrity sha512-oxxvVZdOdUfzk8IOLBF2XUZvl2GoBEfA+b0of4u2EBY/46NlXasi8JdFvazA5lCrf9/lQhTjyVy2QCUW7iq0MQ== - dependencies: - config-chain "^1.1.12" - editorconfig "^0.15.2" - glob "^7.1.3" - mkdirp "~0.5.0" - nopt "~4.0.1" - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.12.0, js-yaml@^3.13.0: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdom@^11.5.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" - integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== - dependencies: - abab "^2.0.0" - acorn "^5.5.3" - acorn-globals "^4.1.0" - array-equal "^1.0.0" - cssom ">= 0.3.2 < 0.4.0" - cssstyle "^1.0.0" - data-urls "^1.0.0" - domexception "^1.0.1" - escodegen "^1.9.1" - html-encoding-sniffer "^1.0.2" - left-pad "^1.3.0" - nwsapi "^2.0.7" - parse5 "4.0.0" - pn "^1.1.0" - request "^2.87.0" - request-promise-native "^1.0.5" - sax "^1.2.4" - symbol-tree "^3.2.2" - tough-cookie "^2.3.4" - w3c-hr-time "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.3" - whatwg-mimetype "^2.1.0" - whatwg-url "^6.4.1" - ws "^5.2.0" - xml-name-validator "^3.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -just-debounce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.0.0.tgz#87fccfaeffc0b68cd19d55f6722943f929ea35ea" - integrity sha1-h/zPrv/AtozRnVX2cilD+SnqNeo= - -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0, kind-of@^5.0.2: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== - -kleur@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -last-run@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" - integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls= - dependencies: - default-resolution "^2.0.0" - es6-weak-map "^2.0.1" - -lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -lead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" - integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= - dependencies: - flush-write-stream "^1.0.2" - -left-pad@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" - integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== - -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== - dependencies: - leven "^3.1.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -liftoff@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" - integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== - dependencies: - extend "^3.0.0" - findup-sync "^3.0.0" - fined "^1.0.1" - flagged-respawn "^1.0.0" - is-plain-object "^2.0.4" - object.map "^1.0.0" - rechoir "^0.6.2" - resolve "^1.1.7" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -linkify-it@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" - integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== - dependencies: - uc.micro "^1.0.1" - -lint-staged@^8.1.5: - version "8.1.5" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.5.tgz#372476fe1a58b8834eb562ed4c99126bd60bdd79" - integrity sha512-e5ZavfnSLcBJE1BTzRTqw6ly8OkqVyO3GL2M6teSmTBYQ/2BuueD5GIt2RPsP31u/vjKdexUyDCxSyK75q4BDA== - dependencies: - chalk "^2.3.1" - commander "^2.14.1" - cosmiconfig "^5.0.2" - debug "^3.1.0" - dedent "^0.7.0" - del "^3.0.0" - execa "^1.0.0" - find-parent-dir "^0.3.0" - g-status "^2.0.2" - is-glob "^4.0.0" - is-windows "^1.0.2" - listr "^0.14.2" - listr-update-renderer "^0.5.0" - lodash "^4.17.11" - log-symbols "^2.2.0" - micromatch "^3.1.8" - npm-which "^3.0.1" - p-map "^1.1.1" - path-is-inside "^1.0.2" - pify "^3.0.0" - please-upgrade-node "^3.0.2" - staged-git-files "1.1.2" - string-argv "^0.0.2" - stringify-object "^3.2.2" - yup "^0.26.10" - -listr-silent-renderer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" - integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= - -listr-update-renderer@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" - integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^2.3.0" - strip-ansi "^3.0.1" - -listr-verbose-renderer@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" - integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== - dependencies: - chalk "^2.4.1" - cli-cursor "^2.1.0" - date-fns "^1.27.2" - figures "^2.0.0" - -listr@^0.14.2: - version "0.14.3" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" - integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== - dependencies: - "@samverschueren/stream-to-observable" "^0.3.0" - is-observable "^1.1.0" - is-promise "^2.1.0" - is-stream "^1.1.0" - listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.5.0" - listr-verbose-renderer "^0.5.0" - p-map "^2.0.0" - rxjs "^6.3.3" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -load-resources@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/load-resources/-/load-resources-0.1.1.tgz#3c588f9fbbf9967992f3e1157dc524f2023e166e" - integrity sha1-PFiPn7v5lnmS8+EVfcUk8gI+Fm4= - dependencies: - escape-string-regexp "^1.0.3" - request "^2.55.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -lodash.cond@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" - integrity sha1-9HGh2khr5g9quVXRcRVSPdHSVdU= - -lodash.sortby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" - integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= - -lodash@^4.17.10, lodash@^4.17.11: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== - -lodash@^4.17.19: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= - dependencies: - chalk "^1.0.0" - -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -log-update@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" - integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= - dependencies: - ansi-escapes "^3.0.0" - cli-cursor "^2.0.0" - wrap-ansi "^3.0.1" - -loose-envify@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-queue@0.1: - version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= - dependencies: - es5-ext "~0.10.2" - -make-dir@^1.1.0, make-dir@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -make-iterator@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" - integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== - dependencies: - kind-of "^6.0.2" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.0, map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -markdown-it@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" - integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== - dependencies: - argparse "^1.0.7" - entities "~2.0.0" - linkify-it "^2.0.0" - mdurl "^1.0.1" - uc.micro "^1.0.5" - -matchdep@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" - integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4= - dependencies: - findup-sync "^2.0.0" - micromatch "^3.0.4" - resolve "^1.4.0" - stack-trace "0.0.10" - -matcher@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" - integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== - dependencies: - escape-string-regexp "^1.0.4" - -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memoizee@0.4.X: - version "0.4.14" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" - integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== - dependencies: - d "1" - es5-ext "^0.10.45" - es6-weak-map "^2.0.2" - event-emitter "^0.3.5" - is-promise "^2.1" - lru-queue "0.1" - next-tick "1" - timers-ext "^0.1.5" - -merge-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= - dependencies: - readable-stream "^2.0.1" - -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -mime-db@~1.38.0: - version "1.38.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad" - integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.22" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd" - integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog== - dependencies: - mime-db "~1.38.0" - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.1, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= - -minipass@^2.2.1, minipass@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" - integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" - integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== - dependencies: - minipass "^2.2.1" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -mute-stdout@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" - integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -nan@^2.9.2: - version "2.13.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" - integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -needle@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.0.tgz#ce3fea21197267bacb310705a7bbe24f2a3a3492" - integrity sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg== - dependencies: - debug "^4.1.0" - iconv-lite "^0.4.4" - sax "^1.2.4" - -neo-async@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" - integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== - -next-tick@1, next-tick@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-fetch@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^5.2.1: - version "5.4.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" - integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - -node-pre-gyp@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" - integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -node-releases@^1.1.61: - version "1.1.61" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" - integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== - -nopt@^4.0.1, nopt@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - dependencies: - abbrev "1" - osenv "^0.1.4" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1, normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -now-and-later@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" - integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== - dependencies: - once "^1.3.2" - -npm-bundled@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" - integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== - -npm-packlist@^1.1.6: - version "1.4.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" - integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - -npm-path@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" - integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== - dependencies: - which "^1.2.10" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-which@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" - integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= - dependencies: - commander "^2.9.0" - npm-path "^2.0.2" - which "^1.2.10" - -npmlog@^4.0.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -nwsapi@^2.0.7: - version "2.1.3" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.3.tgz#25f3a5cec26c654f7376df6659cdf84b99df9558" - integrity sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@4.X, object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.defaults@^1.0.0, object.defaults@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" - integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= - dependencies: - array-each "^1.0.1" - array-slice "^1.0.0" - for-own "^1.0.0" - isobject "^3.0.0" - -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.1" - -object.map@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" - integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - -object.pick@^1.2.0, object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.reduce@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" - integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60= - dependencies: - for-own "^1.0.0" - make-iterator "^1.0.0" - -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.1, optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -ordered-read-streams@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" - integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= - dependencies: - readable-stream "^2.0.1" - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= - dependencies: - lcid "^1.0.0" - -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-each-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" - integrity sha1-kw89Et0fUOdDRFeiLNbwSsatf3E= - dependencies: - p-reduce "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" - integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" - integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-filepath@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" - integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= - dependencies: - is-absolute "^1.0.0" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-node-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= - -parse5@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" - integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= - dependencies: - path-root-regex "^0.1.0" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" - integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== - dependencies: - semver-compare "^1.0.0" - -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - -plugin-error@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" - integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== - dependencies: - ansi-colors "^1.0.1" - arr-diff "^4.0.0" - arr-union "^3.1.0" - extend-shallow "^3.0.2" - -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-parser-tests@6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/postcss-parser-tests/-/postcss-parser-tests-6.3.1.tgz#aacaba481b3cd1b9710df445e7d774c687fbe244" - integrity sha512-GL74Di0wqtE+2i/Q74MyJ2D6+XLVYHaM4TbD+/fd08qa2406dtEoNZqS1aLTvTJG5/tjKvCIPjJHx6q3aCdnvg== - dependencies: - chalk "^2.4.1" - fancy-log "^1.3.2" - load-resources "^0.1.1" - plugin-error "^1.0.1" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -pretty-format@^24.7.0: - version "24.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.7.0.tgz#d23106bc2edcd776079c2daa5da02bcb12ed0c10" - integrity sha512-apen5cjf/U4dj7tHetpC7UEFCvtAgnNZnBDkfPv3fokzIqyOJckAG9OlAPC1BlFALnqT/lGB2tl9EJjlK6eCsA== - dependencies: - "@jest/types" "^24.7.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" - -pretty-hrtime@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= - -process-nextick-args@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= - -process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prompts@^2.0.1: - version "2.0.4" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.0.4.tgz#179f9d4db3128b9933aa35f93a800d8fce76a682" - integrity sha512-HTzM3UWp/99A0gk51gAegwo1QRYA7xjcZufMNe33rCclFszUYAuHe1fIN/3ZmiHeGPkUsNaRyQm1hHOfM0PKxA== - dependencies: - kleur "^3.0.2" - sisteransi "^1.0.0" - -property-expr@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-1.5.1.tgz#22e8706894a0c8e28d58735804f6ba3a3673314f" - integrity sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g== - -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.24, psl@^1.1.28: - version "1.1.31" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" - integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.5: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-is@^16.8.4: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" - integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA== - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read-pkg@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" - integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= - dependencies: - normalize-package-data "^2.3.2" - parse-json "^4.0.0" - pify "^3.0.0" - -"readable-stream@2 || 3": - version "3.3.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9" - integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -regenerate-unicode-properties@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" - integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== - dependencies: - "@babel/runtime" "^7.8.4" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpu-core@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" - integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.2.0" - regjsgen "^0.5.1" - regjsparser "^0.6.4" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.2.0" - -regjsgen@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== - -regjsparser@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" - integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== - dependencies: - jsesc "~0.5.0" - -remove-bom-buffer@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" - integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== - dependencies: - is-buffer "^1.1.5" - is-utf8 "^0.2.1" - -remove-bom-stream@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" - integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= - dependencies: - remove-bom-buffer "^3.0.0" - safe-buffer "^5.1.0" - through2 "^2.0.3" - -remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -replace-ext@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" - integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= - -replace-homedir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" - integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw= - dependencies: - homedir-polyfill "^1.0.1" - is-absolute "^1.0.0" - remove-trailing-separator "^1.1.0" - -request-promise-core@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" - integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== - dependencies: - lodash "^4.17.11" - -request-promise-native@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" - integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== - dependencies: - request-promise-core "1.1.2" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.55.0, request@^2.87.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.0" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.4.3" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -requireindex@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" - integrity sha1-5UBLgVV+91225JxacgBIk/4D4WI= - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-dir@^1.0.0, resolve-dir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" - integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= - dependencies: - expand-tilde "^2.0.0" - global-modules "^1.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-options@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" - integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= - dependencies: - value-or-function "^3.0.0" - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" - integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== - dependencies: - path-parse "^1.0.6" - -resolve@^1.12.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@2.6.3, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rsvp@^4.8.4: - version "4.8.4" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.4.tgz#b50e6b34583f3dd89329a2f23a8a2be072845911" - integrity sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA== - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= - dependencies: - is-promise "^2.1.0" - -run-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" - integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== - -run-sequence@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/run-sequence/-/run-sequence-2.2.1.tgz#1ce643da36fd8c7ea7e1a9329da33fc2b8898495" - integrity sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw== - dependencies: - chalk "^1.1.3" - fancy-log "^1.3.2" - plugin-error "^0.1.2" - -rxjs@^6.3.3, rxjs@^6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" - integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== - dependencies: - tslib "^1.9.0" - -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -sax@>=0.6.0, sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - -semver-greatest-satisfied-range@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" - integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els= - dependencies: - sver-compat "^1.5.0" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== - -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" - integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.1" - to-object-path "^0.3.0" - -set-value@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - -sigmund@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-git@^1.85.0: - version "1.110.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.110.0.tgz#54eb179089d055a7783d32399246cebc9d9933e9" - integrity sha512-UYY0rQkknk0P5eb+KW+03F4TevZ9ou0H+LoGaj7iiVgpnZH4wdj/HTViy/1tNNkmIPcmtxuBqXWiYt2YwlRKOQ== - dependencies: - debug "^4.0.1" - -sisteransi@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.0.tgz#77d9622ff909080f1c19e5f4a1df0c1b0a27b88c" - integrity sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= - -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== - dependencies: - atob "^2.1.1" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.5.6: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sparkles@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" - integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" - integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-trace@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" - integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= - -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== - -staged-git-files@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" - integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - -stream-exhaust@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" - integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= - -string-argv@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" - integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= - -string-length@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" - integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= - dependencies: - astral-regex "^1.0.0" - strip-ansi "^4.0.0" - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string_decoder@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" - integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== - dependencies: - safe-buffer "~5.1.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-object@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-bom-string@1.X: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" - integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -strip-json-comments@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.0.0, supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -sver-compat@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" - integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg= - dependencies: - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - -symbol-observable@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== - -symbol-tree@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" - integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= - -synchronous-promise@^2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.7.tgz#3574b3d2fae86b145356a4b89103e1577f646fe3" - integrity sha512-16GbgwTmFMYFyQMLvtQjvNWh30dsFe1cAW5Fg1wm5+dg84L9Pe36mftsIRU95/W2YsISxsz/xq4VB23sqpgb/A== - -table@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" - integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== - dependencies: - ajv "^6.9.1" - lodash "^4.17.11" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tar@^4: - version "4.4.8" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" - integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.3.4" - minizlib "^1.1.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.2" - -test-exclude@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" - integrity sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA== - dependencies: - arrify "^1.0.1" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^1.0.1" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= - -through2-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" - integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== - dependencies: - through2 "~2.0.0" - xtend "~4.0.0" - -through2@2.X, through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through2@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" - integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== - dependencies: - readable-stream "2 || 3" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -timers-ext@^0.1.5: - version "0.1.7" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== - dependencies: - es5-ext "~0.10.46" - next-tick "1" - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-absolute-glob@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" - integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= - dependencies: - is-absolute "^1.0.0" - is-negated-glob "^1.0.0" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -to-through@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" - integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= - dependencies: - through2 "^2.0.3" - -toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -tough-cookie@^2.3.3, tough-cookie@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== - dependencies: - psl "^1.1.24" - punycode "^1.4.1" - -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= - dependencies: - punycode "^2.1.0" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= - -tslib@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -uc.micro@^1.0.1, uc.micro@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" - integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== - -uglify-js@^3.1.4: - version "3.6.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.4.tgz#88cc880c6ed5cf9868fdfa0760654e7bed463f1d" - integrity sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA== - dependencies: - commander "~2.20.3" - source-map "~0.6.1" - -unc-path-regex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= - -undertaker-registry@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" - integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= - -undertaker@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.2.1.tgz#701662ff8ce358715324dfd492a4f036055dfe4b" - integrity sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA== - dependencies: - arr-flatten "^1.0.1" - arr-map "^2.0.0" - bach "^1.0.0" - collection-map "^1.0.0" - es6-weak-map "^2.0.1" - last-run "^1.1.0" - object.defaults "^1.0.0" - object.reduce "^1.0.0" - undertaker-registry "^1.0.0" - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" - integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== - -union-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" - integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^0.4.3" - -unique-stream@^2.0.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" - integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== - dependencies: - json-stable-stringify-without-jsonify "^1.0.1" - through2-filter "^3.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" - integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -util.promisify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -uuid@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -v8flags@^3.0.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.2.tgz#fc5cd0c227428181e6c29b2992e4f8f1da5e0c9f" - integrity sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw== - dependencies: - homedir-polyfill "^1.0.1" - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -value-or-function@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" - integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vinyl-fs@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" - integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== - dependencies: - fs-mkdirp-stream "^1.0.0" - glob-stream "^6.1.0" - graceful-fs "^4.0.0" - is-valid-glob "^1.0.0" - lazystream "^1.0.0" - lead "^1.0.0" - object.assign "^4.0.4" - pumpify "^1.3.5" - readable-stream "^2.3.3" - remove-bom-buffer "^3.0.0" - remove-bom-stream "^1.2.0" - resolve-options "^1.1.0" - through2 "^2.0.0" - to-through "^2.0.0" - value-or-function "^3.0.0" - vinyl "^2.0.0" - vinyl-sourcemap "^1.1.0" - -vinyl-sourcemap@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" - integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= - dependencies: - append-buffer "^1.0.2" - convert-source-map "^1.5.0" - graceful-fs "^4.1.6" - normalize-path "^2.1.1" - now-and-later "^2.0.0" - remove-bom-buffer "^3.0.0" - vinyl "^2.0.0" - -vinyl-sourcemaps-apply@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" - integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= - dependencies: - source-map "^0.5.1" - -vinyl@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" - integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - -w3c-hr-time@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" - integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= - dependencies: - browser-process-hrtime "^0.1.2" - -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^6.4.1: - version "6.5.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" - integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -whatwg-url@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" - integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.10, which@^1.2.14, which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" - integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" - integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== - dependencies: - async-limiter "~1.0.0" - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xml2js@^0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - -xtend@~4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - -"y18n@^3.2.1 || ^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yallist@^3.0.0, yallist@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" - integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== - -yaml@^1.7.2: - version "1.10.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" - integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== - -yandex-speller@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/yandex-speller/-/yandex-speller-4.1.0.tgz#ccdd565705512934ccdcae2df332491a4834761c" - integrity sha512-z13o3GCMxm5g/MU28JCIdu9SXsAoShroqAheFciS3K0wa2JRkA1y5qASZuavJuaCl0KG5RhTjo8gdkbyp6QC+w== - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= - dependencies: - camelcase "^3.0.0" - -yargs@^12.0.2: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -yargs@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" - -yaspeller@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yaspeller/-/yaspeller-7.0.0.tgz#c49af3b5b147edda430996fa1e65b1e577bfb4f4" - integrity sha512-M8phUfHrL0dGCU5jUK9k85hikCSmjpPFAdjnH/Lg1/E81TEuTI7m8m5jhIWAXHWjfZ+wPEhGBz8HLDuEs4areA== - dependencies: - async "^3.2.0" - chalk "^4.0.0" - commander "^3.0.0" - cosmiconfig "^6.0.0" - entities "^2.0.0" - escape-html "^1.0.3" - eyo-kernel "^2.5.6" - glob "^7.1.6" - isutf8 "^2.1.0" - markdown-it "^10.0.0" - minimatch "^3.0.4" - node-fetch "^2.6.0" - strip-json-comments "^3.0.1" - xml2js "^0.4.23" - yandex-speller "^4.1.0" - -yup@^0.26.10: - version "0.26.10" - resolved "https://registry.yarnpkg.com/yup/-/yup-0.26.10.tgz#3545839663289038faf25facfc07e11fd67c0cb1" - integrity sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw== - dependencies: - "@babel/runtime" "7.0.0" - fn-name "~2.0.1" - lodash "^4.17.10" - property-expr "^1.5.0" - synchronous-promise "^2.0.5" - toposort "^2.0.2"