diff --git a/.github/actions/free-disk-space/action.yaml b/.github/actions/free-disk-space/action.yaml index 5d07acc78924..c5f936895d54 100644 --- a/.github/actions/free-disk-space/action.yaml +++ b/.github/actions/free-disk-space/action.yaml @@ -5,10 +5,11 @@ runs: steps: - name: Free Disk Space (Ubuntu) if: runner.os == 'Linux' - uses: jlumbroso/free-disk-space@main + uses: xc2/free-disk-space@fbe203b3788f2bebe2c835a15925da303eaa5efe # v1.0.0 with: # We need to reclaim some space, but uninstalling everyting takes # too long. So we'll just remove some of the larger packages. + # https://github.com/jlumbroso/free-disk-space/pull/26 android: true dotnet: true haskell: true diff --git a/.github/workflows/release_cli.yml b/.github/workflows/release_cli.yml index e37c0db478a2..363ec8d8b175 100644 --- a/.github/workflows/release_cli.yml +++ b/.github/workflows/release_cli.yml @@ -144,7 +144,7 @@ jobs: # Upload the CLI binary as a build artifact - name: Upload CLI artifact - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: cli-${{ matrix.target }} path: ./dist/biome-* @@ -169,7 +169,7 @@ jobs: run: wasm-pack build --out-dir ../../packages/@biomejs/wasm-web --target web --release --scope biomejs crates/biome_wasm - name: Upload WASM artifact - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: wasm-${{ matrix.target }} path: | diff --git a/.github/workflows/release_js_api.yml b/.github/workflows/release_js_api.yml index c5615ade8303..7e3c8de109c7 100644 --- a/.github/workflows/release_js_api.yml +++ b/.github/workflows/release_js_api.yml @@ -102,7 +102,7 @@ jobs: pnpm --filter @biomejs/js-api run build - name: Upload JS API artifact - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: js-api path: | diff --git a/.github/workflows/release_knope.yml b/.github/workflows/release_knope.yml index 37a7a2bb019e..bf31af078080 100644 --- a/.github/workflows/release_knope.yml +++ b/.github/workflows/release_knope.yml @@ -128,7 +128,7 @@ jobs: - name: Upload Artifact - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: cli-${{ matrix.target }} path: ./dist/biome-* @@ -153,7 +153,7 @@ jobs: run: wasm-pack build --out-dir ../../packages/@biomejs/wasm-web --target web --release --scope biomejs crates/biome_wasm - name: Upload WASM artifact - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: wasm-${{ matrix.target }} path: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d87edec4101..f5ff90b52208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b ### Analyzer +#### New features + +- Implement [nursery/useConsistentMemberAccessibility](https://github.com/biomejs/biome/issues/3271). Contributed by @seitarof + #### Enhancements - Implement [css suppression action](https://github.com/biomejs/biome/issues/3278). Contributed by @togami2864 @@ -25,6 +29,23 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b #### New features - Add `--graphql-linter-enabled` option, to control whether the linter should be enabled or not for GraphQL files. Contributed by @ematipico + +- New EXPERIMENTAL `search` command. The search command allows you to search a Biome project using [GritQL syntax](https://biomejs.dev/reference/gritql). + + GritQL is a powerful language that lets you do _structural_ searches on your codebase. This means that trivia such as whitespace or even the type of strings quotes used will be ignored in your search query. It also has many features for querying the structure of your code, making it much more elegant for searching code than regular expressions. + + While we believe this command may already be useful to users in some situations (especially when integrated in the IDE extensions!), we also had an ulterior motive for adding this command: We intend to utilize GritQL for our plugin efforts, and by allowing our users to try it out in a first iteration, we hope to gain insight in the type of queries you want to do, as well as the bugs we need to focus on. + + For now, the `search` command is explicitly marked as EXPERIMENTAL, since many bugs remain. Keep this in mind when you try it out, and please [let us know](https://github.com/biomejs/biome/issues) your issues! + + Note: GritQL escapes code snippets using backticks, but most shells interpret backticks as command invocations. To avoid this, it's best to put _single quotes_ around your Grit queries. + + ```shell + biome search '`console.log($message)`' # find all `console.log` invocations + ``` + + Contributed by @arendjr and @BackupMiles + - The option `--max-diagnostics` now accept a `none` value, which lifts the limit of diagnostics shown. Contributed by @ematipico - Add a new reporter `--reporter=gitlab`, that emits diagnostics for using the [GitLab Code Quality report](https://docs.gitlab.com/ee/ci/testing/code_quality.html#implement-a-custom-tool). @@ -94,6 +115,14 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Conaclos +- The CLI now returns an error code when calling a command in `stdin` mode, and the contents of the files aren't fixed. For example, the following example will result in an error code of `1` because the `lint` command triggers some lint rules: + + ```shell + echo "let x = 1" | biome lint --stdin-file-path=stdin.js + ``` + + Contributed by @ematipico + #### Bug fixes - `biome lint --write` now takes `--only` and `--skip` into account ([#3470](https://github.com/biomejs/biome/issues/3470)). Contributed by @Conaclos @@ -106,6 +135,10 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - Fix JSX expressions for `noAriaHiddenOnFocusable` ([#3708](https://github.com/biomejs/biome/pull/3708)) . Contributed by @anthonyshew +- Fix edge case for `` elements that use `role="img"` ([#3728](https://github.com/biomejs/biome/pull/3728)) . Contributed by @anthonyshew + +- Fix [#3633](https://github.com/biomejs/biome/issues/3633), where diagnostics where incorrectly printed if the code has errors. Contributed by @ematipico + ### Configuration - Add support for loading configuration from `.editorconfig` files ([#1724](https://github.com/biomejs/biome/issues/1724)). @@ -177,6 +210,7 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b #### Bug fixes - Fix [#3577](https://github.com/biomejs/biome/issues/3577), where the update of the configuration file was resulting in the creation of a new internal project. Contributed by @ematipico +- Fix [#3696](https://github.com/biomejs/biome/issues/3696), where `biome.jsonc` was incorrectly parsed with incorrect options. Contributed by @ematipico ### Formatter @@ -194,6 +228,20 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Conaclos +- The CSS formatter is enabled by default. Which means that you don't need to opt-in anymore using the configuration file `biome.json`: + + ```diff + { + - "css": { + - "formatter": { + - "enabled": true + - } + - } + } + ``` + + Contributed by @ematipico + #### Bug fixes - Keep the parentheses around `infer ... extends` declarations in type unions and type intersections ([#3419](https://github.com/biomejs/biome/issues/3419)). Contributed by @Conaclos @@ -278,6 +326,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - Add [nursery/noUselessEscapeInRegex](https://biomejs.dev/linter/rules/no-useless-escape-in-regex/). Contributed by @Conaclos +- Add [nursery/useConsistentMemberAccessibility](https://biomejs.dev/linter/rules/use-consistent-member-accessibility/). Contributed by @seitarof + #### Enhancements - [noInvalidUseBeforeDeclaration](https://biomejs.dev/linter/rules/no-invalid-use-before-declaration) now reports direct use of an enum member before its declaration. @@ -332,6 +382,13 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Conaclos +- [noUndeclaredVariables](https://biomejs.dev/linter/rules/no-undeclared-variables/) recognized Svelte 5 runes in Svelte components and svelte files. + + Svelte 5 introduced runes. + The rule now recognizes Svelte 5 runes in files ending with the `.svelte`, `.svelte.js` or `.svelte.ts` extensions. + + Contributed by @Conaclos + - [noBlankTarget](https://biomejs.dev/linter/rules/no-blank-target) now supports an array of allowed domains. The following configuration allows `example.com` and `example.org` as blank targets. @@ -368,6 +425,24 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b - Add an `ignoreNull` option for [noDoubleEquals](https://biomejs.dev/linter/rules/no-double-equals/). Contributed by @peaBerberian. +- The rule `noDuplicateObjectKeys` now works for JSON and JSONC files. Contributed by @ematipico + +- The CSS linter is now enabled by default. Which means that you don't need to opt-in anymore using the configuration file `biome.json`: + + ```diff + { + - "css": { + - "linter": { + - "enabled": true + - } + - } + } + ``` + + Contributed by @ematipico + +- The rule `noRedundantUseStrict` no longer reports `use strict` when the `package.json` marks the file as a script using the field `"type": "commonjs"`. Contributed by @ematipico + #### Bug fixes - Don't request alt text for elements hidden from assistive technologies ([#3316](https://github.com/biomejs/biome/issues/3316)). Contributed by @robintown @@ -390,6 +465,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Conaclos +- [noRedeclare](https://biomejs.dev/linter/rules/no-redeclare/) no longer report a variable named as the function expression where it is declared. Contributed by @Conaclos + - [noMultipleSpacesInRegularExpressionLiterals](https://biomejs.dev/linter/rules/no-multiple-spaces-in-regular-expression-literals/) now correctly provides a code fix when unicode characters are used. - `useAdjacentOverloadSignatures` no longer reports a `#private` class member and a public class member that share the same name ([#3309](https://github.com/biomejs/biome/issues/3309)). @@ -466,6 +543,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b Contributed by @Conaclos +- The JSON parser now allows comments in `jest.config.json`. Contributed by @Conaclos + #### Bug fixes - Fix [#3287](https://github.com/biomejs/biome/issues/3287) nested selectors with pseudo-classes. Contributed by @denbezrukov @@ -487,6 +566,7 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b } ``` Contributed by @ah-yu +- Fix [#3464](https://github.com/biomejs/biome/issues/3464) by enabling JSX in `.vue` files that use the `lang='jsx'` or `lang='tsx'` attribute. Contributed by @ematipico ## v1.8.3 (2024-06-27) diff --git a/Cargo.lock b/Cargo.lock index e3def6d00a94..02e19ba2aef0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,7 +171,7 @@ dependencies = [ "crossbeam", "dashmap 6.0.1", "hdrhistogram", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", "libc", "mimalloc", @@ -215,7 +215,7 @@ dependencies = [ "biome_json_syntax", "biome_rowan", "bpaf", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", "oxc_resolver", "rustc-hash 1.1.0", @@ -353,7 +353,7 @@ dependencies = [ "biome_json_syntax", "biome_rowan", "enumflags2", - "indexmap 2.4.0", + "indexmap 2.5.0", "schemars", "serde", "serde_json", @@ -436,7 +436,7 @@ dependencies = [ "cfg-if", "countme", "drop_bomb", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", "rustc-hash 1.1.0", "schemars", @@ -473,13 +473,15 @@ dependencies = [ "crossbeam", "directories", "enumflags2", - "indexmap 2.4.0", + "indexmap 2.5.0", "oxc_resolver", "parking_lot", "rayon", "rustc-hash 1.1.0", "schemars", "serde", + "serde_json", + "smallvec", "tracing", ] @@ -761,7 +763,7 @@ dependencies = [ "bitflags 2.6.0", "drop_bomb", "expect-test", - "indexmap 2.4.0", + "indexmap 2.5.0", "quickcheck", "quickcheck_macros", "rustc-hash 1.1.0", @@ -1033,7 +1035,7 @@ dependencies = [ "enumflags2", "getrandom 0.2.15", "ignore", - "indexmap 2.4.0", + "indexmap 2.5.0", "insta", "oxc_resolver", "regex", @@ -1142,6 +1144,8 @@ dependencies = [ "biome_rowan", "biome_unicode_table", "biome_yaml_syntax", + "quickcheck", + "quickcheck_macros", "tracing", ] @@ -2121,9 +2125,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -2546,18 +2550,20 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "oxc_resolver" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f862ee8e1ba728378ac7e007de195ae00fbb21337ef152380c052cc07e2ee2" +checksum = "e7fe4d07afdfcf6b1d7fb952e6691d82692a54b71964a377cf49f3e47dac283d" dependencies = [ + "cfg-if", "dashmap 6.0.1", "dunce", - "indexmap 2.4.0", + "indexmap 2.5.0", "json-strip-comments", "once_cell", "rustc-hash 2.0.0", "serde", "serde_json", + "simdutf8", "thiserror", "tracing", ] @@ -2779,7 +2785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfc1a6a5406a114913df2df8507998c755311b55b78584bed5f6e88f6417c4d4" dependencies = [ "chrono", - "indexmap 2.4.0", + "indexmap 2.5.0", "newtype-uuid", "quick-xml", "strip-ansi-escapes", @@ -3157,7 +3163,7 @@ checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" dependencies = [ "dyn-clone", "indexmap 1.9.3", - "indexmap 2.4.0", + "indexmap 2.5.0", "schemars_derive", "serde", "serde_json", @@ -3241,7 +3247,7 @@ version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -3283,7 +3289,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "ryu", "serde", @@ -3308,6 +3314,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "similar" version = "2.6.0" @@ -3653,7 +3665,7 @@ version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", diff --git a/Cargo.toml b/Cargo.toml index ec8033233ce1..5ace77fc87a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -166,10 +166,10 @@ dashmap = "6.0.1" enumflags2 = "0.7.10" getrandom = "0.2.15" ignore = "0.4.22" -indexmap = { version = "2.4.0", features = ["serde"] } +indexmap = { version = "2.5.0", features = ["serde"] } insta = "1.39.0" natord = "1.0.9" -oxc_resolver = "1.10.2" +oxc_resolver = "1.11.0" proc-macro2 = "1.0.86" quickcheck = "1.0.3" quickcheck_macros = "1.0.0" diff --git a/Dockerfile.benchmark b/Dockerfile.benchmark index ccd4316a4310..1fd1fc39698d 100644 --- a/Dockerfile.benchmark +++ b/Dockerfile.benchmark @@ -14,4 +14,5 @@ WORKDIR /usr/src/benchmark COPY ./benchmark . RUN npm ci -RUN node run.js +RUN node bench.js formatter +RUN node bench.js linter diff --git a/benchmark/.prettierignore b/benchmark/.prettierignore new file mode 100644 index 000000000000..617a767169c3 --- /dev/null +++ b/benchmark/.prettierignore @@ -0,0 +1,4 @@ +**/*.json +**/*.css +**/*.md +**/*.htnl diff --git a/benchmark/.prettierrc.json b/benchmark/.prettierrc.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/benchmark/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/benchmark/README.md b/benchmark/README.md index b864149b1643..376a1863bff9 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -9,8 +9,11 @@ Run in the root directory, not `./benchmark` ## Running locally 1. Install hyperfine: `cargo install hyperfine` -2. Install node modules: `npm i` -3. Run the benchmarks: `node run.js` +2. Install node modules: `pnpm i` +3. Run one of benchmark suites: + - the benchmarks of the formatters: `node bench.js formatter` + - the benchmarks of the linter: `node bench.js linter` + ## Results @@ -21,46 +24,39 @@ Setup: MacBook Pro (13-inch, M1, 2020) * Biome's ~25 times faster than Prettier * Biome's ~20 times faster than parallel-prettier * Biome's ~20 times faster than `xargs -P`[^1] -* Biome's 1.5-2 times faster than `dprint` +* Biome's 1.5 to 2 times faster than `dprint` * Biome single-threaded is ~7 times faster than Prettier. +The speed-ups for the multithreaded benchmarks can vary significantly depending on the setup. +For example, Biome is 100 times faster than Prettier on an M1 Max with 10 cores. [^1]: Run `time find lib/ examples declarations benchmark -name '*.js' -print0 | xargs -P8 -0 -n 200 npx prettier --write --loglevel=error` in the `target/webpack` directory. I manually tinkered with the `-n` parameter to get the fastest run. ### Linting -* Biome's ~15x times faster than ESLint +* Biome's ~15x times faster than ESLint (without any plugins) * Biome single-threaded is ~4 times faster than ESLint. -The speed-ups for the multithreaded benchmarks can vary significantly depending on the setup. For example, Biome is 100 times faster than Prettier on an M1 Max with 10 cores. - -## Analysis - -### Formatter - -* Biome's formatter is fast :). -* It should be possible to speed up Prettier. Biome's architecture isn't that different, and native has its advantages, but Prettier should be able to compete in single-threaded mode. - -### Linting - -* Biome's linter is fast but there is room for improvements +* Biome's linter is fast, but there is room for improvements * Biome's linter spends significant time building the semantic model, the control flow graph, and matching queries. I'm convinced there's room for improvement ([3565](https://github.com/rome/tools/pull/3565), [3569](https://github.com/rome/tools/pull/3569)). * Computing the diff for code fixes is expensive. Biome can spend up to 3s computing diffs (not measured by these benchmarks, see explanations below) + ## Notes We've been careful to create fair benchmarks. This section explains some of the decisions behind the benchmark setup and how these decisions affect the results. Please [let us know](https://github.com/rome/tools/issues) if you have ideas on how to make the benchmarks fairer or if there's a mistake with our setup. ### Formatting -* Compares the wall time of Biome, Prettier, and dprint to format all files in a project where all files are correctly formatted. +* Compares the wall time of Biome, Prettier, and dprint to format all files in a project where all files are correctly formatted. To ensure that files are correctly formatted we run twice a toll (warm-up) before benchmarking it. * dprint and Prettier support incremental formatting to only format changed files, whereas Biome does not. This benchmark does not measure incremental formatting as it measures cold formatting time. You may see significant speedups on subsequent formatting runs when enabling incremental formatting. * The benchmark limits Prettier to only format JavaScript and TypeScript files because Biome doesn't support other file types. -* Biome only prints a summary with the number of formatted files. The prettier benchmark uses `--loglevel=error` for a fairer benchmark so that Prettier doesn't print every filename. +* Biome only prints a summary with the number of formatted files. The prettier benchmark uses `--log-level=error` for a fairer benchmark so that Prettier doesn't print every filename. ### Linting * Compares the wall time of Biome and ESLint to check all files in a project. * Only enables rules that both Biome and ESLint support. +* The comparison includes ESLint without plugin and ESLint with the TypeScript ESLint plugin. + To have a fair comparison we don't enable any rules that require type information because this is known to be very slow and Biome has not such capabilities yet. * Biome prints rich diffs for each lint diagnostic, whereas ESLint only shows the name and description of the lint rule. That's why the benchmark uses `--max-diagnostics=0` when running Biome because Biome then only counts diagnostics without generating the diffs. Overall, this results in a more accurate comparison but has the downside that Biome only prints the diagnostic count, whereas ESLint prints a line for each lint error. - diff --git a/benchmark/bench.biome.json b/benchmark/bench.biome.json deleted file mode 100644 index 2d588ebc5d96..000000000000 --- a/benchmark/bench.biome.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "../packages/@biomejs/biome/configuration_schema.json", - "linter": { - "enabled": true, - "rules": { - "recommended": false, - "complexity": { - "noExtraBooleanCast": "error" - }, - "correctness": { - "noArguments": "error", - "noAsyncPromiseExecutor": "error", - "noCatchAssign": "error", - "noCompareNegZero": "error", - "noDebugger": "error", - "noDelete": "error", - "noDoubleEquals": "error", - "noDuplicateParameters": "error", - "noEmptyPattern": "error", - "noFunctionAssign": "error", - "noImportAssign": "error", - "noLabelVar": "error", - "noMultipleSpacesInRegularExpressionLiterals": "error", - "noNewSymbol": "error", - "noRestrictedGlobals": "error", - "noShadowRestrictedNames": "error", - "noSparseArray": "error", - "noUnreachable": "error", - "noUnsafeNegation": "error", - "noUnusedVariables": "error", - "useValidTypeof": "error" - }, - "nursery": { - "noConstAssign": "warn", - "useValidForDirection": "warn" - } - } - } -} diff --git a/benchmark/bench.eslint.config.js b/benchmark/bench.eslint.config.js deleted file mode 100644 index 0b051416a0d7..000000000000 --- a/benchmark/bench.eslint.config.js +++ /dev/null @@ -1,29 +0,0 @@ -export default [ - { - rules: { - "no-extra-boolean-cast": "error", - "prefer-rest-params": "error", - "no-async-promise-executor": "error", - "no-ex-assign": "error", - "no-compare-neg-zero": "error", - "no-debugger": "error", - "no-delete-var": "error", - eqeqeq: "error", - "no-dupe-args": "error", - "no-empty-pattern": "error", - "no-func-assign": "error", - "no-import-assign": "error", - "no-label-var": "error", - "no-new-symbol": "error", - "no-restricted-globals": "error", - "no-shadow-restricted-names": "error", - "no-sparse-arrays": "error", - "no-unreachable": "error", - "no-unsafe-negation": "error", - "no-unused-vars": "error", - "valid-typeof": "error", - "no-const-assign": "warn", - "for-direction": "warn", - } - } -]; diff --git a/benchmark/bench.js b/benchmark/bench.js new file mode 100644 index 000000000000..0ba3b7f74476 --- /dev/null +++ b/benchmark/bench.js @@ -0,0 +1,250 @@ +#!/usr/bin/node + +import { execSync } from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import * as process from "node:process"; +import * as util from "node:util"; + +const REPOSITORIES = { + eslint: { + repository: "https://github.com/eslint/eslint.git", + lintedDirs: ["lib", "messages", "tests/lib", "tests/performance", "tools"], + }, + prettier: { + repository: "https://github.com/prettier/prettier.git", + formattedDirs: ["src", "scripts"], + }, + webpack: { + repository: "https://github.com/webpack/webpack.git", + formattedDirs: ["lib", "examples", "benchmark"], + lintedDirs: ["lib"], + }, +}; + +const TMP_DIR = path.resolve("./target"); + +function benchmarkFormatter(biomeBin, options) { + // Run Dprint once to run the installer + execSync("npx dprint --version"); + + for (const [name, config] of Object.entries(REPOSITORIES)) { + if ( + !config.formattedDirs || + ("repository" in options && options.repository !== name) + ) { + continue; + } + console.info(`\n⌛ repository: ${name}`); + const projectDirectory = cloneProject( + name, + config.repository, + config.formattedDirs, + ); + console.info(""); + + const dirs = config.formattedDirs.join(" "); + const dirGlobs = config.formattedDirs.map((dir) => `"${dir}/**"`).join(" "); + const biomeCommand = `${biomeBin} format --config-path=../../ --write --max-diagnostics=0 ${dirs}`; + const benchCommands = { + prettier: `../../node_modules/.bin/prettier --config=../../.prettierrc.json --ignore-path=../../.prettierignore --write --log-level=error ${dirs}`, + // FIXME: Parallel Prettier is crashing on Node 22 + // "parallel-prettier": `../../node_modules/.bin/pprettier --write --concurrency ${os.cpus().length} ${dirGlobs}`, + dprint: `../../node_modules/dprint/dprint fmt --config=../../dprint.json ${dirGlobs}`, + biome: biomeCommand, + "biome-1-thread": withEnvVariable("RAYON_NUM_THREADS", "1", biomeCommand), + }; + + let suite = ""; + for (const benchName of Object.keys(benchCommands)) { + if ("bench" in options && !options.bench.includes(benchName)) { + continue; + } + suite += ` -n "${benchName}" '${benchCommands[benchName]}'`; + } + if (suite.length === 0) { + console.error(`Benchmark '${options.bench}' doesn't exist.`); + process.exit(1); + } + + // Run 2 warmups to make sure the files are formatted correctly + let hyperfineCommand = `hyperfine --warmup 2 --shell=${shellOption()} ${suite}`; + if (options.verbose) { + hyperfineCommand += " --show-output"; + console.info(`${hyperfineCommand}\n`); + } + + execSync(hyperfineCommand, { + cwd: projectDirectory, + stdio: "inherit", + }); + } +} + +function benchmarkLinter(biomeBin, options) { + for (const [name, config] of Object.entries(REPOSITORIES)) { + if ( + !config.lintedDirs || + ("repository" in options && options.repository !== name) + ) { + continue; + } + console.info(`\n⌛ repository: ${name}`); + const projectDirectory = cloneProject( + name, + config.repository, + config.formattedDirs, + ); + console.info(""); + + const dirs = config.lintedDirs.map((dir) => `"${dir}"`).join(" "); + const biomeCmd = `"${biomeBin}" lint --config-path=../../ --max-diagnostics=0 ${dirs}`; + const benchCommands = { + eslint: `../../node_modules/.bin/eslint --quiet --config=../../eslint.config.js --no-ignore ${dirs}`, + "ts-eslint": `../../node_modules/.bin/eslint --quiet --config=../../ts-eslint.config.js --no-ignore ${dirs}`, + biome: biomeCmd, + "biome-1-thread": withEnvVariable("RAYON_NUM_THREADS", "1", biomeCmd), + "ts-biome": `"${biomeBin}" lint --config-path=../../ts-biome.json --max-diagnostics=0 ${dirs}`, + }; + + let suite = ""; + for (const benchName of Object.keys(benchCommands)) { + if ("bench" in options && !options.bench.includes(benchName)) { + continue; + } + suite += ` -n "${benchName}" '${benchCommands[benchName]}'`; + } + if (suite.length === 0) { + console.error(`Benchmark '${options.bench}' doesn't exist.`); + process.exit(1); + } + + let hyperfineCommand = `hyperfine --ignore-failure --shell=${shellOption()} ${suite}`; + if (options.verbose) { + hyperfineCommand += " --show-output"; + console.info(`${hyperfineCommand}\n`); + } + + execSync(hyperfineCommand, { + cwd: projectDirectory, + stdio: "inherit", + }); + } +} + +function shellOption() { + if (process.platform == "win32") { + // Use Powershell so that it is possible to set an environment variable for a single command (ugh!) + return "powershell"; + } else { + return "default"; + } +} + +function withEnvVariable(name, value, command) { + switch (process.platform) { + case "win32": { + return `$Env:${name}=${value}; ${command}`; + } + default: + return `${name}="${value}" ${command}`; + } +} + +function withDirectory(cwd) { + return { + run(command, options) { + execSync(command, { + cwd, + ...options, + }); + }, + }; +} + +function cloneProject(name, repository, dirs = []) { + const projectDirectory = path.join(TMP_DIR, name); + + const inProjectDirectory = withDirectory(projectDirectory); + + if (fs.existsSync(projectDirectory)) { + inProjectDirectory.run("git reset --hard @{u}"); + inProjectDirectory.run("git clean -df"); + inProjectDirectory.run("git pull --quiet --depth=1 --ff-only"); + } else { + withDirectory(TMP_DIR).run( + `git clone --quiet --depth=1 ${dirs.length > 0 ? "--sparse" : ""} ${repository}`, + { + stdio: "inherit", + }, + ); + } + + if (dirs.length > 0) { + console.info( + `Adding directories ${dirs.join()} to sparse checkout in ${projectDirectory}`, + ); + inProjectDirectory.run(`git sparse-checkout add ${dirs.join(" ")}`); + } + + return projectDirectory; +} + +function buildBiome() { + console.info("Building Biome..."); + execSync( + withEnvVariable( + "BIOME_VERSION", + "0.0.0", + "cargo build --bin biome --release", + ), + { + stdio: "inherit", + }, + ); + return path.resolve("../target/release/biome"); +} + +function run({ positionals, values: options }) { + fs.mkdirSync(TMP_DIR, { recursive: true }); + let biomeBinPath; + if ("biome" in options) { + biomeBinPath = options.biome; + } else { + biomeBinPath = buildBiome(); + } + switch (positionals[0]) { + case "formatter": + benchmarkFormatter(biomeBinPath, options); + break; + case "linter": + benchmarkLinter(biomeBinPath, options); + break; + default: + console.error( + `A positional argument among 'formatter' and 'linter' must be passed.`, + ); + process.exit(1); + } +} + +run( + util.parseArgs({ + allowPositionals: true, + options: { + bench: { + multiple: true, + type: "string", + }, + biome: { + type: "string", + }, + repository: { + type: "string", + }, + verbose: { + type: "boolean", + }, + }, + }), +); diff --git a/benchmark/biome.json b/benchmark/biome.json new file mode 100644 index 000000000000..84d8e7851659 --- /dev/null +++ b/benchmark/biome.json @@ -0,0 +1,112 @@ +{ + "$schema": "../packages/@biomejs/biome/configuration_schema.json", + "formatter": { + "include": [ + "**/*.js", + "**/*.jsx", + "**/*.cjs", + "**/*.ts", + "**/*.tsx" + ], + "indentStyle": "space" + }, + "linter": { + "include": [ + "**/*.js" + ], + "rules": { + "recommended": false, + "complexity": { + "noExtraBooleanCast": "error", + "noMultipleSpacesInRegularExpressionLiterals": "error", + "noUselessCatch": "error", + "noUselessConstructor": "error", + "noUselessLabel": "error", + "noUselessRename": "error", + "noVoid": "error", + "noWith": "error", + "useArrowFunction": "error", + "useLiteralKeys": "error", + "useRegexLiterals": "error" + }, + "correctness": { + "noConstAssign": "error", + "noConstantCondition": "error", + "noConstructorReturn": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInnerDeclarations": "error", + "noInvalidConstructorSuper": "error", + "noInvalidNewBuiltin": "error", + "noInvalidUseBeforeDeclaration": "error", + "noNewSymbol": "error", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noSwitchDeclarations": "error", + "noUndeclaredVariables": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedLabels": "error", + "noUnusedPrivateClassMembers": "error", + "noUnusedVariables": "error", + "useArrayLiterals": "error", + "useIsNan": "error", + "useValidForDirection": "error", + "useYield": "error" + }, + "security": { + "noGlobalEval": "error" + }, + "style": { + "noArguments": "error", + "noCommaOperator": "error", + "noParameterAssign": "error", + "noVar": "error", + "useConst": "error", + "useCollapsedElseIf": "error", + "useDefaultParameterLast": "error", + "useExponentiationOperator": "error", + "useNumericLiterals": "error", + "useSingleVarDeclarator": "error", + "useTemplate": "error" + }, + "suspicious": { + "noAsyncPromiseExecutor": "error", + "noAssignInExpressions": "error", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCompareNegZero": "error", + "noConfusingLabels": "error", + "noControlCharactersInRegex": "error", + "noDebugger": "error", + "noDoubleEquals": "error", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyBlockStatements": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noImportAssign": "error", + "noLabelVar": "error", + "noMisleadingCharacterClass": "error", + "noPrototypeBuiltins": "error", + "noRedeclare": "error", + "noSelfCompare": "error", + "noShadowRestrictedNames": "error", + "noSparseArray": "error", + "noUnsafeNegation": "error", + "useAwait": "error", + "useDefaultSwitchClauseLast": "error", + "useGetterReturn": "error", + "useValidTypeof": "error" + } + } + } +} diff --git a/benchmark/dprint.json b/benchmark/dprint.json index 91ec9208092f..a9a8d4bd51a9 100644 --- a/benchmark/dprint.json +++ b/benchmark/dprint.json @@ -1,7 +1,13 @@ { - "incremental": false, - "typescript": {}, - "includes": ["**/*.{ts,tsx,js,jsx,cjs,mjs}"], - "excludes": ["**/node_modules"], - "plugins": ["https://plugins.dprint.dev/typescript-0.77.0.wasm"] + "incremental": false, + "typescript": {}, + "includes": [ + "**/*.{js,jsx,cjs,ts,tsx}" + ], + "excludes": [ + "**/node_modules" + ], + "plugins": [ + "https://plugins.dprint.dev/typescript-0.91.6.wasm" + ] } diff --git a/benchmark/eslint.config.js b/benchmark/eslint.config.js new file mode 100644 index 000000000000..57c86fb64bae --- /dev/null +++ b/benchmark/eslint.config.js @@ -0,0 +1,105 @@ +export default [ + { + files: ["**/*.js"], + languageOptions: { + parserOptions: { + ecmaFeatures: { modules: true }, + ecmaVersion: "latest", + }, + }, + rules: { + // Biome complexity + "no-extra-boolean-cast": "error", + "no-regex-spaces": "error", + "no-useless-catch": "error", + "no-useless-constructor": "error", + "no-extra-label": "error", + "no-useless-rename": "error", + "no-void": "error", + "no-with": "error", + "prefer-arrow-callback": "error", + "dot-notation": "error", + "prefer-regex-literals": "error", + + // Biome correctness + "no-const-assign": "error", + "no-constant-condition": "error", + "no-constructor-return": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-obj-calls": "error", + "no-inner-declarations": "error", + "constructor-super": "error", + "no-new-native-nonconstructor": "error", + "no-new-symbol": "error", + "no-use-before-define": "error", + "no-loss-of-precision": "error", + "no-self-assign": "error", + "no-setter-return": "error", + "no-case-declarations": "error", + "no-undef": "error", + "no-unreachable": "error", + "no-this-before-super": "error", + "no-unsafe-finally": "error", + "no-unsafe-optional-chaining": "error", + "no-unused-labels": "error", + "no-unused-private-class-members": "error", + "no-unused-vars": "error", + "no-array-constructor": "error", + "use-isnan": "error", + "for-direction": "error", + "require-yield": "error", + + // Biome security + "no-eval": "error", + + // Biome style + "prefer-rest-params": "error", + "no-sequences": "error", + "no-param-reassign": "error", + "no-var": "error", + "prefer-const": "error", + "no-lonely-if": "error", + "default-param-last": "error", + "prefer-exponentiation-operator": "error", + "prefer-numeric-literals": "error", + "one-var": "error", + "prefer-template": "error", + + // Biome suspicious + "no-async-promise-executor": "error", + "no-cond-assign": "error", + "no-ex-assign": "error", + "no-class-assign": "error", + "no-compare-neg-zero": "error", + "no-labels": "error", + "no-control-regex": "error", + "no-debugger": "error", + eqeqeq: "error", + "no-duplicate-case": "error", + "no-dupe-class-members": "error", + "no-dupe-keys": "error", + "no-dupe-args": "error", + "no-empty": "error", + "no-empty-static-block": "error", + "no-empty-static-block": "error", + "no-empty-function": "error", + "no-fallthrough": "error", + "no-func-assign": "error", + "no-global-assign": "error", + "no-import-assign": "error", + "no-label-var": "error", + "no-misleading-character-class": "error", + "no-prototype-builtins": "error", + "no-redeclare": "error", + "no-self-compare": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", + "no-unsafe-negation": "error", + "require-await": "error", + "default-case-last": "error", + "getter-return": "error", + "valid-typeof": "error", + }, + }, +]; diff --git a/benchmark/package-lock.json b/benchmark/package-lock.json deleted file mode 100644 index b379b48f5e14..000000000000 --- a/benchmark/package-lock.json +++ /dev/null @@ -1,3157 +0,0 @@ -{ - "name": "@biomejs/benchmark", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@biomejs/benchmark", - "version": "1.0.0", - "license": "MIT OR Apache-2.0", - "devDependencies": { - "@mixer/parallel-prettier": "2.0.3", - "dprint": "0.47.2", - "eslint": "9.8.0", - "prettier": "3.3.3" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@dprint/darwin-arm64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.47.2.tgz", - "integrity": "sha512-mVPFBJsXxGDKHHCAY8wbqOyS4028g1bN15H9tivCnPAjwaZhkUimZHXWejXADjhGn+Xm2SlakugY9PY/68pH3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@dprint/darwin-x64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.47.2.tgz", - "integrity": "sha512-T7wzlc+rBV+6BRRiBjoqoy5Hj4TR2Nv2p2s9+ycyPGs10Kj/JXOWD8dnEHeBgUr2r4qe/ZdcxmsFQ5Hf2n0WuA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@dprint/linux-arm64-glibc": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.47.2.tgz", - "integrity": "sha512-B0m1vT5LdVtrNOVdkqpLPrSxuCD+l5bTIgRzPaDoIB1ChWQkler9IlX8C+RStpujjPj6SYvwo5vTzjQSvRdQkA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-arm64-musl": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.47.2.tgz", - "integrity": "sha512-zID6wZZqpg2/Q2Us+ERQkbhLwlW3p3xaeEr00MPf49bpydmEjMiPuSjWPkNv+slQSIyIsVovOxF4lbNZjsdtvw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-x64-glibc": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.47.2.tgz", - "integrity": "sha512-rB3WXMdINnRd33DItIp7mObS7dzHW90ZzeJSsoKJLPp+Z7wXjjb27UUowfqVI4baa/1pd7sdbX54DPohMtfu/A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-x64-musl": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.47.2.tgz", - "integrity": "sha512-E0+TNbzYdTXJ/jCVjUctVxkda/faw++aDQLfyWGcmdMJnbM7NZz+W4fUpDXzMPsjy+zTWxXcPK7/q2DZz2gnbg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/win32-arm64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-arm64/-/win32-arm64-0.47.2.tgz", - "integrity": "sha512-K1EieTCFjfOCmyIhw9zFSduE6qVCNHEveupqZEfbSkVGw5T9MJQ1I9+n7MDb3RIDYEUk0enJ58/w82q8oDKCyA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@dprint/win32-x64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.47.2.tgz", - "integrity": "sha512-LhizWr8VrhHvq4ump8HwOERyFmdLiE8C6A42QSntGXzKdaa2nEOq20x/o56ZIiDcesiV+1TmosMKimPcOZHa+Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", - "dev": true, - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@mixer/parallel-prettier": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@mixer/parallel-prettier/-/parallel-prettier-2.0.3.tgz", - "integrity": "sha512-42ImvDusmxjpQLHEmZrljV/+L9ynfmaTe5ooLMTTLyELulUJtJW8vBXCadQdodfZ5wjr2Sg3YGIzWE0rnBsfDg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "commander": "^7.0.0", - "glob-stream": "^7.0.0", - "ignore": "^5.1.8", - "ora": "^5.3.0", - "prettier": "^2.0.4", - "rxjs": "^6.6.3" - }, - "bin": { - "pprettier": "dist/index.js" - }, - "peerDependencies": { - "prettier": "^2.0.0" - } - }, - "node_modules/@mixer/parallel-prettier/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dprint": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.47.2.tgz", - "integrity": "sha512-geUcVIIrmLaY+YtuOl4gD7J/QCjsXZa5gUqre9sO6cgH0X/Fa9heBN3l/AWVII6rKPw45ATuCSDWz1pyO+HkPQ==", - "dev": true, - "hasInstallScript": true, - "bin": { - "dprint": "bin.js" - }, - "optionalDependencies": { - "@dprint/darwin-arm64": "0.47.2", - "@dprint/darwin-x64": "0.47.2", - "@dprint/linux-arm64-glibc": "0.47.2", - "@dprint/linux-arm64-musl": "0.47.2", - "@dprint/linux-x64-glibc": "0.47.2", - "@dprint/linux-x64-musl": "0.47.2", - "@dprint/win32-arm64": "0.47.2", - "@dprint/win32-x64": "0.47.2" - } - }, - "node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", - "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.8.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "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" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "dev": true, - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-7.0.0.tgz", - "integrity": "sha512-evR4kvr6s0Yo5t4CD4H171n4T8XcnPFznvsbeN8K9FPzc0Q0wYqcOWyGtck2qcvJSLXKnU6DnDyfmbDDabYvRQ==", - "dev": true, - "dependencies": { - "extend": "^3.0.2", - "glob": "^7.2.0", - "glob-parent": "^6.0.2", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.1", - "pumpify": "^2.0.1", - "readable-stream": "^3.6.0", - "remove-trailing-separator": "^1.1.0", - "to-absolute-glob": "^2.0.2", - "unique-stream": "^2.3.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/ordered-read-streams/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "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" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "dev": true, - "dependencies": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "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" - } - }, - "node_modules/to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@dprint/darwin-arm64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.47.2.tgz", - "integrity": "sha512-mVPFBJsXxGDKHHCAY8wbqOyS4028g1bN15H9tivCnPAjwaZhkUimZHXWejXADjhGn+Xm2SlakugY9PY/68pH3Q==", - "dev": true, - "optional": true - }, - "@dprint/darwin-x64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.47.2.tgz", - "integrity": "sha512-T7wzlc+rBV+6BRRiBjoqoy5Hj4TR2Nv2p2s9+ycyPGs10Kj/JXOWD8dnEHeBgUr2r4qe/ZdcxmsFQ5Hf2n0WuA==", - "dev": true, - "optional": true - }, - "@dprint/linux-arm64-glibc": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.47.2.tgz", - "integrity": "sha512-B0m1vT5LdVtrNOVdkqpLPrSxuCD+l5bTIgRzPaDoIB1ChWQkler9IlX8C+RStpujjPj6SYvwo5vTzjQSvRdQkA==", - "dev": true, - "optional": true - }, - "@dprint/linux-arm64-musl": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.47.2.tgz", - "integrity": "sha512-zID6wZZqpg2/Q2Us+ERQkbhLwlW3p3xaeEr00MPf49bpydmEjMiPuSjWPkNv+slQSIyIsVovOxF4lbNZjsdtvw==", - "dev": true, - "optional": true - }, - "@dprint/linux-x64-glibc": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.47.2.tgz", - "integrity": "sha512-rB3WXMdINnRd33DItIp7mObS7dzHW90ZzeJSsoKJLPp+Z7wXjjb27UUowfqVI4baa/1pd7sdbX54DPohMtfu/A==", - "dev": true, - "optional": true - }, - "@dprint/linux-x64-musl": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.47.2.tgz", - "integrity": "sha512-E0+TNbzYdTXJ/jCVjUctVxkda/faw++aDQLfyWGcmdMJnbM7NZz+W4fUpDXzMPsjy+zTWxXcPK7/q2DZz2gnbg==", - "dev": true, - "optional": true - }, - "@dprint/win32-arm64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-arm64/-/win32-arm64-0.47.2.tgz", - "integrity": "sha512-K1EieTCFjfOCmyIhw9zFSduE6qVCNHEveupqZEfbSkVGw5T9MJQ1I9+n7MDb3RIDYEUk0enJ58/w82q8oDKCyA==", - "dev": true, - "optional": true - }, - "@dprint/win32-x64": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.47.2.tgz", - "integrity": "sha512-LhizWr8VrhHvq4ump8HwOERyFmdLiE8C6A42QSntGXzKdaa2nEOq20x/o56ZIiDcesiV+1TmosMKimPcOZHa+Q==", - "dev": true, - "optional": true - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true - }, - "@eslint/config-array": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", - "dev": true, - "requires": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - } - }, - "@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.8.0.tgz", - "integrity": "sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==", - "dev": true - }, - "@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "dev": true - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", - "dev": true - }, - "@mixer/parallel-prettier": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@mixer/parallel-prettier/-/parallel-prettier-2.0.3.tgz", - "integrity": "sha512-42ImvDusmxjpQLHEmZrljV/+L9ynfmaTe5ooLMTTLyELulUJtJW8vBXCadQdodfZ5wjr2Sg3YGIzWE0rnBsfDg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "commander": "^7.0.0", - "glob-stream": "^7.0.0", - "ignore": "^5.1.8", - "ora": "^5.3.0", - "prettier": "^2.0.4", - "rxjs": "^6.6.3" - }, - "dependencies": { - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", - "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", - "dev": true - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "dprint": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.47.2.tgz", - "integrity": "sha512-geUcVIIrmLaY+YtuOl4gD7J/QCjsXZa5gUqre9sO6cgH0X/Fa9heBN3l/AWVII6rKPw45ATuCSDWz1pyO+HkPQ==", - "dev": true, - "requires": { - "@dprint/darwin-arm64": "0.47.2", - "@dprint/darwin-x64": "0.47.2", - "@dprint/linux-arm64-glibc": "0.47.2", - "@dprint/linux-arm64-musl": "0.47.2", - "@dprint/linux-x64-glibc": "0.47.2", - "@dprint/linux-x64-musl": "0.47.2", - "@dprint/win32-arm64": "0.47.2", - "@dprint/win32-x64": "0.47.2" - } - }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "9.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.8.0.tgz", - "integrity": "sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.17.1", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.8.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "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" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "dev": true, - "requires": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true - } - } - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - } - }, - "flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-7.0.0.tgz", - "integrity": "sha512-evR4kvr6s0Yo5t4CD4H171n4T8XcnPFznvsbeN8K9FPzc0Q0wYqcOWyGtck2qcvJSLXKnU6DnDyfmbDDabYvRQ==", - "dev": true, - "requires": { - "extend": "^3.0.2", - "glob": "^7.2.0", - "glob-parent": "^6.0.2", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.1", - "pumpify": "^2.0.1", - "readable-stream": "^3.6.0", - "remove-trailing-separator": "^1.1.0", - "to-absolute-glob": "^2.0.2", - "unique-stream": "^2.3.1" - } - }, - "globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "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" - } - } - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "dev": true, - "requires": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "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" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", - "dev": true - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/benchmark/package.json b/benchmark/package.json index 70e1b15ad2d5..f51fe2f43833 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -1,16 +1,19 @@ { - "name": "@biomejs/benchmark", - "version": "1.0.0", - "description": "", - "private": true, - "main": "run.js", - "author": "Biome Developers and Contributors", - "license": "MIT OR Apache-2.0", - "type": "module", - "devDependencies": { - "@mixer/parallel-prettier": "2.0.3", - "dprint": "0.47.2", - "eslint": "9.8.0", - "prettier": "3.3.3" - } + "name": "@biomejs/benchmark", + "version": "1.0.0", + "description": "", + "private": true, + "main": "run.js", + "author": "Biome Developers and Contributors", + "license": "MIT OR Apache-2.0", + "type": "module", + "engines": { + "node": ">20.0.0" + }, + "devDependencies": { + "@typescript-eslint/eslint-plugin": "8.3.0", + "dprint": "0.47.2", + "eslint": "9.9.1", + "prettier": "3.3.3" + } } diff --git a/benchmark/run.js b/benchmark/run.js deleted file mode 100644 index 98459b649bfe..000000000000 --- a/benchmark/run.js +++ /dev/null @@ -1,278 +0,0 @@ -import * as fs from "node:fs"; -import { execSync } from "node:child_process"; -import * as path from "node:path"; -import * as os from "node:os"; - -const TMP_DIRECTORY = path.resolve("./target"); - -function buildBiome() { - console.log("Building Biome..."); - - execSync("cargo build --bin biome --release", { - stdio: "inherit", - }); - - return path.resolve("../target/release/biome"); -} - -const BENCHMARKS = { - formatter: { - webpack: { - repository: "https://github.com/webpack/webpack.git", - sourceDirectories: { - lib: ["js"], - examples: ["js"], - declarations: ["ts"], - benchmark: ["js"], - }, - }, - prettier: { - repository: "https://github.com/prettier/prettier.git", - sourceDirectories: { - src: ["js"], - scripts: ["js"], - }, - }, - }, - linter: { - eslint: { - repository: "https://github.com/eslint/eslint.git", - sourceDirectories: [ - "lib", - "messages", - "tests/lib", - "tests/performance", - "tools", - ], - }, - webpack: { - repository: "https://github.com/webpack/webpack.git", - sourceDirectories: ["lib"], - }, - }, -}; - -function getDirsToClone(sourceDirs) { - if (typeof sourceDirs !== "object" || sourceDirs === null) { - return; - } - - if (Array.isArray(sourceDirs)) { - return sourceDirs; - } - - return Object.keys(sourceDirs); -} - -function benchmarkFormatter(biome) { - console.log(""); - console.log("Benchmark formatter..."); - console.log("―".repeat(80)); - console.log(""); - - // Run Dprint once to run the installer - execSync("npx dprint --version"); - - for (const [name, configuration] of Object.entries(BENCHMARKS.formatter)) { - console.log(`[${name}]`); - - const projectDirectory = cloneProject( - name, - configuration.repository, - getDirsToClone(configuration.sourceDirectories), - ); - - const prettierPaths = Object.entries(configuration.sourceDirectories) - .flatMap(([directory, extensions]) => { - return extensions.map( - (extension) => `'${path.join(directory, `**/*.${extension}`)}'`, - ); - }) - .join(" "); - - const prettierCommand = `node '${resolvePrettier()}' ${prettierPaths} --write --loglevel=error`; - const parallelPrettierCommand = `node '${resolveParallelPrettier()}' ${prettierPaths} --write --concurrency ${ - os.cpus().length - }`; - - const dprintCommand = `${resolveDprint()} fmt --incremental=false --config '${import.meta.resolve( - "./dprint.json", - )}' ${Object.keys(configuration.sourceDirectories) - .map((path) => `'${path}/**/*'`) - .join(" ")}`; - - const biomeCommand = `${biome} format --max-diagnostics=0 ${Object.keys( - configuration.sourceDirectories, - ) - .map((path) => `'${path}'`) - .join(" ")} --write`; - - const biomeSingleCoreCommand = withEnvVariable( - "RAYON_NUM_THREADS", - "1", - biomeCommand, - ); - - // Run 2 warmups to make sure the files are formatted correctly - const hyperfineCommand = `hyperfine --show-output -w 2 -n Prettier "${prettierCommand}" -n "Parallel-Prettier" "${parallelPrettierCommand}" -n dprint "${dprintCommand}" -n Biome "${biomeCommand}" --shell=${shellOption()} -n "Biome (1 thread)" "${biomeSingleCoreCommand}"`; - console.log(hyperfineCommand); - - execSync(hyperfineCommand, { - cwd: projectDirectory, - stdio: "inherit", - }); - } -} - -function resolvePrettier() { - return path.resolve("node_modules/prettier/standalone.js"); -} - -function resolveParallelPrettier() { - return path.resolve("node_modules/@mixer/parallel-prettier/dist/index.js"); -} - -function resolveDprint() { - return path.resolve("node_modules/dprint/dprint"); -} - -function benchmarkLinter(biome) { - console.log(""); - console.log("Benchmark linter..."); - console.log("―".repeat(80)); - console.log(""); - - for (const [name, configuration] of Object.entries(BENCHMARKS.linter)) { - console.log(`[${name}]`); - - const projectDirectory = cloneProject( - name, - configuration.repository, - getDirsToClone(configuration.sourceDirectories), - ); - - deleteFile(path.join(projectDirectory, ".eslintignore")); - deleteFile(path.join(projectDirectory, "/eslintrc.js")); - - // Override eslint config - const eslintConfig = fs.readFileSync("./bench.eslint.config.js"); - fs.writeFileSync( - path.join(projectDirectory, "eslint.config.js"), - eslintConfig, - ); - - const biomeConfig = fs.readFileSync("./bench.biome.json"); - fs.writeFileSync(path.join(projectDirectory, "biome.json"), biomeConfig); - - const eslintPaths = configuration.sourceDirectories - .map((directory) => `'${directory}/**'`) - .join(" "); - - const eslintCommand = `node '${resolveESlint()}' --no-ignore ${eslintPaths}`; - - const biomePaths = configuration.sourceDirectories - .map((directory) => `'${directory}'`) - .join(" "); - - // Don't compute the code frames for pulled diagnostics. ESLint doesn't do so as well. - const biomeCommand = `${biome} check --max-diagnostics=0 ${biomePaths}`; - - const biomeSingleCoreCommand = withEnvVariable( - "RAYON_NUM_THREADS", - "1", - biomeCommand, - ); - - // Run 2 warmups to make sure the files are formatted correctly - const hyperfineCommand = `hyperfine -i -w 2 -n ESLint "${eslintCommand}" -n Biome "${biomeCommand}" --shell=${shellOption()} -n "Biome (1 thread)" "${biomeSingleCoreCommand}"`; - console.log(hyperfineCommand); - - execSync(hyperfineCommand, { - cwd: projectDirectory, - stdio: "inherit", - }); - } -} - -function resolveESlint() { - return path.resolve("node_modules/eslint/bin/eslint.js"); -} - -function shellOption() { - switch (process.platform) { - case "win32": - // Use Powershell so that it is possible to set an environment variable for a single command (ugh!) - return "powershell"; - default: - return "default"; - } -} - -function withEnvVariable(name, value, command) { - switch (process.platform) { - case "win32": { - return `$Env:${name}=${value}; ${command}`; - } - default: - return `${name}=\"${value}\" ${command}`; - } -} - -function withDirectory(cwd) { - return { - run(command, options) { - execSync(command, { - cwd, - ...options, - }); - }, - }; -} - -function deleteFile(path) { - if (fs.existsSync(path)) { - fs.rmSync(path); - } -} - -function cloneProject(name, repository, dirs = []) { - const projectDirectory = path.join(TMP_DIRECTORY, name); - - const inProjectDirectory = withDirectory(projectDirectory); - - if (fs.existsSync(projectDirectory)) { - console.log(`Updating git repository in directory ${projectDirectory}`); - inProjectDirectory.run("git reset --hard @{u}"); - inProjectDirectory.run("git clean -df"); - inProjectDirectory.run("git pull --depth=1 --ff-only"); - } else { - console.log("Clone project..."); - - withDirectory(TMP_DIRECTORY).run( - `git clone ${dirs.length > 0 ? "--sparse" : ""} --depth=1 ${repository}`, - { - stdio: "inherit", - }, - ); - } - - if (dirs.length > 0) { - console.log( - `Adding directories ${dirs.join()} to sparse checkout in ${projectDirectory}`, - ); - inProjectDirectory.run(`git sparse-checkout add ${dirs.join(" ")}`); - } - - return projectDirectory; -} - -function run() { - fs.mkdirSync("target", { recursive: true }); - - const biome = buildBiome(); - - benchmarkFormatter(biome); - benchmarkLinter(biome); -} - -run(); diff --git a/benchmark/ts-biome.json b/benchmark/ts-biome.json new file mode 100644 index 000000000000..5570e0501bef --- /dev/null +++ b/benchmark/ts-biome.json @@ -0,0 +1,116 @@ +{ + "linter": { + "rules": { + "recommended": false, + "complexity": { + "noExtraBooleanCast": "error", + "noMultipleSpacesInRegularExpressionLiterals": "error", + "noStaticOnlyClass": "error", + "noUselessCatch": "error", + "noUselessConstructor": "error", + "noUselessEmptyExport": "error", + "noUselessLabel": "error", + "noUselessRename": "error", + "noUselessTypeConstraint": "error", + "noVoid": "error", + "noWith": "error", + "useArrowFunction": "error", + "useRegexLiterals": "error" + }, + "correctness": { + "noConstAssign": "error", + "noConstantCondition": "error", + "noConstructorReturn": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInnerDeclarations": "error", + "noInvalidConstructorSuper": "error", + "noInvalidNewBuiltin": "error", + "noInvalidUseBeforeDeclaration": "error", + "noNewSymbol": "error", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noSwitchDeclarations": "error", + "noUndeclaredVariables": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedLabels": "error", + "noUnusedPrivateClassMembers": "error", + "noUnusedVariables": "error", + "useArrayLiterals": "error", + "useIsNan": "error", + "useValidForDirection": "error", + "useYield": "error" + }, + "security": { + "noGlobalEval": "error" + }, + "style": { + "noArguments": "error", + "noCommaOperator": "error", + "noInferrableTypes": "error", + "noNamespace": "error", + "noNonNullAssertion": "error", + "noParameterAssign": "error", + "noParameterProperties": "error", + "noVar": "error", + "useAsConstAssertion": "error", + "useConst": "error", + "useCollapsedElseIf": "error", + "useConsistentArrayType": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useExponentiationOperator": "error", + "useForOf": "error", + "useLiteralEnumMembers": "error", + "useNumericLiterals": "error", + "useShorthandFunctionType": "error", + "useSingleVarDeclarator": "error", + "useTemplate": "error" + }, + "suspicious": { + "noAsyncPromiseExecutor": "error", + "noAssignInExpressions": "error", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCompareNegZero": "error", + "noConfusingLabels": "error", + "noControlCharactersInRegex": "error", + "noDebugger": "error", + "noDoubleEquals": "error", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyBlockStatements": "error", + "noEmptyInterface": "error", + "noExplicitAny": "error", + "noExtraNonNullAssertion": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noImportAssign": "error", + "noLabelVar": "error", + "noMisleadingCharacterClass": "error", + "noMisleadingInstantiator": "error", + "noPrototypeBuiltins": "error", + "noRedeclare": "error", + "noSelfCompare": "error", + "noShadowRestrictedNames": "error", + "noSparseArray": "error", + "noUnsafeDeclarationMerging": "error", + "noUnsafeNegation": "error", + "useAwait": "error", + "useDefaultSwitchClauseLast": "error", + "useGetterReturn": "error", + "useNamespaceKeyword": "error", + "useValidTypeof": "error" + } + } + } +} diff --git a/benchmark/ts-eslint.config.js b/benchmark/ts-eslint.config.js new file mode 100644 index 000000000000..a4077a09b1da --- /dev/null +++ b/benchmark/ts-eslint.config.js @@ -0,0 +1,147 @@ +import tsPlugin from "@typescript-eslint/eslint-plugin"; +import parser from "@typescript-eslint/parser"; + +export default [ + { + files: ["**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"], + languageOptions: { + parser, + parserOptions: { + ecmaFeatures: { modules: true }, + ecmaVersion: "latest", + project: "../../tsconfig.json", + }, + }, + plugins: { + "@typescript-eslint": tsPlugin, + }, + rules: { + // Biome complexity + // deprecated rule + //"@typescript-eslint/ban-types": "error", + "no-extra-boolean-cast": "error", + "no-regex-spaces": "error", + "@typescript-eslint/no-extraneous-class": "error", + "no-useless-catch": "error", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-useless-empty-export": "error", + "no-extra-label": "error", + "no-useless-rename": "error", + "@typescript-eslint/no-unnecessary-type-constraint": "error", + "no-void": "error", + "no-with": "error", + "prefer-arrow-callback": "error", + // disable type rules + //"@typescript-eslint/dot-notation": "error", + //"@typescript-eslint/prefer-optional-chain": "error", + "prefer-regex-literals": "error", + + // Biome correctness + "no-const-assign": "error", + "no-constant-condition": "error", + "no-constructor-return": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-obj-calls": "error", + "no-inner-declarations": "error", + "constructor-super": "error", + "no-new-native-nonconstructor": "error", + "no-new-symbol": "error", + "@typescript-eslint/no-use-before-define": "error", + "no-loss-of-precision": "error", + "no-self-assign": "error", + "no-setter-return": "error", + "no-case-declarations": "error", + "no-undef": "error", + "no-unreachable": "error", + "no-this-before-super": "error", + "no-unsafe-finally": "error", + "no-unsafe-optional-chaining": "error", + "no-unused-labels": "error", + "no-unused-private-class-members": "error", + "no-unused-vars": "error", + "no-array-constructor": "error", + "use-isnan": "error", + "for-direction": "error", + "require-yield": "error", + + // Biome security + "no-eval": "error", + + // Biome style + "prefer-rest-params": "error", + "no-sequences": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "no-param-reassign": "error", + "@typescript-eslint/parameter-properties": [ + "error", + { prefer: "class-property" }, + ], + "no-var": "error", + "@typescript-eslint/prefer-as-const": "error", + "prefer-const": "error", + "no-lonely-if": "error", + "@typescript-eslint/array-type": "error", + "default-param-last": "error", + "@typescript-eslint/prefer-enum-initializers": "error", + "prefer-exponentiation-operator": "error", + // disable type rule + //"@typescript-eslint/consistent-type-exports": "error", + "@typescript-eslint/prefer-for-of": "error", + // disable type rule + //"@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/prefer-literal-enum-member": "error", + // disable type rule + //"@typescript-eslint/naming-convention": "error", + "prefer-numeric-literals": "error", + "@typescript-eslint/prefer-function-type": "error", + "one-var": "error", + "prefer-template": "error", + + // Biome suspicious + "no-async-promise-executor": "error", + "no-cond-assign": "error", + "no-ex-assign": "error", + "no-class-assign": "error", + "no-compare-neg-zero": "error", + "no-labels": "error", + "no-control-regex": "error", + "no-debugger": "error", + eqeqeq: "error", + "no-duplicate-case": "error", + "@typescript-eslint/no-dupe-class-members": "error", + "no-dupe-keys": "error", + "no-dupe-args": "error", + "no-empty": "error", + "no-empty-static-block": "error", + "no-empty-static-block": "error", + "@typescript-eslint/no-empty-function": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "no-fallthrough": "error", + "no-func-assign": "error", + "no-global-assign": "error", + "no-import-assign": "error", + "no-label-var": "error", + "no-misleading-character-class": "error", + "@typescript-eslint/no-misused-new": "error", + "no-prototype-builtins": "error", + "no-redeclare": "error", + "no-self-compare": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", + "@typescript-eslint/no-unsafe-declaration-merging": "error", + "no-unsafe-negation": "error", + "require-await": "error", + // disable type rule + //"@typescript-eslint/require-await": "error", + "default-case-last": "error", + "getter-return": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "valid-typeof": "error", + }, + }, +]; diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json new file mode 100644 index 000000000000..e80c898fd4ce --- /dev/null +++ b/benchmark/tsconfig.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "compilerOptions": { + "lib": [ + "ES2021" + ], + "module": "Node16", + "target": "ES2021", + + "noEmit": true, + + "types": [], + + "esModuleInterop": true, + "isolatedModules": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "verbatimModuleSyntax": true, + + "allowUnreachableCode": false, + "exactOptionalPropertyTypes": true, + "noFallthroughCasesInSwitch": false, + "noImplicitOverride": true, + "noImplicitReturns": true, + "strict": true + } +} diff --git a/biome.json b/biome.json index ad2d7cc51c0f..75c216333cbe 100644 --- a/biome.json +++ b/biome.json @@ -27,11 +27,13 @@ "**/__snapshots__", "**/undefined/**", "_fonts/**", - "packages/@biomejs/wasm-*" + "packages/@biomejs/wasm-*", + "benchmark/target/**" ], "include": [ "packages/@biomejs/**", - "packages/tailwindcss-config-analyzer" + "packages/tailwindcss-config-analyzer/**", + "benchmark/**" ] }, "formatter": { diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index f4cb958db28c..416db04df981 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -47,12 +47,12 @@ pub(crate) mod version; #[bpaf(options, version(VERSION))] /// Biome official CLI. Use it to check the health of your project or run it to check single files. pub enum BiomeCommand { - /// Shows the Biome version information and quit + /// Shows the Biome version information and quit. #[bpaf(command)] Version(#[bpaf(external(cli_options), hide_usage)] CliOptions), #[bpaf(command)] - /// Prints information for debugging + /// Prints information for debugging. Rage( #[bpaf(external(cli_options), hide_usage)] CliOptions, /// Prints the Biome daemon server logs @@ -65,7 +65,7 @@ pub enum BiomeCommand { #[bpaf(long("linter"), switch)] bool, ), - /// Start the Biome daemon server process + /// Starts the Biome daemon server process. #[bpaf(command)] Start { /// Allows to change the prefix applied to the file name of the logs. @@ -94,7 +94,7 @@ pub enum BiomeCommand { config_path: Option, }, - /// Stop the Biome daemon server process + /// Stops the Biome daemon server process. #[bpaf(command)] Stop, @@ -368,7 +368,7 @@ pub enum BiomeCommand { #[bpaf(long("jsonc"), switch)] bool, ), - /// Acts as a server for the Language Server Protocol over stdin/stdout + /// Acts as a server for the Language Server Protocol over stdin/stdout. #[bpaf(command("lsp-proxy"))] LspProxy { /// Allows to change the prefix applied to the file name of the logs. @@ -398,7 +398,7 @@ pub enum BiomeCommand { #[bpaf(long("stdio"), hide, hide_usage, switch)] stdio: bool, }, - /// It updates the configuration when there are breaking changes + /// Updates the configuration when there are breaking changes. #[bpaf(command)] Migrate { #[bpaf(external, hide_usage)] @@ -416,8 +416,18 @@ pub enum BiomeCommand { sub_command: Option, }, - /// Searches for Grit patterns across a project. - #[bpaf(command, hide)] // !! Command is hidden until ready for release. + /// [EXPERIMENTAL] Searches for Grit patterns across a project. + /// + /// Note: GritQL escapes code snippets using backticks, but most shells + /// interpret backticks as command invocations. To avoid this, it's best to + /// put single quotes around your Grit queries. + /// + /// ## Example + /// + /// ```shell + /// biome search '`console.log($message)`' # find all `console.log` invocations + /// ``` + #[bpaf(command)] Search { #[bpaf(external, hide_usage)] cli_options: CliOptions, @@ -450,7 +460,7 @@ pub enum BiomeCommand { paths: Vec, }, - /// A command to retrieve the documentation of various aspects of the CLI. + /// Shows documentation of various aspects of the CLI. /// /// ## Examples /// @@ -469,7 +479,7 @@ pub enum BiomeCommand { }, #[bpaf(command)] - /// Clean the logs emitted by the daemon + /// Cleans the logs emitted by the daemon. Clean, #[bpaf(command("__run_server"), hide)] diff --git a/crates/biome_cli/src/diagnostics.rs b/crates/biome_cli/src/diagnostics.rs index a6cec49e0a73..48aa995f8261 100644 --- a/crates/biome_cli/src/diagnostics.rs +++ b/crates/biome_cli/src/diagnostics.rs @@ -56,6 +56,8 @@ pub enum CliDiagnostic { MigrateError(MigrationDiagnostic), /// Emitted during the reporting phase Report(ReportDiagnostic), + /// Emitted when there's an error emitted when using stdin mode + Stdin(StdinDiagnostic), } #[derive(Debug, Diagnostic)] @@ -415,6 +417,10 @@ impl CliDiagnostic { }) } + pub fn stdin() -> Self { + Self::Stdin(StdinDiagnostic::default()) + } + /// Emitted when the server is not running pub fn server_not_running() -> Self { Self::ServerNotRunning(ServerNotRunning) @@ -489,6 +495,14 @@ impl DeprecatedConfigurationFile { } } +#[derive(Debug, Default, Diagnostic)] +#[diagnostic( + severity = Error, + category = "stdin", + message = "The contents aren't fixed. Use the `--fix` flag to fix them." +)] +pub struct StdinDiagnostic {} + #[cfg(test)] mod test { use crate::CliDiagnostic; diff --git a/crates/biome_cli/src/execute/migrate/eslint.rs b/crates/biome_cli/src/execute/migrate/eslint.rs index 9f69addb28dd..255224bcf4ed 100644 --- a/crates/biome_cli/src/execute/migrate/eslint.rs +++ b/crates/biome_cli/src/execute/migrate/eslint.rs @@ -6,6 +6,7 @@ use biome_fs::{FileSystem, OpenOptions}; use biome_json_parser::JsonParserOptions; use biome_service::DynRef; use std::borrow::Cow; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; use crate::diagnostics::MigrationDiagnostic; @@ -154,8 +155,7 @@ fn load_legacy_config_data( path: &Path, console: &mut dyn Console, ) -> Result { - let (deserialized, diagnostics) = match path.extension().and_then(|file_ext| file_ext.to_str()) - { + let (deserialized, diagnostics) = match path.extension().and_then(OsStr::to_str) { None | Some("json") => { let mut file = fs.open_with_options(path, OpenOptions::default().read(true))?; let mut content = String::new(); diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 55d8286778be..de440e186128 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -73,6 +73,16 @@ pub(crate) fn migrate_eslint_any_rule( let rule = group.use_literal_keys.get_or_insert(Default::default()); rule.set_level(rule_severity.into()); } + "@typescript-eslint/explicit-member-accessibility" => { + if !options.include_nursery { + return false; + } + let group = rules.nursery.get_or_insert_with(Default::default); + let rule = group + .use_consistent_member_accessibility + .get_or_insert(Default::default()); + rule.set_level(rule_severity.into()); + } "@typescript-eslint/naming-convention" => { if !options.include_inspired { results.has_inspired_rules = true; diff --git a/crates/biome_cli/src/execute/migrate/eslint_eslint.rs b/crates/biome_cli/src/execute/migrate/eslint_eslint.rs index 5d5e709587b5..9a7a70c24860 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_eslint.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_eslint.rs @@ -494,6 +494,11 @@ impl Deserializable for Rules { result.insert(Rule::TypeScriptArrayType(conf)); } } + "@typescript-eslint/explicit-member-accessibility" => { + if let Some(conf) = RuleConf::deserialize(&value, name, diagnostics) { + result.insert(Rule::TypeScriptExplicitMemberAccessibility(conf)); + } + } "@typescript-eslint/naming-convention" => { if let Some(conf) = RuleConf::deserialize(&value, name, diagnostics) { result.insert(Rule::TypeScriptNamingConvention(conf)); @@ -567,6 +572,9 @@ pub(crate) enum Rule { // Eslint plugins Jsxa11yArioaRoles(RuleConf>), TypeScriptArrayType(RuleConf), + TypeScriptExplicitMemberAccessibility( + RuleConf, + ), TypeScriptNamingConvention(RuleConf>), UnicornFilenameCase(RuleConf), // If you add new variants, don't forget to update [Rules::deserialize]. @@ -578,6 +586,9 @@ impl Rule { Rule::NoRestrictedGlobals(_) => Cow::Borrowed("no-restricted-globals"), Rule::Jsxa11yArioaRoles(_) => Cow::Borrowed("jsx-a11y/aria-role"), Rule::TypeScriptArrayType(_) => Cow::Borrowed("@typescript-eslint/array-type"), + Rule::TypeScriptExplicitMemberAccessibility(_) => { + Cow::Borrowed("@typescript-eslint/explicit-member-accessibility") + } Rule::TypeScriptNamingConvention(_) => { Cow::Borrowed("@typescript-eslint/naming-convention") } diff --git a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs index 01b00db35082..4f3fb09b6a78 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_to_biome.rs @@ -252,6 +252,20 @@ fn migrate_eslint_rule( } } } + eslint_eslint::Rule::TypeScriptExplicitMemberAccessibility(conf) => { + if migrate_eslint_any_rule(rules, &name, conf.severity(), opts, results) { + if let eslint_eslint::RuleConf::Option(severity, rule_options) = conf { + let group = rules.nursery.get_or_insert_with(Default::default); + group.use_consistent_member_accessibility = + Some(biome_config::RuleConfiguration::WithOptions( + biome_config::RuleWithOptions { + level: severity.into(), + options: rule_options.into(), + }, + )); + } + } + } eslint_eslint::Rule::TypeScriptNamingConvention(conf) => { if migrate_eslint_any_rule(rules, &name, conf.severity(), opts, results) { let severity = conf.severity(); diff --git a/crates/biome_cli/src/execute/migrate/eslint_typescript.rs b/crates/biome_cli/src/execute/migrate/eslint_typescript.rs index dd0692078efb..3344d0450cd5 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_typescript.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_typescript.rs @@ -6,6 +6,7 @@ use std::{cmp::Ordering, str::FromStr}; use biome_deserialize::Deserializable; use biome_deserialize_macros::Deserializable; use biome_js_analyze::{ + lint::nursery::use_consistent_member_accessibility, lint::style::{use_consistent_array_type, use_naming_convention}, utils::regex::RestrictedRegex, }; @@ -44,6 +45,38 @@ impl From for use_consistent_array_type::ConsistentArrayType { } } +#[derive(Debug, Default, Deserializable)] +#[deserializable(unknown_fields = "allow")] +pub(crate) struct ExplicitMemberAccessibilityOptions { + accessibility: Option, +} +impl From + for use_consistent_member_accessibility::ConsistentMemberAccessibilityOptions +{ + fn from(value: ExplicitMemberAccessibilityOptions) -> Self { + use_consistent_member_accessibility::ConsistentMemberAccessibilityOptions { + accessibility: value.accessibility.map(|x| x.into()).unwrap_or_default(), + } + } +} +#[derive(Clone, Copy, Debug, Default, Deserializable)] +pub(crate) enum AccessibilityLevel { + #[default] + #[deserializable(rename = "no-public")] + NoPublic, + Explicit, + None, +} +impl From for use_consistent_member_accessibility::Accessibility { + fn from(value: AccessibilityLevel) -> Self { + match value { + AccessibilityLevel::NoPublic => Self::NoPublic, + AccessibilityLevel::Explicit => Self::Explicit, + AccessibilityLevel::None => Self::None, + } + } +} + #[derive(Debug)] pub(crate) struct NamingConventionOptions(Vec); impl NamingConventionOptions { diff --git a/crates/biome_cli/src/execute/migrate/prettier.rs b/crates/biome_cli/src/execute/migrate/prettier.rs index e0739b03dc99..eae4d3231e91 100644 --- a/crates/biome_cli/src/execute/migrate/prettier.rs +++ b/crates/biome_cli/src/execute/migrate/prettier.rs @@ -12,7 +12,7 @@ use biome_fs::{FileSystem, OpenOptions}; use biome_js_formatter::context::{ArrowParentheses, QuoteProperties, Semicolons, TrailingCommas}; use biome_json_parser::JsonParserOptions; use biome_service::DynRef; -use std::path::Path; +use std::{ffi::OsStr, path::Path}; use super::{eslint_eslint::ShorthandVec, node}; @@ -416,8 +416,7 @@ fn load_config( path: &Path, console: &mut dyn Console, ) -> Result { - let (deserialized, diagnostics) = match path.extension().and_then(|file_ext| file_ext.to_str()) - { + let (deserialized, diagnostics) = match path.extension().and_then(OsStr::to_str) { None | Some("json") => { let mut file = fs.open_with_options(path, OpenOptions::default().read(true))?; let mut content = String::new(); diff --git a/crates/biome_cli/src/execute/mod.rs b/crates/biome_cli/src/execute/mod.rs index 2a3611cbf114..61b22930d1ed 100644 --- a/crates/biome_cli/src/execute/mod.rs +++ b/crates/biome_cli/src/execute/mod.rs @@ -186,7 +186,7 @@ pub enum TraversalMode { Search { /// The GritQL pattern to search for. /// - /// Note that the search command (currently) does not support rewrites. + /// Note that the search command does not support rewrites. pattern: PatternId, /// An optional tuple. diff --git a/crates/biome_cli/src/execute/process_file.rs b/crates/biome_cli/src/execute/process_file.rs index 06c98a509a08..a553ef4b010d 100644 --- a/crates/biome_cli/src/execute/process_file.rs +++ b/crates/biome_cli/src/execute/process_file.rs @@ -27,6 +27,8 @@ pub(crate) enum FileStatus { Unchanged, /// While handling the file, something happened Message(Message), + /// A match was found while searching a file + SearchResult(Message), /// File ignored, it should not be count as "handled" Ignored, /// Files that belong to other tools and shouldn't be touched diff --git a/crates/biome_cli/src/execute/process_file/assists.rs b/crates/biome_cli/src/execute/process_file/assists.rs index 9ad57a298e34..6afe2c6cf1fb 100644 --- a/crates/biome_cli/src/execute/process_file/assists.rs +++ b/crates/biome_cli/src/execute/process_file/assists.rs @@ -1,3 +1,5 @@ +use std::ffi::OsStr; + use crate::execute::diagnostics::ResultExt; use crate::execute::process_file::workspace_file::WorkspaceFile; use crate::execute::process_file::{ @@ -38,14 +40,14 @@ pub(crate) fn assists_with_guard<'ctx>( let mut output = fix_result.code; - match workspace_file.as_extension() { - Some("astro") => { + match workspace_file.as_extension().map(OsStr::as_encoded_bytes) { + Some(b"astro") => { output = AstroFileHandler::output(input.as_str(), output.as_str()); } - Some("vue") => { + Some(b"vue") => { output = VueFileHandler::output(input.as_str(), output.as_str()); } - Some("svelte") => { + Some(b"svelte") => { output = SvelteFileHandler::output(input.as_str(), output.as_str()); } _ => {} diff --git a/crates/biome_cli/src/execute/process_file/format.rs b/crates/biome_cli/src/execute/process_file/format.rs index b58596b827f1..306067d56769 100644 --- a/crates/biome_cli/src/execute/process_file/format.rs +++ b/crates/biome_cli/src/execute/process_file/format.rs @@ -7,6 +7,7 @@ use crate::execute::TraversalMode; use biome_analyze::RuleCategoriesBuilder; use biome_diagnostics::{category, Diagnostic, DiagnosticExt, Error, Severity}; use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler}; +use std::ffi::OsStr; use std::path::Path; use std::sync::atomic::Ordering; use tracing::debug; @@ -90,21 +91,21 @@ pub(crate) fn format_with_guard<'ctx>( return Ok(FileStatus::Ignored); } - match workspace_file.as_extension() { - Some("astro") => { + match workspace_file.as_extension().map(OsStr::as_encoded_bytes) { + Some(b"astro") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } output = AstroFileHandler::output(input.as_str(), output.as_str()); } - Some("vue") => { + Some(b"vue") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } output = VueFileHandler::output(input.as_str(), output.as_str()); } - Some("svelte") => { + Some(b"svelte") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } diff --git a/crates/biome_cli/src/execute/process_file/lint.rs b/crates/biome_cli/src/execute/process_file/lint.rs index 6fa4e8c1f06f..b5e4a7db823c 100644 --- a/crates/biome_cli/src/execute/process_file/lint.rs +++ b/crates/biome_cli/src/execute/process_file/lint.rs @@ -6,6 +6,7 @@ use biome_analyze::RuleCategoriesBuilder; use biome_diagnostics::{category, Error}; use biome_rowan::TextSize; use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler}; +use std::ffi::OsStr; use std::path::Path; use std::sync::atomic::Ordering; @@ -53,14 +54,14 @@ pub(crate) fn lint_with_guard<'ctx>( let mut output = fix_result.code; - match workspace_file.as_extension() { - Some("astro") => { + match workspace_file.as_extension().map(OsStr::as_encoded_bytes) { + Some(b"astro") => { output = AstroFileHandler::output(input.as_str(), output.as_str()); } - Some("vue") => { + Some(b"vue") => { output = VueFileHandler::output(input.as_str(), output.as_str()); } - Some("svelte") => { + Some(b"svelte") => { output = SvelteFileHandler::output(input.as_str(), output.as_str()); } _ => {} @@ -93,10 +94,10 @@ pub(crate) fn lint_with_guard<'ctx>( && pull_diagnostics_result.skipped_diagnostics == 0; if !no_diagnostics { - let offset = match workspace_file.as_extension() { - Some("vue") => VueFileHandler::start(input.as_str()), - Some("astro") => AstroFileHandler::start(input.as_str()), - Some("svelte") => SvelteFileHandler::start(input.as_str()), + let offset = match workspace_file.as_extension().map(OsStr::as_encoded_bytes) { + Some(b"vue") => VueFileHandler::start(input.as_str()), + Some(b"astro") => AstroFileHandler::start(input.as_str()), + Some(b"svelte") => SvelteFileHandler::start(input.as_str()), _ => None, }; diff --git a/crates/biome_cli/src/execute/process_file/organize_imports.rs b/crates/biome_cli/src/execute/process_file/organize_imports.rs index 6bdbbbefd84e..eb2bb9902222 100644 --- a/crates/biome_cli/src/execute/process_file/organize_imports.rs +++ b/crates/biome_cli/src/execute/process_file/organize_imports.rs @@ -1,3 +1,5 @@ +use std::ffi::OsStr; + use crate::execute::diagnostics::ResultExt; use crate::execute::process_file::workspace_file::WorkspaceFile; use crate::execute::process_file::{ @@ -24,21 +26,21 @@ pub(crate) fn organize_imports_with_guard<'ctx>( let input = workspace_file.input()?; let mut output = sorted.code; - match workspace_file.as_extension() { - Some("astro") => { + match workspace_file.as_extension().map(OsStr::as_encoded_bytes) { + Some(b"astro") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } output = AstroFileHandler::output(input.as_str(), output.as_str()); } - Some("vue") => { + Some(b"vue") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } output = VueFileHandler::output(input.as_str(), output.as_str()); } - Some("svelte") => { + Some(b"svelte") => { if output.is_empty() { return Ok(FileStatus::Unchanged); } diff --git a/crates/biome_cli/src/execute/process_file/search.rs b/crates/biome_cli/src/execute/process_file/search.rs index fe88dfd2b6c3..bdec8109d569 100644 --- a/crates/biome_cli/src/execute/process_file/search.rs +++ b/crates/biome_cli/src/execute/process_file/search.rs @@ -31,6 +31,7 @@ pub(crate) fn search_with_guard<'ctx>( let input = workspace_file.input()?; let file_name = workspace_file.path.display().to_string(); + let matches_len = result.matches.len(); let search_results = Message::Diagnostics { name: file_name, @@ -42,7 +43,12 @@ pub(crate) fn search_with_guard<'ctx>( .collect(), skipped_diagnostics: 0, }; - Ok(FileStatus::Message(search_results)) + + if matches_len > 0 { + Ok(FileStatus::SearchResult(search_results)) + } else { + Ok(FileStatus::Message(search_results)) + } }, ) } diff --git a/crates/biome_cli/src/execute/process_file/workspace_file.rs b/crates/biome_cli/src/execute/process_file/workspace_file.rs index 6503c64c6baa..8855bd84e06e 100644 --- a/crates/biome_cli/src/execute/process_file/workspace_file.rs +++ b/crates/biome_cli/src/execute/process_file/workspace_file.rs @@ -4,6 +4,7 @@ use biome_diagnostics::{category, Error}; use biome_fs::{BiomePath, File, OpenOptions}; use biome_service::workspace::{FileGuard, OpenFileParams}; use biome_service::{Workspace, WorkspaceError}; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; /// Small wrapper that holds information and operations around the current processed file @@ -59,8 +60,8 @@ impl<'ctx, 'app> WorkspaceFile<'ctx, 'app> { self.guard().get_file_content() } - pub(crate) fn as_extension(&self) -> Option<&str> { - self.path.extension().and_then(|s| s.to_str()) + pub(crate) fn as_extension(&self) -> Option<&OsStr> { + self.path.extension() } /// It updates the workspace file with `new_content` diff --git a/crates/biome_cli/src/execute/std_in.rs b/crates/biome_cli/src/execute/std_in.rs index a47987937689..cf793abea81d 100644 --- a/crates/biome_cli/src/execute/std_in.rs +++ b/crates/biome_cli/src/execute/std_in.rs @@ -1,17 +1,16 @@ //! In here, there are the operations that run via standard input //! -use crate::execute::diagnostics::{ContentDiffAdvice, FormatDiffDiagnostic}; use crate::execute::Execution; use crate::{CliDiagnostic, CliSession, TraversalMode}; use biome_analyze::RuleCategoriesBuilder; use biome_console::{markup, ConsoleExt}; +use biome_diagnostics::Diagnostic; use biome_diagnostics::PrintDiagnostic; -use biome_diagnostics::{Diagnostic, DiagnosticExt, Error}; use biome_fs::BiomePath; use biome_service::file_handlers::{AstroFileHandler, SvelteFileHandler, VueFileHandler}; use biome_service::workspace::{ ChangeFileParams, DropPatternParams, FeaturesBuilder, FixFileParams, FormatFileParams, - OpenFileParams, OrganizeImportsParams, PullDiagnosticsParams, SupportsFeatureParams, + OpenFileParams, OrganizeImportsParams, SupportsFeatureParams, }; use biome_service::WorkspaceError; use std::borrow::Cow; @@ -57,10 +56,10 @@ pub(crate) fn run<'a>( })?; let code = printed.into_code(); - let output = match biome_path.extension_as_str() { - Some("astro") => AstroFileHandler::output(content, code.as_str()), - Some("vue") => VueFileHandler::output(content, code.as_str()), - Some("svelte") => SvelteFileHandler::output(content, code.as_str()), + let output = match biome_path.extension().map(|ext| ext.as_encoded_bytes()) { + Some(b"astro") => AstroFileHandler::output(content, code.as_str()), + Some(b"vue") => VueFileHandler::output(content, code.as_str()), + Some(b"svelte") => SvelteFileHandler::output(content, code.as_str()), _ => code, }; console.append(markup! { @@ -71,11 +70,11 @@ pub(crate) fn run<'a>( {content} }); console.error(markup! { - "The content was not formatted because the formatter is currently disabled." - }) + "The content was not formatted because the formatter is currently disabled." + }); + return Err(CliDiagnostic::stdin()); } } else if mode.is_check() || mode.is_lint() { - let mut diagnostics: Vec = Vec::new(); let mut new_content = Cow::Borrowed(content); workspace.open_file(OpenFileParams { @@ -128,10 +127,10 @@ pub(crate) fn run<'a>( .build(), })?; let code = fix_file_result.code; - let output = match biome_path.extension_as_str() { - Some("astro") => AstroFileHandler::output(&new_content, code.as_str()), - Some("vue") => VueFileHandler::output(&new_content, code.as_str()), - Some("svelte") => SvelteFileHandler::output(&new_content, code.as_str()), + let output = match biome_path.extension().map(|ext| ext.as_encoded_bytes()) { + Some(b"astro") => AstroFileHandler::output(&new_content, code.as_str()), + Some(b"vue") => VueFileHandler::output(&new_content, code.as_str()), + Some(b"svelte") => SvelteFileHandler::output(&new_content, code.as_str()), _ => code, }; if output != new_content { @@ -150,10 +149,10 @@ pub(crate) fn run<'a>( path: biome_path.clone(), })?; let code = result.code; - let output = match biome_path.extension_as_str() { - Some("astro") => AstroFileHandler::output(&new_content, code.as_str()), - Some("vue") => VueFileHandler::output(&new_content, code.as_str()), - Some("svelte") => SvelteFileHandler::output(&new_content, code.as_str()), + let output = match biome_path.extension().map(|ext| ext.as_encoded_bytes()) { + Some(b"astro") => AstroFileHandler::output(&new_content, code.as_str()), + Some(b"vue") => VueFileHandler::output(&new_content, code.as_str()), + Some(b"svelte") => SvelteFileHandler::output(&new_content, code.as_str()), _ => code, }; if output != new_content { @@ -168,57 +167,19 @@ pub(crate) fn run<'a>( } } - if !mode.is_check_apply_unsafe() { - let result = workspace.pull_diagnostics(PullDiagnosticsParams { - categories: RuleCategoriesBuilder::default() - .with_lint() - .with_syntax() - .build(), - path: biome_path.clone(), - max_diagnostics: mode.max_diagnostics.into(), - only, - skip, - })?; - let content = match biome_path.extension_as_str() { - Some("astro") => AstroFileHandler::input(&new_content), - Some("vue") => VueFileHandler::input(&new_content), - Some("svelte") => SvelteFileHandler::input(&new_content), - _ => &new_content, - }; - diagnostics.extend( - result - .diagnostics - .into_iter() - .map(Error::from) - .map(|diag| diag.with_file_source_code(content.to_string())) - .collect::>(), - ); - } - if file_features.supports_format() && mode.is_check() { let printed = workspace.format_file(FormatFileParams { path: biome_path.clone(), })?; let code = printed.into_code(); - let output = match biome_path.extension_as_str() { - Some("astro") => AstroFileHandler::output(&new_content, code.as_str()), - Some("vue") => VueFileHandler::output(&new_content, code.as_str()), - Some("svelte") => SvelteFileHandler::output(&new_content, code.as_str()), + let output = match biome_path.extension().map(|ext| ext.as_encoded_bytes()) { + Some(b"astro") => AstroFileHandler::output(&new_content, code.as_str()), + Some(b"vue") => VueFileHandler::output(&new_content, code.as_str()), + Some(b"svelte") => SvelteFileHandler::output(&new_content, code.as_str()), _ => code, }; - if mode.is_check_apply() || mode.is_check_apply_unsafe() { - if output != new_content { - new_content = Cow::Owned(output); - } - } else { - let diagnostic = FormatDiffDiagnostic { - file_name: biome_path.display().to_string(), - diff: ContentDiffAdvice { - new: output, - old: content.to_string(), - }, - }; - diagnostics.push(Error::from(diagnostic)); + if (mode.is_check_apply() || mode.is_check_apply_unsafe()) && output != new_content { + new_content = Cow::Owned(output); } } @@ -227,6 +188,7 @@ pub(crate) fn run<'a>( console.append(markup! { {original_content} }); + return Err(CliDiagnostic::stdin()); } Cow::Owned(ref new_content) => { console.append(markup! { @@ -234,13 +196,6 @@ pub(crate) fn run<'a>( }); } } - if !diagnostics.is_empty() { - for diag in diagnostics { - console.error(markup! { - {if verbose { PrintDiagnostic::verbose(&diag) } else { PrintDiagnostic::simple(&diag) }} - }) - } - } } else if let TraversalMode::Search { pattern, .. } = mode.traversal_mode() { // Make sure patterns are always cleaned up at the end of execution. let _ = session.app.workspace.drop_pattern(DropPatternParams { diff --git a/crates/biome_cli/src/execute/traverse.rs b/crates/biome_cli/src/execute/traverse.rs index 34855480958a..d4088de088b2 100644 --- a/crates/biome_cli/src/execute/traverse.rs +++ b/crates/biome_cli/src/execute/traverse.rs @@ -78,6 +78,7 @@ pub(crate) fn traverse( let changed = AtomicUsize::new(0); let unchanged = AtomicUsize::new(0); + let matches = AtomicUsize::new(0); let skipped = AtomicUsize::new(0); let fs = &*session.app.fs; @@ -107,6 +108,7 @@ pub(crate) fn traverse( workspace, execution, interner, + matches: &matches, changed: &changed, unchanged: &unchanged, skipped: &skipped, @@ -132,6 +134,7 @@ pub(crate) fn traverse( let warnings = printer.warnings(); let changed = changed.load(Ordering::Relaxed); let unchanged = unchanged.load(Ordering::Relaxed); + let matches = matches.load(Ordering::Relaxed); let skipped = skipped.load(Ordering::Relaxed); let suggested_fixes_skipped = printer.skipped_fixes(); let diagnostics_not_printed = printer.not_printed_diagnostics(); @@ -141,6 +144,7 @@ pub(crate) fn traverse( unchanged, duration, errors, + matches, warnings, skipped, suggested_fixes_skipped, @@ -547,6 +551,8 @@ pub(crate) struct TraversalOptions<'ctx, 'app> { changed: &'ctx AtomicUsize, /// Shared atomic counter storing the number of unchanged files unchanged: &'ctx AtomicUsize, + /// Shared atomic counter storing the number of unchanged files + matches: &'ctx AtomicUsize, /// Shared atomic counter storing the number of skipped files skipped: &'ctx AtomicUsize, /// Channel sending messages to the display thread @@ -568,6 +574,9 @@ impl<'ctx, 'app> TraversalOptions<'ctx, 'app> { pub(crate) fn increment_unchanged(&self) { self.unchanged.fetch_add(1, Ordering::Relaxed); } + pub(crate) fn increment_matches(&self) { + self.matches.fetch_add(1, Ordering::Relaxed); + } /// Send a message to the display thread pub(crate) fn push_message(&self, msg: impl Into) { @@ -691,6 +700,11 @@ fn handle_file(ctx: &TraversalOptions, path: &BiomePath) { Ok(Ok(FileStatus::Unchanged)) => { ctx.increment_unchanged(); } + Ok(Ok(FileStatus::SearchResult(msg))) => { + ctx.increment_unchanged(); + ctx.increment_matches(); + ctx.push_message(msg); + } Ok(Ok(FileStatus::Message(msg))) => { ctx.increment_unchanged(); ctx.push_message(msg); diff --git a/crates/biome_cli/src/reporter/mod.rs b/crates/biome_cli/src/reporter/mod.rs index c864fa7af816..491fa535c787 100644 --- a/crates/biome_cli/src/reporter/mod.rs +++ b/crates/biome_cli/src/reporter/mod.rs @@ -25,6 +25,7 @@ pub struct DiagnosticsPayload { pub struct TraversalSummary { pub changed: usize, pub unchanged: usize, + pub matches: usize, // We skip it during testing because the time isn't predictable #[cfg_attr(debug_assertions, serde(skip))] pub duration: Duration, diff --git a/crates/biome_cli/src/reporter/summary.rs b/crates/biome_cli/src/reporter/summary.rs index f9fb45a02780..3d78b6f1a87c 100644 --- a/crates/biome_cli/src/reporter/summary.rs +++ b/crates/biome_cli/src/reporter/summary.rs @@ -4,7 +4,7 @@ use biome_console::fmt::{Display, Formatter}; use biome_console::{markup, Console, ConsoleExt, HorizontalLine, Padding, SOFT_LINE}; use biome_diagnostics::{Resource, Severity}; use std::cmp::Ordering; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::fmt::Debug; use std::io; @@ -120,8 +120,8 @@ impl<'a> ReporterVisitor for SummaryReporterVisitor<'a> { #[derive(Debug, Default)] struct FileToDiagnostics { - formats: Vec, - organize_imports: Vec, + formats: BTreeSet, + organize_imports: BTreeSet, lints: LintsByCategory, } @@ -132,11 +132,11 @@ impl FileToDiagnostics { } fn insert_format(&mut self, location: &str) { - self.formats.push(location.into()) + self.formats.insert(location.into()); } fn insert_organize_imports(&mut self, location: &str) { - self.organize_imports.push(location.into()) + self.organize_imports.insert(location.into()); } } diff --git a/crates/biome_cli/src/reporter/terminal.rs b/crates/biome_cli/src/reporter/terminal.rs index 95b4237043f0..89f38d79ca38 100644 --- a/crates/biome_cli/src/reporter/terminal.rs +++ b/crates/biome_cli/src/reporter/terminal.rs @@ -234,6 +234,10 @@ impl<'a> fmt::Display for ConsoleTraversalSummary<'a> { fmt.write_markup(markup!("\n""Found "{self.1.warnings}" warnings."))?; } } + + if let TraversalMode::Search { .. } = self.0 { + fmt.write_markup(markup!(" ""Found "{self.1.matches}" matches."))? + }; Ok(()) } } diff --git a/crates/biome_cli/tests/cases/handle_astro_files.rs b/crates/biome_cli/tests/cases/handle_astro_files.rs index d8c0665242b3..714f86ebd0bf 100644 --- a/crates/biome_cli/tests/cases/handle_astro_files.rs +++ b/crates/biome_cli/tests/cases/handle_astro_files.rs @@ -472,7 +472,7 @@ fn lint_stdin_successfully() { Args::from(["lint", "--stdin-file-path", "file.astro"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer @@ -590,7 +590,7 @@ fn check_stdin_successfully() { Args::from(["check", "--stdin-file-path", "file.astro"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer diff --git a/crates/biome_cli/tests/cases/handle_svelte_files.rs b/crates/biome_cli/tests/cases/handle_svelte_files.rs index 92010b62c8d0..3ba2d52fb78f 100644 --- a/crates/biome_cli/tests/cases/handle_svelte_files.rs +++ b/crates/biome_cli/tests/cases/handle_svelte_files.rs @@ -351,7 +351,7 @@ fn lint_stdin_successfully() { Args::from(["lint", "--stdin-file-path", "file.svelte"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer @@ -471,7 +471,7 @@ fn check_stdin_successfully() { Args::from(["check", "--stdin-file-path", "file.svelte"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer diff --git a/crates/biome_cli/tests/cases/handle_vue_files.rs b/crates/biome_cli/tests/cases/handle_vue_files.rs index 076eddc23b0c..da261f14b810 100644 --- a/crates/biome_cli/tests/cases/handle_vue_files.rs +++ b/crates/biome_cli/tests/cases/handle_vue_files.rs @@ -672,7 +672,7 @@ fn lint_stdin_successfully() { Args::from(["lint", "--stdin-file-path", "file.svelte"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer @@ -786,7 +786,7 @@ fn check_stdin_successfully() { Args::from(["check", "--stdin-file-path", "file.vue"].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer diff --git a/crates/biome_cli/tests/cases/overrides_formatter.rs b/crates/biome_cli/tests/cases/overrides_formatter.rs index 789e43cf3816..8cfeb75088bb 100644 --- a/crates/biome_cli/tests/cases/overrides_formatter.rs +++ b/crates/biome_cli/tests/cases/overrides_formatter.rs @@ -303,7 +303,6 @@ fn complex_enable_disable_overrides() { } #[test] -#[ignore = "Enable when we are ready to handle CSS files"] fn does_include_file_with_different_languages() { let mut console = BufferConsole::default(); let mut fs = MemoryFileSystem::default(); diff --git a/crates/biome_cli/tests/cases/protected_files.rs b/crates/biome_cli/tests/cases/protected_files.rs index 2877f18acc72..f14353dde2a0 100644 --- a/crates/biome_cli/tests/cases/protected_files.rs +++ b/crates/biome_cli/tests/cases/protected_files.rs @@ -43,7 +43,7 @@ fn not_process_file_from_stdin_lint() { Args::from([("lint"), ("--stdin-file-path=package.json")].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); assert_cli_snapshot(SnapshotPayload::new( module_path!(), diff --git a/crates/biome_cli/tests/commands/check.rs b/crates/biome_cli/tests/commands/check.rs index 8e054af164a1..cbad904e9c24 100644 --- a/crates/biome_cli/tests/commands/check.rs +++ b/crates/biome_cli/tests/commands/check.rs @@ -2325,7 +2325,7 @@ fn check_stdin_returns_text_if_content_is_not_changed() { ), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer @@ -2346,6 +2346,50 @@ fn check_stdin_returns_text_if_content_is_not_changed() { result, )); } + +#[test] +fn check_stdin_returns_content_when_not_write() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + console.in_buffer.push("let b = 2;".to_string()); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Args::from( + [ + ("check"), + "--organize-imports-enabled=true", + ("--stdin-file-path"), + ("mock.js"), + ] + .as_slice(), + ), + ); + + assert!(result.is_err(), "run_cli returned {result:?}"); + + let message = console + .out_buffer + .first() + .expect("Console should have written a message"); + + let content = markup_to_string(markup! { + {message.content} + }); + + assert_eq!(content, "let b = 2;"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "check_stdin_returns_content_when_not_write", + fs, + console, + result, + )); +} + #[test] fn should_apply_correct_file_source() { let mut fs = MemoryFileSystem::default(); @@ -2588,8 +2632,8 @@ fn check_json_files() { r#"{ "linter": { "rules": { - "nursery": { - "noDuplicateJsonKeys": "error" + "suspicious": { + "noDuplicateObjectKeys": "error" } } } diff --git a/crates/biome_cli/tests/commands/format.rs b/crates/biome_cli/tests/commands/format.rs index 27485b120dcf..86cb66284ba0 100644 --- a/crates/biome_cli/tests/commands/format.rs +++ b/crates/biome_cli/tests/commands/format.rs @@ -1360,7 +1360,7 @@ fn does_not_format_if_disabled() { Args::from([("format"), ("--stdin-file-path"), ("mock.js")].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); let message = console .out_buffer @@ -2642,7 +2642,6 @@ fn should_apply_different_formatting() { }, "css": { "formatter": { - "enabled": true, "lineWidth": 40, "indentWidth": 6 } diff --git a/crates/biome_cli/tests/commands/lint.rs b/crates/biome_cli/tests/commands/lint.rs index 6612b73314b7..2d94067b0a9d 100644 --- a/crates/biome_cli/tests/commands/lint.rs +++ b/crates/biome_cli/tests/commands/lint.rs @@ -2297,7 +2297,7 @@ const = ""; "# Args::from([("lint"), "--write", ("--stdin-file-path"), ("mock.ts")].as_slice()), ); - assert!(result.is_ok(), "run_cli returned {result:?}"); + assert!(result.is_err(), "run_cli returned {result:?}"); assert_cli_snapshot(SnapshotPayload::new( module_path!(), @@ -2596,8 +2596,8 @@ fn check_json_files() { r#"{ "linter": { "rules": { - "nursery": { - "noDuplicateJsonKeys": "error" + "suspicious": { + "noDuplicateObjectKeys": "error" } } } diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap index e3b069feb782..7ae9b81e673c 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_successfully.snap @@ -13,6 +13,17 @@ statement ( ) ; var foo: string = ""; ---
+``` + +# Termination Message + +```block +stdin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × The contents aren't fixed. Use the `--fix` flag to fix them. + + + ``` # Emitted Messages @@ -27,110 +38,3 @@ var foo: string = ""; ---
``` - -```block -file.astro:2:9 lint/complexity/noUselessRename FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Useless rename. - - > 2 │ import {a as a} from 'mod'; - │ ^^^^^^ - 3 │ import { something } from "file.astro"; - 4 │ debugger; - - i Safe fix: Remove the renaming. - - 2 │ import·{a·as·a}·from·'mod'; - │ ----- - -``` - -```block -file.astro:4:1 lint/suspicious/noDebugger FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × This is an unexpected use of the debugger statement. - - 2 │ import {a as a} from 'mod'; - 3 │ import { something } from "file.astro"; - > 4 │ debugger; - │ ^^^^^^^^^ - 5 │ statement ( ) ; - 6 │ var foo: string = ""; - - i Unsafe fix: Remove debugger statement - - 2 2 │ import {a as a} from 'mod'; - 3 3 │ import { something } from "file.astro"; - 4 │ - debugger; - 5 4 │ statement ( ) ; - 6 5 │ var foo: string = ""; - - -``` - -```block -file.astro:6:8 lint/style/noInferrableTypes FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × This type annotation is trivially inferred from its initialization. - - 4 │ debugger; - 5 │ statement ( ) ; - > 6 │ var foo: string = ""; - │ ^^^^^^^^ - 7 │ - - i Safe fix: Remove the type annotation. - - 4 4 │ debugger; - 5 5 │ statement ( ) ; - 6 │ - var·foo:·string·=·""; - 6 │ + var·foo·=·""; - 7 7 │ - - -``` - -```block -file.astro:6:1 lint/style/noVar FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Use let or const instead of var. - - 4 │ debugger; - 5 │ statement ( ) ; - > 6 │ var foo: string = ""; - │ ^^^^^^^^^^^^^^^^^^^^ - 7 │ - - i A variable declared with var is accessible in the whole module. Thus, the variable can be accessed before its initialization and outside the block where it is declared. - - i See MDN web docs for more details. - - i Unsafe fix: Use 'const' instead. - - 4 4 │ debugger; - 5 5 │ statement ( ) ; - 6 │ - var·foo:·string·=·""; - 6 │ + const·foo:·string·=·""; - 7 7 │ - - -``` - -```block -file.astro format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Formatter would have printed the following content: - - 1 1 │ --- - 2 │ - import·{a·as·a}·from·'mod'; - 3 │ - import·{····something·}·from·"file.astro"; - 2 │ + import·{·a·as·a·}·from·"mod"; - 3 │ + import·{·something·}·from·"file.astro"; - 4 4 │ debugger; - 5 │ - statement·(·)·; - 5 │ + statement(); - 6 6 │ var foo: string = ""; - 7 7 │ --- - - -``` diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap index 6a6c4b582bd4..bc3ef7032ebf 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/check_stdin_write_successfully.snap @@ -27,52 +27,3 @@ var foo = ""; ---
``` - -```block -file.astro:4:1 lint/suspicious/noDebugger FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × This is an unexpected use of the debugger statement. - - 2 │ import { something } from "file.astro"; - 3 │ import { a } from "mod"; - > 4 │ debugger; - │ ^^^^^^^^^ - 5 │ statement(); - 6 │ var foo = ""; - - i Unsafe fix: Remove debugger statement - - 2 2 │ import { something } from "file.astro"; - 3 3 │ import { a } from "mod"; - 4 │ - debugger; - 5 4 │ statement(); - 6 5 │ var foo = ""; - - -``` - -```block -file.astro:6:1 lint/style/noVar FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Use let or const instead of var. - - 4 │ debugger; - 5 │ statement(); - > 6 │ var foo = ""; - │ ^^^^^^^^^^^^ - 7 │ - - i A variable declared with var is accessible in the whole module. Thus, the variable can be accessed before its initialization and outside the block where it is declared. - - i See MDN web docs for more details. - - i Unsafe fix: Use 'const' instead. - - 4 4 │ debugger; - 5 5 │ statement(); - 6 │ - var·foo·=·""; - 6 │ + const·foo·=·""; - 7 7 │ - - -``` diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_successfully.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_successfully.snap index e8d37a995706..62ae40e3330f 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_successfully.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_astro_files/lint_stdin_successfully.snap @@ -9,6 +9,17 @@ expression: content import {a as a} from 'mod'; ---
+``` + +# Termination Message + +```block +stdin ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × The contents aren't fixed. Use the `--fix` flag to fix them. + + + ``` # Emitted Messages @@ -19,19 +30,3 @@ import {a as a} from 'mod'; ---
``` - -```block -file.astro:2:9 lint/complexity/noUselessRename FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - × Useless rename. - - > 2 │ import {a as a} from 'mod'; - │ ^^^^^^ - 3 │ - - i Safe fix: Remove the renaming. - - 2 │ import·{a·as·a}·from·'mod'; - │ ----- - -``` diff --git a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_format_files_by_default.snap b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_format_files_by_default.snap index 3802794618b9..397f0a2d3d05 100644 --- a/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_format_files_by_default.snap +++ b/crates/biome_cli/tests/snapshots/main_cases_handle_css_files/should_not_format_files_by_default.snap @@ -11,9 +11,9 @@ html {} # Termination Message ```block -internalError/io ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +format ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × No files were processed in the specified paths. + × Some errors were emitted while running checks. @@ -22,5 +22,19 @@ internalError/io ━━━━━━━━━━━━━━━━━━━━━ # Emitted Messages ```block -Checked 0 files in