├── .c8rc.json ├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── node.js.yml │ └── publish.yml ├── .gitignore ├── .gitmodules ├── .mocharc.js ├── .ncurc ├── .npmignore ├── CHANGELOG.md ├── CMakeLists.txt ├── CMakePresets.json ├── LICENSE ├── README.md ├── SECURITY.md ├── bin └── editorconfig ├── eslint.config.mjs ├── package.json ├── pnpm-lock.yaml ├── src ├── cli.test.ts ├── cli.ts ├── index.test.ts └── index.ts └── tsconfig.json /.c8rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "exclude": [ 3 | "coverage/**", 4 | "**/*.test.*", 5 | ".mocharc.js" 6 | ], 7 | "reporter": [ 8 | "lcov", 9 | "text" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | block_comment_start = /** 13 | block_comment = * 14 | block_comment_end = */ 15 | 16 | [*.md] 17 | indent_size = 4 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml merge=text 2 | shrinkwrap.yaml merge=binary 3 | npm-shrinkwrap.json merge=binary 4 | yarn.lock merge=binary 5 | 6 | bin/* text eol=lf 7 | *.js text eol=lf 8 | *.ts text eol=lf 9 | *.peggy text eol=lf 10 | *.json text eol=lf 11 | *.html text eol=lf 12 | *.css text eol=lf 13 | *.map text eol=lf 14 | *.png binary 15 | *.jpg binary 16 | *.ico binary 17 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | 14 | strategy: 15 | matrix: 16 | node-version: [20, 22, 24] 17 | os: [ubuntu-latest, macos-latest, windows-latest] 18 | 19 | runs-on: ${{ matrix.os }} 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | submodules: true 25 | - name: install corepack 26 | uses: pnpm/action-setup@v4 27 | - name: Use Node.js ${{ matrix.node-version }} 28 | uses: actions/setup-node@v4 29 | with: 30 | node-version: ${{ matrix.node-version }} 31 | cache: pnpm 32 | - name: Install dependencies 33 | run: pnpm install 34 | # Only lint on Linux because of linebreaks. 35 | - name: Check coding standards 36 | if: matrix.node-version == 22 && matrix.os == 'ubuntu-latest' 37 | run: npm run lint 38 | - name: Test 39 | run: npm run ci 40 | # Stay on coveralls instead of codecov, since hildjj doesn't own the 41 | # repo directly, and it's too much work to figure out. 42 | - name: Coveralls Parallel 43 | uses: coverallsapp/github-action@master 44 | with: 45 | github-token: ${{ secrets.github_token }} 46 | flag-name: node-${{ matrix.node-version }} 47 | path-to-lcov: ./coverage/lcov.info 48 | parallel: true 49 | finish: 50 | needs: build 51 | runs-on: ubuntu-latest 52 | steps: 53 | - name: Coveralls Finished 54 | uses: coverallsapp/github-action@master 55 | with: 56 | github-token: ${{ secrets.github_token }} 57 | path-to-lcov: ./coverage/lcov.info 58 | parallel-finished: true 59 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npmjs 2 | on: 3 | release: 4 | types: [published] 5 | workflow_call: 6 | secrets: 7 | NPM_TOKEN: 8 | required: true 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | permissions: 14 | contents: read 15 | id-token: write 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | submodules: true 20 | - name: install corepack 21 | uses: pnpm/action-setup@v4 22 | - uses: actions/setup-node@v4 23 | with: 24 | node-version: 22 25 | registry-url: 'https://registry.npmjs.org' 26 | cache: pnpm 27 | - run: pnpm install 28 | - run: npm run test 29 | - run: npm pkg delete devDependencies scripts packageManager pnpm 30 | - run: npm publish --access public --provenance 31 | env: 32 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | [Tt]ests/ 3 | *.cmake 4 | *.log 5 | *.sln 6 | *.tgz 7 | *.tmp 8 | *.vcxproj* 9 | /CMakeCache.txt 10 | /CMakeFiles/ 11 | coverage/ 12 | CTest* 13 | lib/ 14 | Makefile 15 | node_modules/ 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "tests"] 2 | path = tests 3 | url = https://github.com/editorconfig/editorconfig-core-test.git 4 | ignore = untracked 5 | -------------------------------------------------------------------------------- /.mocharc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | 'spec': 'lib/**/*.test.js', 5 | 'diff': true, 6 | 'full-trace': true, 7 | 'recursive': true, 8 | 'reporter': 'progress', 9 | }; 10 | -------------------------------------------------------------------------------- /.ncurc: -------------------------------------------------------------------------------- 1 | { 2 | "dep": ["prod", "dev", "packageManager"], 3 | "reject": [ 4 | "chai", 5 | "@types/chai" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .c8rc.json 2 | .editorconfig 3 | .eslintrc.js 4 | .gitattributes 5 | .github 6 | .gitmodules 7 | .mocharc.js 8 | .ncurc 9 | .npmignore 10 | .vscode 11 | [Tt]ests/ 12 | *.cmake 13 | *.log 14 | *.log 15 | *.sln 16 | *.test.* 17 | *.tgz 18 | *.tmp 19 | *.vcxproj* 20 | CHANGELOG.md 21 | CMakeCache.txt 22 | CMakeFiles/ 23 | CMakeLists.txt 24 | CMakePresets.json 25 | coverage/ 26 | CTest* 27 | Makefile 28 | SECURITY.md 29 | src/ 30 | tsconfig.json 31 | tslint.json 32 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.0.0 2 | 3 | - **Breaking**: Now requires Node v16+ 4 | - Enable extended globbing from minimatch. This means that some patterns will 5 | work in this version might not work in other editorconfig implementations. 6 | Fixes #84. 7 | - Add `unset` option to API and CLI. When enabled, properties with the value 8 | "unset" will be removed from the returned object. Defaults to false in all 9 | cases, since according to the core team, this is something that the editor 10 | plugin is supposed to do, and the tests reinforce this. An `unset()` 11 | function is now exported if you'd like to call it explicitly. 12 | Fixes #123. 13 | 14 | ## 1.0.3 15 | 16 | - Updated all dependencies, including security fixes for semver 7.3.8 17 | 18 | ## 1.0.2 19 | 20 | - Updated all dependencies, including breaking changes from minimatch and 21 | rimraf. 22 | - Removed @types/minimatch in favor of minimatch's built-in type definitions. 23 | 24 | ## 1.0.1 25 | 26 | - Fixed #111 by updating to latest version of one-ini. Config files that 27 | contained empty comment lines would cause parse failures. 28 | 29 | ## 1.0.0 30 | 31 | - Upgrade dependencies, including moving to modern TS linting with eslint, 32 | using minimap directly, and removing now-unneeded dependencies. 33 | - Moved to @one-ini/wasm as the parser 34 | - Moved to GitHub Actions for CI 35 | - Added automated API testing, with coverage statistics 36 | - Ensured that all tests pass on Windows 37 | - Added an option to receive information about which config files were used to 38 | produce the combined parameters 39 | - Added an option for caching (including negative caching) 40 | - **Breaking**: Now requires Node v14+ 41 | 42 | ## 0.15.3 43 | - Move @types dependencies to dev dependencies. 44 | - Upgrade dependencies. 45 | 46 | ## 0.15.2 47 | - Fix publish. 48 | 49 | ## 0.15.1 50 | - Update dependencies. 51 | 52 | ## 0.15.0 53 | - Convert source code into TypeScript. Generated type definitions are now provided. 54 | - Remove dependency on Bluebird. 55 | - **Breaking**: Node v4 no longer supported. 56 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is used for testing only 2 | 3 | # To perform the test, run `cmake .` at the root of the project tree followed 4 | # by `ctest .` 5 | 6 | cmake_minimum_required(VERSION 3.16.3) 7 | 8 | # Do not check any compiler 9 | project(editorconfig-core-js NONE) 10 | find_program(NODE node DOC "Node.js command") 11 | 12 | enable_testing() 13 | 14 | set(EDITORCONFIG_CMD ${NODE} ${PROJECT_SOURCE_DIR}/bin/editorconfig) 15 | add_subdirectory(tests) 16 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 5, 3 | "configurePresets": [ 4 | { 5 | "name": "default" 6 | } 7 | ], 8 | "testPresets": [ 9 | { 10 | "name": "Test", 11 | "configurePreset": "default", 12 | "configuration": "Release", 13 | "output": { 14 | "shortProgress": true, 15 | "outputOnFailure": true 16 | }, 17 | "filter": { 18 | "exclude": { 19 | "name": "braces_closing_in_beginning" 20 | } 21 | }, 22 | "execution": { 23 | "noTestsAction": "error" 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2012 EditorConfig Team 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the “Software”), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EditorConfig JavaScript Core 2 | 3 | [![Tests](https://github.com/editorconfig/editorconfig-core-js/actions/workflows/node.js.yml/badge.svg)](https://github.com/editorconfig/editorconfig-core-js/actions/workflows/node.js.yml) 4 | [![Coverage Status](https://coveralls.io/repos/github/editorconfig/editorconfig-core-js/badge.svg?branch=master)](https://coveralls.io/github/editorconfig/editorconfig-core-js?branch=master) 5 | 6 | The EditorConfig JavaScript core will provide the same functionality as the 7 | [EditorConfig C Core][] and [EditorConfig Python Core][]. 8 | 9 | ## Installation 10 | 11 | You need [node][] to use this package. 12 | 13 | To install the package locally: 14 | 15 | ```bash 16 | $ npm install editorconfig 17 | ``` 18 | 19 | To install the package system-wide: 20 | 21 | ```bash 22 | $ npm install -g editorconfig 23 | ``` 24 | 25 | ## Usage 26 | 27 | ### Options 28 | 29 | Most of the API takes an `options` object, which has the following defaults: 30 | 31 | ```js 32 | { 33 | config: '.editorconfig', 34 | version: pkg.version, 35 | root: '/', 36 | files: undefined, 37 | cache: undefined, 38 | unset: false, 39 | }; 40 | ``` 41 | 42 |
43 |
config
44 |
The name of the config file to look for in the current and every parent 45 | directory.
46 | 47 |
version
48 |
Which editorconfig spec version to use. Earlier versions had different 49 | defaults.
50 | 51 |
root
52 |
What directory to stop processing in, even if we haven't found a file 53 | containing root=true. Defaults to the root of the filesystem containing 54 | `process.cwd()`.
55 | 56 |
files
57 |
Pass in an empty array, which will be filled with one object for each 58 | config file processed. The objects will have the shape 59 | `{filename: "[DIRECTORY]/.editorconfig", glob: "*"}`
60 | 61 |
cache
62 |
If you are going to process more than one file in the same project, pass 63 | in a cache object. It must have `get(string): object|undefined` and 64 | `set(string, object)` methods, like a JavaScript Map. A long-running 65 | process might want to consider that this cache might grow over time, 66 | and that the config files might change over time. However, we leave any 67 | complexity of that nature to the caller, since there are so many different 68 | approaches that might be taken based on latency, memory, and CPU trade-offs. 69 | Note that some of the objects in the cache will be for files that did not 70 | exist. Those objects will have a `notfound: true` property. All of the 71 | objects will have a `name: string` property that contains the 72 | fully-qualified file name of the config file and a `root: boolean` property 73 | that describes if the config file had a `root=true` at the top. Any other 74 | properties in the objects should be treated as opaque.
75 | 76 |
unset
77 |
If true, after combining all properties, remove all properties whose value 78 | remains as "unset". This is typically left for plugin authors to do, and 79 | the conformance tests assume that this value is always false.
80 |
81 | 82 | ### in Node.js: 83 | 84 | #### parse(filePath[, options]) 85 | 86 | Search for `.editorconfig` files starting from the current directory to the 87 | root directory. Combine all of the sections whose section names match 88 | filePath into a single object. 89 | 90 | Example: 91 | 92 | ```js 93 | const editorconfig = require('editorconfig'); 94 | const path = require('path'); 95 | 96 | const filePath = path.join(__dirname, 'sample.js'); 97 | 98 | (async () => { 99 | console.log(await editorconfig.parse(filePath, {files: []})); 100 | })(); 101 | /* 102 | { 103 | indent_style: 'space', 104 | indent_size: 2, 105 | end_of_line: 'lf', 106 | charset: 'utf-8', 107 | trim_trailing_whitespace: true, 108 | insert_final_newline: true, 109 | tab_width: 2 110 | }; 111 | assert.deepEqual(files, [ 112 | { fileName: '[DIRECTORY]/.editorconfig', glob: '*' }, 113 | { fileName: '[DIRECTORY]/.editorconfig', glob: '*.js' } 114 | ]) 115 | */ 116 | ``` 117 | 118 | #### parseSync(filePath[, options]) 119 | 120 | Synchronous version of `editorconfig.parse()`. 121 | 122 | #### parseBuffer(fileContent) 123 | 124 | The `parse()` function above uses `parseBuffer()` under the hood. If you have 125 | the contents of a config file, and want to see what is being processed for 126 | just that file rather than the full directory hierarchy, this might be useful. 127 | 128 | #### parseString(fileContent) 129 | 130 | This is a thin wrapper around `parseBuffer()` for backward-compatibility. 131 | Prefer `parseBuffer()` to avoid an unnecessary UTF8-to-UTF16-to-UTF8 132 | conversion. Deprecated. 133 | 134 | #### parseFromFiles(filePath, configs[, options]) 135 | 136 | Low-level interface, which exists only for backward-compatibility. Deprecated. 137 | 138 | Example: 139 | 140 | ```js 141 | const editorconfig = require('editorconfig'); 142 | const fs = require('fs'); 143 | const path = require('path'); 144 | 145 | const configPath = path.join(__dirname, '.editorconfig'); 146 | const configs = [ 147 | { 148 | name: configPath, 149 | contents: fs.readFileSync(configPath, 'utf8') 150 | } 151 | ]; 152 | 153 | const filePath = path.join(__dirname, '/sample.js'); 154 | 155 | (async () => { 156 | console.log(await editorconfig.parseFromFiles(filePath, Promise.resolve(configs))) 157 | })(); 158 | /* 159 | { 160 | indent_style: 'space', 161 | indent_size: 2, 162 | end_of_line: 'lf', 163 | charset: 'utf-8', 164 | trim_trailing_whitespace: true, 165 | insert_final_newline: true, 166 | tab_width: 2 167 | }; 168 | */ 169 | ``` 170 | 171 | #### parseFromFilesSync(filePath, configs[, options]) 172 | 173 | Synchronous version of `editorconfig.parseFromFiles()`. Deprecated. 174 | 175 | ### in Command Line 176 | 177 | ```bash 178 | $ ./bin/editorconfig 179 | 180 | Usage: editorconfig [options] 181 | 182 | Arguments: 183 | FILEPATH Files to find configuration for. Can be a hyphen (-) if you 184 | want path(s) to be read from stdin. 185 | 186 | Options: 187 | -v, --version Display version information from the package 188 | -f Specify conf filename other than '.editorconfig' 189 | -b Specify version (used by devs to test compatibility) 190 | --files Output file names that contributed to the configuration, 191 | rather than the configuation itself 192 | -h, --help display help for command 193 | ``` 194 | 195 | Example: 196 | 197 | ```bash 198 | $ ./bin/editorconfig /home/zoidberg/humans/anatomy.md 199 | charset=utf-8 200 | insert_final_newline=true 201 | end_of_line=lf 202 | tab_width=8 203 | trim_trailing_whitespace=sometimes 204 | ``` 205 | 206 | ```bash 207 | $ ./bin/editorconfig --files /home/zoidberg/humans/anatomy.md 208 | /home/zoidberg/.editorconfig [*] 209 | /home/zoidberg/.editorconfig [*.md] 210 | /home/zoidberg/humans/.editorconfig [*] 211 | ``` 212 | 213 | ## Development 214 | 215 | To install dependencies for this package run this in the package directory: 216 | 217 | ```bash 218 | $ npm install 219 | ``` 220 | 221 | Next, run the following commands: 222 | 223 | ```bash 224 | $ npm run build 225 | $ npm link 226 | ``` 227 | 228 | The global editorconfig will now point to the files in your development 229 | repository instead of a globally-installed version from npm. You can now use 230 | editorconfig directly to test your changes. 231 | 232 | If you ever update from the central repository and there are errors, it might 233 | be because you are missing some dependencies. If that happens, just run npm 234 | link again to get the latest dependencies. 235 | 236 | To test the command line interface: 237 | 238 | ```bash 239 | $ editorconfig 240 | ``` 241 | 242 | # Testing 243 | 244 | [CMake][] must be installed to run the tests. 245 | 246 | To run the tests: 247 | 248 | ```bash 249 | $ npm test 250 | ``` 251 | 252 | To run the tests with increased verbosity (for debugging test failures): 253 | 254 | ```bash 255 | $ npm run ci 256 | ``` 257 | 258 | [EditorConfig C Core]: https://github.com/editorconfig/editorconfig-core 259 | [EditorConfig Python Core]: https://github.com/editorconfig/editorconfig-core-py 260 | [node]: http://nodejs.org/ 261 | [cmake]: http://www.cmake.org 262 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | v1.0.0 | :white_check_mark: | 8 | | v0.15.3 | :x: | 9 | | { 4 | console.error(e) 5 | process.exit(1) 6 | }) 7 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import base from '@cto.af/eslint-config'; 2 | import ts from '@cto.af/eslint-config/ts.js'; 3 | 4 | export default [ 5 | { 6 | ignores: [ 7 | 'lib/**', 8 | '**/*.d.ts', 9 | ], 10 | }, 11 | ...base, 12 | ...ts, 13 | { 14 | files: [ 15 | 'src/index.ts', 16 | ], 17 | rules: { 18 | // We are extra-careful with some inputs. 19 | '@typescript-eslint/no-unnecessary-type-conversion': 'off', 20 | }, 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editorconfig", 3 | "version": "2.0.1", 4 | "description": "EditorConfig File Locator and Interpreter for Node.js", 5 | "keywords": [ 6 | "editorconfig", 7 | "core" 8 | ], 9 | "main": "./lib/index.js", 10 | "contributors": [ 11 | "Hong Xu (topbug.net)", 12 | "Jed Mao (https://github.com/jedmao/)", 13 | "Trey Hunner (http://treyhunner.com)", 14 | "Joe Hildebrand (https://github.com/hildjj/)" 15 | ], 16 | "directories": { 17 | "bin": "./bin", 18 | "lib": "./lib" 19 | }, 20 | "scripts": { 21 | "clean": "rimraf lib cmake_install.cmake CTestTestfile.cmake Makefile", 22 | "prebuild": "npm run clean", 23 | "build": "cmake . && tsc", 24 | "pretest": "npm run build && npm run lint", 25 | "test": "npm run test:all", 26 | "test:all": "mocha && ctest . --preset Test", 27 | "precoverage": "npm run build -- --inlineSourceMap", 28 | "coverage": "c8 npm run test:all", 29 | "postcoverage": "npm run build", 30 | "ci": "npm run coverage -- -- -VV --output-on-failure", 31 | "lint": "eslint .", 32 | "prepub": "npm run lint && npm run build", 33 | "pub": "npm publish" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "git://github.com/editorconfig/editorconfig-core-js.git" 38 | }, 39 | "bugs": "https://github.com/editorconfig/editorconfig-core-js/issues", 40 | "author": "EditorConfig Team", 41 | "license": "MIT", 42 | "dependencies": { 43 | "@one-ini/wasm": "0.2.0", 44 | "commander": "^14.0.0", 45 | "minimatch": "10.0.1", 46 | "semver": "^7.7.2" 47 | }, 48 | "devDependencies": { 49 | "@cto.af/eslint-config": "6.0.5", 50 | "@types/chai": "4.3.20", 51 | "@types/mocha": "^10.0.10", 52 | "@types/node": "^22.15.30", 53 | "@types/semver": "^7.7.0", 54 | "@typescript-eslint/eslint-plugin": "8.34.0", 55 | "@typescript-eslint/parser": "8.34.0", 56 | "c8": "10.1.3", 57 | "chai": "4.5.0", 58 | "eslint": "9.28.0", 59 | "eslint-plugin-jsdoc": "50.7.1", 60 | "mocha": "^11.6.0", 61 | "rimraf": "^6.0.1", 62 | "typescript": "5.8.3", 63 | "typescript-eslint": "8.34.0" 64 | }, 65 | "packageManager": "pnpm@10.12.1", 66 | "engines": { 67 | "node": ">=20" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@one-ini/wasm': 12 | specifier: 0.2.0 13 | version: 0.2.0 14 | commander: 15 | specifier: ^14.0.0 16 | version: 14.0.0 17 | minimatch: 18 | specifier: 10.0.1 19 | version: 10.0.1 20 | semver: 21 | specifier: ^7.7.2 22 | version: 7.7.2 23 | devDependencies: 24 | '@cto.af/eslint-config': 25 | specifier: 6.0.5 26 | version: 6.0.5(eslint@9.28.0)(typescript@5.8.3) 27 | '@types/chai': 28 | specifier: 4.3.20 29 | version: 4.3.20 30 | '@types/mocha': 31 | specifier: ^10.0.10 32 | version: 10.0.10 33 | '@types/node': 34 | specifier: ^22.15.30 35 | version: 22.15.30 36 | '@types/semver': 37 | specifier: ^7.7.0 38 | version: 7.7.0 39 | '@typescript-eslint/eslint-plugin': 40 | specifier: 8.34.0 41 | version: 8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0)(typescript@5.8.3))(eslint@9.28.0)(typescript@5.8.3) 42 | '@typescript-eslint/parser': 43 | specifier: 8.34.0 44 | version: 8.34.0(eslint@9.28.0)(typescript@5.8.3) 45 | c8: 46 | specifier: 10.1.3 47 | version: 10.1.3 48 | chai: 49 | specifier: 4.5.0 50 | version: 4.5.0 51 | eslint: 52 | specifier: 9.28.0 53 | version: 9.28.0 54 | eslint-plugin-jsdoc: 55 | specifier: 50.7.1 56 | version: 50.7.1(eslint@9.28.0) 57 | mocha: 58 | specifier: ^11.6.0 59 | version: 11.6.0 60 | rimraf: 61 | specifier: ^6.0.1 62 | version: 6.0.1 63 | typescript: 64 | specifier: 5.8.3 65 | version: 5.8.3 66 | typescript-eslint: 67 | specifier: 8.34.0 68 | version: 8.34.0(eslint@9.28.0)(typescript@5.8.3) 69 | 70 | packages: 71 | 72 | '@bcoe/v8-coverage@1.0.2': 73 | resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} 74 | engines: {node: '>=18'} 75 | 76 | '@cto.af/eslint-config@6.0.5': 77 | resolution: {integrity: sha512-6iXp94N7LgFXqWgLk3u+PnhF7h4PYKNRcEnlQDA4qpFIuxee02dgPg69SBX1GlbftVeUTGM8DPT/xMp7cHZkQw==} 78 | engines: {node: '>=20'} 79 | 80 | '@es-joy/jsdoccomment@0.50.2': 81 | resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} 82 | engines: {node: '>=18'} 83 | 84 | '@eslint-community/eslint-utils@4.7.0': 85 | resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} 86 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 87 | peerDependencies: 88 | eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 89 | 90 | '@eslint-community/regexpp@4.12.1': 91 | resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} 92 | engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} 93 | 94 | '@eslint/config-array@0.20.0': 95 | resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} 96 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 97 | 98 | '@eslint/config-helpers@0.2.2': 99 | resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} 100 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 101 | 102 | '@eslint/core@0.12.0': 103 | resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} 104 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 105 | 106 | '@eslint/core@0.13.0': 107 | resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} 108 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 109 | 110 | '@eslint/core@0.14.0': 111 | resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} 112 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 113 | 114 | '@eslint/eslintrc@3.3.1': 115 | resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} 116 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 117 | 118 | '@eslint/js@9.28.0': 119 | resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} 120 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 121 | 122 | '@eslint/json@0.12.0': 123 | resolution: {integrity: sha512-n/7dz8HFStpEe4o5eYk0tdkBdGUS/ZGb0GQCeDWN1ZmRq67HMHK4vC33b0rQlTT6xdZoX935P4vstiWVk5Ying==} 124 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 125 | 126 | '@eslint/object-schema@2.1.6': 127 | resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} 128 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 129 | 130 | '@eslint/plugin-kit@0.2.8': 131 | resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} 132 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 133 | 134 | '@eslint/plugin-kit@0.3.1': 135 | resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} 136 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 137 | 138 | '@humanfs/core@0.19.1': 139 | resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} 140 | engines: {node: '>=18.18.0'} 141 | 142 | '@humanfs/node@0.16.6': 143 | resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} 144 | engines: {node: '>=18.18.0'} 145 | 146 | '@humanwhocodes/module-importer@1.0.1': 147 | resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} 148 | engines: {node: '>=12.22'} 149 | 150 | '@humanwhocodes/momoa@3.3.8': 151 | resolution: {integrity: sha512-/3PZzor2imi/RLLcnHztkwA79txiVvW145Ve2cp5dxRcH5qOUNJPToasqLFHniTfw4B4lT7jGDdBOPXbXYlIMQ==} 152 | engines: {node: '>=18'} 153 | 154 | '@humanwhocodes/retry@0.3.1': 155 | resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} 156 | engines: {node: '>=18.18'} 157 | 158 | '@humanwhocodes/retry@0.4.3': 159 | resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} 160 | engines: {node: '>=18.18'} 161 | 162 | '@isaacs/cliui@8.0.2': 163 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 164 | engines: {node: '>=12'} 165 | 166 | '@istanbuljs/schema@0.1.3': 167 | resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} 168 | engines: {node: '>=8'} 169 | 170 | '@jridgewell/resolve-uri@3.1.2': 171 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 172 | engines: {node: '>=6.0.0'} 173 | 174 | '@jridgewell/sourcemap-codec@1.5.0': 175 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 176 | 177 | '@jridgewell/trace-mapping@0.3.25': 178 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 179 | 180 | '@nodelib/fs.scandir@2.1.5': 181 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 182 | engines: {node: '>= 8'} 183 | 184 | '@nodelib/fs.stat@2.0.5': 185 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 186 | engines: {node: '>= 8'} 187 | 188 | '@nodelib/fs.walk@1.2.8': 189 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 190 | engines: {node: '>= 8'} 191 | 192 | '@one-ini/wasm@0.2.0': 193 | resolution: {integrity: sha512-n+L/BvrwKUn7q5O3wHGo+CJZAqfewh38+37sk+eBzv/39lM9pPgPRd4sOZRvSRzo0ukLxzyXso4WlGj2oKZ5hA==} 194 | 195 | '@pkgjs/parseargs@0.11.0': 196 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 197 | engines: {node: '>=14'} 198 | 199 | '@stylistic/eslint-plugin@4.4.0': 200 | resolution: {integrity: sha512-bIh/d9X+OQLCAMdhHtps+frvyjvAM4B1YlSJzcEEhl7wXLIqPar3ngn9DrHhkBOrTA/z9J0bUMtctAspe0dxdQ==} 201 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 202 | peerDependencies: 203 | eslint: '>=9.0.0' 204 | 205 | '@types/chai@4.3.20': 206 | resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} 207 | 208 | '@types/estree@1.0.8': 209 | resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 210 | 211 | '@types/istanbul-lib-coverage@2.0.6': 212 | resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} 213 | 214 | '@types/json-schema@7.0.15': 215 | resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} 216 | 217 | '@types/mocha@10.0.10': 218 | resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} 219 | 220 | '@types/node@22.15.30': 221 | resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==} 222 | 223 | '@types/semver@7.7.0': 224 | resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} 225 | 226 | '@typescript-eslint/eslint-plugin@8.34.0': 227 | resolution: {integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==} 228 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 229 | peerDependencies: 230 | '@typescript-eslint/parser': ^8.34.0 231 | eslint: ^8.57.0 || ^9.0.0 232 | typescript: '>=4.8.4 <5.9.0' 233 | 234 | '@typescript-eslint/parser@8.34.0': 235 | resolution: {integrity: sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==} 236 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 237 | peerDependencies: 238 | eslint: ^8.57.0 || ^9.0.0 239 | typescript: '>=4.8.4 <5.9.0' 240 | 241 | '@typescript-eslint/project-service@8.34.0': 242 | resolution: {integrity: sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==} 243 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 244 | peerDependencies: 245 | typescript: '>=4.8.4 <5.9.0' 246 | 247 | '@typescript-eslint/scope-manager@8.34.0': 248 | resolution: {integrity: sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==} 249 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 250 | 251 | '@typescript-eslint/tsconfig-utils@8.34.0': 252 | resolution: {integrity: sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==} 253 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 254 | peerDependencies: 255 | typescript: '>=4.8.4 <5.9.0' 256 | 257 | '@typescript-eslint/type-utils@8.34.0': 258 | resolution: {integrity: sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==} 259 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 260 | peerDependencies: 261 | eslint: ^8.57.0 || ^9.0.0 262 | typescript: '>=4.8.4 <5.9.0' 263 | 264 | '@typescript-eslint/types@8.34.0': 265 | resolution: {integrity: sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==} 266 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 267 | 268 | '@typescript-eslint/typescript-estree@8.34.0': 269 | resolution: {integrity: sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==} 270 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 271 | peerDependencies: 272 | typescript: '>=4.8.4 <5.9.0' 273 | 274 | '@typescript-eslint/utils@8.34.0': 275 | resolution: {integrity: sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==} 276 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 277 | peerDependencies: 278 | eslint: ^8.57.0 || ^9.0.0 279 | typescript: '>=4.8.4 <5.9.0' 280 | 281 | '@typescript-eslint/visitor-keys@8.34.0': 282 | resolution: {integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==} 283 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 284 | 285 | acorn-jsx@5.3.2: 286 | resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} 287 | peerDependencies: 288 | acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 289 | 290 | acorn@8.15.0: 291 | resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} 292 | engines: {node: '>=0.4.0'} 293 | hasBin: true 294 | 295 | ajv@6.12.6: 296 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 297 | 298 | ansi-regex@5.0.1: 299 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 300 | engines: {node: '>=8'} 301 | 302 | ansi-regex@6.1.0: 303 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} 304 | engines: {node: '>=12'} 305 | 306 | ansi-styles@4.3.0: 307 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 308 | engines: {node: '>=8'} 309 | 310 | ansi-styles@6.2.1: 311 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 312 | engines: {node: '>=12'} 313 | 314 | are-docs-informative@0.0.2: 315 | resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} 316 | engines: {node: '>=14'} 317 | 318 | argparse@2.0.1: 319 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 320 | 321 | assertion-error@1.1.0: 322 | resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} 323 | 324 | balanced-match@1.0.2: 325 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 326 | 327 | brace-expansion@1.1.11: 328 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 329 | 330 | brace-expansion@2.0.1: 331 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 332 | 333 | braces@3.0.3: 334 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 335 | engines: {node: '>=8'} 336 | 337 | browser-stdout@1.3.1: 338 | resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} 339 | 340 | c8@10.1.3: 341 | resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==} 342 | engines: {node: '>=18'} 343 | hasBin: true 344 | peerDependencies: 345 | monocart-coverage-reports: ^2 346 | peerDependenciesMeta: 347 | monocart-coverage-reports: 348 | optional: true 349 | 350 | callsites@3.1.0: 351 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 352 | engines: {node: '>=6'} 353 | 354 | camelcase@6.3.0: 355 | resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} 356 | engines: {node: '>=10'} 357 | 358 | chai@4.5.0: 359 | resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} 360 | engines: {node: '>=4'} 361 | 362 | chalk@4.1.2: 363 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 364 | engines: {node: '>=10'} 365 | 366 | check-error@1.0.3: 367 | resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} 368 | 369 | chokidar@4.0.3: 370 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} 371 | engines: {node: '>= 14.16.0'} 372 | 373 | cliui@8.0.1: 374 | resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} 375 | engines: {node: '>=12'} 376 | 377 | color-convert@2.0.1: 378 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 379 | engines: {node: '>=7.0.0'} 380 | 381 | color-name@1.1.4: 382 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 383 | 384 | commander@14.0.0: 385 | resolution: {integrity: sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==} 386 | engines: {node: '>=20'} 387 | 388 | comment-parser@1.4.1: 389 | resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} 390 | engines: {node: '>= 12.0.0'} 391 | 392 | concat-map@0.0.1: 393 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 394 | 395 | convert-source-map@2.0.0: 396 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} 397 | 398 | cross-spawn@7.0.6: 399 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 400 | engines: {node: '>= 8'} 401 | 402 | debug@4.4.1: 403 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} 404 | engines: {node: '>=6.0'} 405 | peerDependencies: 406 | supports-color: '*' 407 | peerDependenciesMeta: 408 | supports-color: 409 | optional: true 410 | 411 | decamelize@4.0.0: 412 | resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} 413 | engines: {node: '>=10'} 414 | 415 | deep-eql@4.1.4: 416 | resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} 417 | engines: {node: '>=6'} 418 | 419 | deep-is@0.1.4: 420 | resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} 421 | 422 | diff@7.0.0: 423 | resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} 424 | engines: {node: '>=0.3.1'} 425 | 426 | eastasianwidth@0.2.0: 427 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 428 | 429 | emoji-regex@8.0.0: 430 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 431 | 432 | emoji-regex@9.2.2: 433 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 434 | 435 | enhanced-resolve@5.18.1: 436 | resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} 437 | engines: {node: '>=10.13.0'} 438 | 439 | escalade@3.2.0: 440 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 441 | engines: {node: '>=6'} 442 | 443 | escape-string-regexp@4.0.0: 444 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 445 | engines: {node: '>=10'} 446 | 447 | eslint-compat-utils@0.5.1: 448 | resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} 449 | engines: {node: '>=12'} 450 | peerDependencies: 451 | eslint: '>=6.0.0' 452 | 453 | eslint-plugin-es-x@7.8.0: 454 | resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} 455 | engines: {node: ^14.18.0 || >=16.0.0} 456 | peerDependencies: 457 | eslint: '>=8' 458 | 459 | eslint-plugin-jsdoc@50.7.1: 460 | resolution: {integrity: sha512-XBnVA5g2kUVokTNUiE1McEPse5n9/mNUmuJcx52psT6zBs2eVcXSmQBvjfa7NZdfLVSy3u1pEDDUxoxpwy89WA==} 461 | engines: {node: '>=18'} 462 | peerDependencies: 463 | eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 464 | 465 | eslint-plugin-n@17.18.0: 466 | resolution: {integrity: sha512-hvZ/HusueqTJ7VDLoCpjN0hx4N4+jHIWTXD4TMLHy9F23XkDagR9v+xQWRWR57yY55GPF8NnD4ox9iGTxirY8A==} 467 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 468 | peerDependencies: 469 | eslint: '>=8.23.0' 470 | 471 | eslint-plugin-redos@4.4.5: 472 | resolution: {integrity: sha512-t2OxsTply2KTXjjJbfQPgQcwxzcoqhx8DtmM/0r17GLNTr35Aa5C/slXHg1r2fEk1LhzjfYXysjLCsD0ZLJjLg==} 473 | engines: {node: '>=14'} 474 | peerDependencies: 475 | eslint: '>= 3' 476 | 477 | eslint-scope@8.4.0: 478 | resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} 479 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 480 | 481 | eslint-visitor-keys@3.4.3: 482 | resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} 483 | engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 484 | 485 | eslint-visitor-keys@4.2.1: 486 | resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} 487 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 488 | 489 | eslint@9.28.0: 490 | resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} 491 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 492 | hasBin: true 493 | peerDependencies: 494 | jiti: '*' 495 | peerDependenciesMeta: 496 | jiti: 497 | optional: true 498 | 499 | espree@10.4.0: 500 | resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} 501 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 502 | 503 | esquery@1.6.0: 504 | resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} 505 | engines: {node: '>=0.10'} 506 | 507 | esrecurse@4.3.0: 508 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 509 | engines: {node: '>=4.0'} 510 | 511 | estraverse@5.3.0: 512 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 513 | engines: {node: '>=4.0'} 514 | 515 | esutils@2.0.3: 516 | resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} 517 | engines: {node: '>=0.10.0'} 518 | 519 | fast-deep-equal@3.1.3: 520 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 521 | 522 | fast-glob@3.3.3: 523 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 524 | engines: {node: '>=8.6.0'} 525 | 526 | fast-json-stable-stringify@2.1.0: 527 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 528 | 529 | fast-levenshtein@2.0.6: 530 | resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 531 | 532 | fastq@1.19.1: 533 | resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} 534 | 535 | file-entry-cache@8.0.0: 536 | resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} 537 | engines: {node: '>=16.0.0'} 538 | 539 | fill-range@7.1.1: 540 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 541 | engines: {node: '>=8'} 542 | 543 | find-up@5.0.0: 544 | resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} 545 | engines: {node: '>=10'} 546 | 547 | flat-cache@4.0.1: 548 | resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} 549 | engines: {node: '>=16'} 550 | 551 | flat@5.0.2: 552 | resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} 553 | hasBin: true 554 | 555 | flatted@3.3.3: 556 | resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} 557 | 558 | foreground-child@3.3.1: 559 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} 560 | engines: {node: '>=14'} 561 | 562 | get-caller-file@2.0.5: 563 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 564 | engines: {node: 6.* || 8.* || >= 10.*} 565 | 566 | get-func-name@2.0.2: 567 | resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} 568 | 569 | get-tsconfig@4.10.1: 570 | resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} 571 | 572 | glob-parent@5.1.2: 573 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 574 | engines: {node: '>= 6'} 575 | 576 | glob-parent@6.0.2: 577 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 578 | engines: {node: '>=10.13.0'} 579 | 580 | glob@10.4.5: 581 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 582 | hasBin: true 583 | 584 | glob@11.0.2: 585 | resolution: {integrity: sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==} 586 | engines: {node: 20 || >=22} 587 | hasBin: true 588 | 589 | globals@14.0.0: 590 | resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} 591 | engines: {node: '>=18'} 592 | 593 | globals@15.15.0: 594 | resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} 595 | engines: {node: '>=18'} 596 | 597 | globals@16.2.0: 598 | resolution: {integrity: sha512-O+7l9tPdHCU320IigZZPj5zmRCFG9xHmx9cU8FqU2Rp+JN714seHV+2S9+JslCpY4gJwU2vOGox0wzgae/MCEg==} 599 | engines: {node: '>=18'} 600 | 601 | graceful-fs@4.2.11: 602 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 603 | 604 | graphemer@1.4.0: 605 | resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} 606 | 607 | has-flag@4.0.0: 608 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 609 | engines: {node: '>=8'} 610 | 611 | he@1.2.0: 612 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 613 | hasBin: true 614 | 615 | html-escaper@2.0.2: 616 | resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} 617 | 618 | ignore@5.3.2: 619 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 620 | engines: {node: '>= 4'} 621 | 622 | ignore@7.0.5: 623 | resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} 624 | engines: {node: '>= 4'} 625 | 626 | import-fresh@3.3.1: 627 | resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} 628 | engines: {node: '>=6'} 629 | 630 | imurmurhash@0.1.4: 631 | resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} 632 | engines: {node: '>=0.8.19'} 633 | 634 | is-extglob@2.1.1: 635 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 636 | engines: {node: '>=0.10.0'} 637 | 638 | is-fullwidth-code-point@3.0.0: 639 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 640 | engines: {node: '>=8'} 641 | 642 | is-glob@4.0.3: 643 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 644 | engines: {node: '>=0.10.0'} 645 | 646 | is-number@7.0.0: 647 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 648 | engines: {node: '>=0.12.0'} 649 | 650 | is-plain-obj@2.1.0: 651 | resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} 652 | engines: {node: '>=8'} 653 | 654 | is-unicode-supported@0.1.0: 655 | resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} 656 | engines: {node: '>=10'} 657 | 658 | isexe@2.0.0: 659 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 660 | 661 | istanbul-lib-coverage@3.2.2: 662 | resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} 663 | engines: {node: '>=8'} 664 | 665 | istanbul-lib-report@3.0.1: 666 | resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} 667 | engines: {node: '>=10'} 668 | 669 | istanbul-reports@3.1.7: 670 | resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} 671 | engines: {node: '>=8'} 672 | 673 | jackspeak@3.4.3: 674 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 675 | 676 | jackspeak@4.1.1: 677 | resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} 678 | engines: {node: 20 || >=22} 679 | 680 | js-yaml@4.1.0: 681 | resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} 682 | hasBin: true 683 | 684 | jsdoc-type-pratt-parser@4.1.0: 685 | resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} 686 | engines: {node: '>=12.0.0'} 687 | 688 | json-buffer@3.0.1: 689 | resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} 690 | 691 | json-schema-traverse@0.4.1: 692 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 693 | 694 | json-stable-stringify-without-jsonify@1.0.1: 695 | resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} 696 | 697 | keyv@4.5.4: 698 | resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} 699 | 700 | levn@0.4.1: 701 | resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} 702 | engines: {node: '>= 0.8.0'} 703 | 704 | locate-path@6.0.0: 705 | resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} 706 | engines: {node: '>=10'} 707 | 708 | lodash.merge@4.6.2: 709 | resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} 710 | 711 | log-symbols@4.1.0: 712 | resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} 713 | engines: {node: '>=10'} 714 | 715 | loupe@2.3.7: 716 | resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} 717 | 718 | lru-cache@10.4.3: 719 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 720 | 721 | lru-cache@11.1.0: 722 | resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} 723 | engines: {node: 20 || >=22} 724 | 725 | make-dir@4.0.0: 726 | resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} 727 | engines: {node: '>=10'} 728 | 729 | merge2@1.4.1: 730 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 731 | engines: {node: '>= 8'} 732 | 733 | micromatch@4.0.8: 734 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 735 | engines: {node: '>=8.6'} 736 | 737 | minimatch@10.0.1: 738 | resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} 739 | engines: {node: 20 || >=22} 740 | 741 | minimatch@3.1.2: 742 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 743 | 744 | minimatch@9.0.5: 745 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 746 | engines: {node: '>=16 || 14 >=14.17'} 747 | 748 | minipass@7.1.2: 749 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 750 | engines: {node: '>=16 || 14 >=14.17'} 751 | 752 | mocha@11.6.0: 753 | resolution: {integrity: sha512-i0JVb+OUBqw63X/1pC3jCyJsqYisgxySBbsQa8TKvefpA1oEnw7JXxXnftfMHRsw7bEEVGRtVlHcDYXBa7FzVw==} 754 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 755 | hasBin: true 756 | 757 | ms@2.1.3: 758 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 759 | 760 | natural-compare@1.4.0: 761 | resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} 762 | 763 | optionator@0.9.4: 764 | resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} 765 | engines: {node: '>= 0.8.0'} 766 | 767 | p-limit@3.1.0: 768 | resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} 769 | engines: {node: '>=10'} 770 | 771 | p-locate@5.0.0: 772 | resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} 773 | engines: {node: '>=10'} 774 | 775 | package-json-from-dist@1.0.1: 776 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} 777 | 778 | parent-module@1.0.1: 779 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 780 | engines: {node: '>=6'} 781 | 782 | parse-imports-exports@0.2.4: 783 | resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} 784 | 785 | parse-statements@1.0.11: 786 | resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} 787 | 788 | path-exists@4.0.0: 789 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 790 | engines: {node: '>=8'} 791 | 792 | path-key@3.1.1: 793 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 794 | engines: {node: '>=8'} 795 | 796 | path-scurry@1.11.1: 797 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 798 | engines: {node: '>=16 || 14 >=14.18'} 799 | 800 | path-scurry@2.0.0: 801 | resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} 802 | engines: {node: 20 || >=22} 803 | 804 | pathval@1.1.1: 805 | resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} 806 | 807 | picocolors@1.1.1: 808 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 809 | 810 | picomatch@2.3.1: 811 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 812 | engines: {node: '>=8.6'} 813 | 814 | picomatch@4.0.2: 815 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} 816 | engines: {node: '>=12'} 817 | 818 | prelude-ls@1.2.1: 819 | resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 820 | engines: {node: '>= 0.8.0'} 821 | 822 | punycode@2.3.1: 823 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 824 | engines: {node: '>=6'} 825 | 826 | queue-microtask@1.2.3: 827 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 828 | 829 | randombytes@2.1.0: 830 | resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} 831 | 832 | readdirp@4.1.2: 833 | resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} 834 | engines: {node: '>= 14.18.0'} 835 | 836 | recheck-jar@4.4.5: 837 | resolution: {integrity: sha512-a2kMzcfr+ntT0bObNLY22EUNV6Z6WeZ+DybRmPOUXVWzGcqhRcrK74tpgrYt3FdzTlSh85pqoryAPmrNkwLc0g==} 838 | 839 | recheck-linux-x64@4.4.5: 840 | resolution: {integrity: sha512-s8OVPCpiSGw+tLCxH3eei7Zp2AoL22kXqLmEtWXi0AnYNwfuTjZmeLn2aQjW8qhs8ZPSkxS7uRIRTeZqR5Fv/Q==} 841 | cpu: [x64] 842 | os: [linux] 843 | 844 | recheck-macos-x64@4.4.5: 845 | resolution: {integrity: sha512-Ouup9JwwoKCDclt3Na8+/W2pVbt8FRpzjkDuyM32qTR2TOid1NI+P1GA6/VQAKEOjvaxgGjxhcP/WqAjN+EULA==} 846 | cpu: [x64] 847 | os: [darwin] 848 | 849 | recheck-windows-x64@4.4.5: 850 | resolution: {integrity: sha512-mkpzLHu9G9Ztjx8HssJh9k/Xm1d1d/4OoT7etHqFk+k1NGzISCRXBD22DqYF9w8+J4QEzTAoDf8icFt0IGhOEQ==} 851 | cpu: [x64] 852 | os: [win32] 853 | 854 | recheck@4.4.5: 855 | resolution: {integrity: sha512-J80Ykhr+xxWtvWrfZfPpOR/iw2ijvb4WY8d9AVoN8oHsPP07JT1rCAalUSACMGxM1cvSocb6jppWFjVS6eTTrA==} 856 | engines: {node: '>=14'} 857 | 858 | require-directory@2.1.1: 859 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 860 | engines: {node: '>=0.10.0'} 861 | 862 | resolve-from@4.0.0: 863 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 864 | engines: {node: '>=4'} 865 | 866 | resolve-pkg-maps@1.0.0: 867 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 868 | 869 | reusify@1.1.0: 870 | resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} 871 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 872 | 873 | rimraf@6.0.1: 874 | resolution: {integrity: sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==} 875 | engines: {node: 20 || >=22} 876 | hasBin: true 877 | 878 | run-parallel@1.2.0: 879 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 880 | 881 | safe-buffer@5.2.1: 882 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 883 | 884 | semver@7.7.2: 885 | resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 886 | engines: {node: '>=10'} 887 | hasBin: true 888 | 889 | serialize-javascript@6.0.2: 890 | resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} 891 | 892 | shebang-command@2.0.0: 893 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 894 | engines: {node: '>=8'} 895 | 896 | shebang-regex@3.0.0: 897 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 898 | engines: {node: '>=8'} 899 | 900 | signal-exit@4.1.0: 901 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 902 | engines: {node: '>=14'} 903 | 904 | spdx-exceptions@2.5.0: 905 | resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} 906 | 907 | spdx-expression-parse@4.0.0: 908 | resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} 909 | 910 | spdx-license-ids@3.0.21: 911 | resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} 912 | 913 | string-width@4.2.3: 914 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 915 | engines: {node: '>=8'} 916 | 917 | string-width@5.1.2: 918 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 919 | engines: {node: '>=12'} 920 | 921 | strip-ansi@6.0.1: 922 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 923 | engines: {node: '>=8'} 924 | 925 | strip-ansi@7.1.0: 926 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 927 | engines: {node: '>=12'} 928 | 929 | strip-json-comments@3.1.1: 930 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 931 | engines: {node: '>=8'} 932 | 933 | supports-color@7.2.0: 934 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 935 | engines: {node: '>=8'} 936 | 937 | supports-color@8.1.1: 938 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 939 | engines: {node: '>=10'} 940 | 941 | tapable@2.2.2: 942 | resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} 943 | engines: {node: '>=6'} 944 | 945 | test-exclude@7.0.1: 946 | resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} 947 | engines: {node: '>=18'} 948 | 949 | to-regex-range@5.0.1: 950 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 951 | engines: {node: '>=8.0'} 952 | 953 | ts-api-utils@2.1.0: 954 | resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} 955 | engines: {node: '>=18.12'} 956 | peerDependencies: 957 | typescript: '>=4.8.4' 958 | 959 | type-check@0.4.0: 960 | resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} 961 | engines: {node: '>= 0.8.0'} 962 | 963 | type-detect@4.1.0: 964 | resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} 965 | engines: {node: '>=4'} 966 | 967 | typescript-eslint@8.34.0: 968 | resolution: {integrity: sha512-MRpfN7uYjTrTGigFCt8sRyNqJFhjN0WwZecldaqhWm+wy0gaRt8Edb/3cuUy0zdq2opJWT6iXINKAtewnDOltQ==} 969 | engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 970 | peerDependencies: 971 | eslint: ^8.57.0 || ^9.0.0 972 | typescript: '>=4.8.4 <5.9.0' 973 | 974 | typescript@5.8.3: 975 | resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} 976 | engines: {node: '>=14.17'} 977 | hasBin: true 978 | 979 | undici-types@6.21.0: 980 | resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 981 | 982 | uri-js@4.4.1: 983 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 984 | 985 | v8-to-istanbul@9.3.0: 986 | resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} 987 | engines: {node: '>=10.12.0'} 988 | 989 | which@2.0.2: 990 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 991 | engines: {node: '>= 8'} 992 | hasBin: true 993 | 994 | word-wrap@1.2.5: 995 | resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} 996 | engines: {node: '>=0.10.0'} 997 | 998 | workerpool@9.3.2: 999 | resolution: {integrity: sha512-Xz4Nm9c+LiBHhDR5bDLnNzmj6+5F+cyEAWPMkbs2awq/dYazR/efelZzUAjB/y3kNHL+uzkHvxVVpaOfGCPV7A==} 1000 | 1001 | wrap-ansi@7.0.0: 1002 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1003 | engines: {node: '>=10'} 1004 | 1005 | wrap-ansi@8.1.0: 1006 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1007 | engines: {node: '>=12'} 1008 | 1009 | y18n@5.0.8: 1010 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 1011 | engines: {node: '>=10'} 1012 | 1013 | yargs-parser@21.1.1: 1014 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 1015 | engines: {node: '>=12'} 1016 | 1017 | yargs-unparser@2.0.0: 1018 | resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} 1019 | engines: {node: '>=10'} 1020 | 1021 | yargs@17.7.2: 1022 | resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} 1023 | engines: {node: '>=12'} 1024 | 1025 | yocto-queue@0.1.0: 1026 | resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} 1027 | engines: {node: '>=10'} 1028 | 1029 | snapshots: 1030 | 1031 | '@bcoe/v8-coverage@1.0.2': {} 1032 | 1033 | '@cto.af/eslint-config@6.0.5(eslint@9.28.0)(typescript@5.8.3)': 1034 | dependencies: 1035 | '@eslint/json': 0.12.0 1036 | '@stylistic/eslint-plugin': 4.4.0(eslint@9.28.0)(typescript@5.8.3) 1037 | eslint-plugin-n: 17.18.0(eslint@9.28.0) 1038 | eslint-plugin-redos: 4.4.5(eslint@9.28.0) 1039 | globals: 16.2.0 1040 | transitivePeerDependencies: 1041 | - eslint 1042 | - supports-color 1043 | - typescript 1044 | 1045 | '@es-joy/jsdoccomment@0.50.2': 1046 | dependencies: 1047 | '@types/estree': 1.0.8 1048 | '@typescript-eslint/types': 8.34.0 1049 | comment-parser: 1.4.1 1050 | esquery: 1.6.0 1051 | jsdoc-type-pratt-parser: 4.1.0 1052 | 1053 | '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0)': 1054 | dependencies: 1055 | eslint: 9.28.0 1056 | eslint-visitor-keys: 3.4.3 1057 | 1058 | '@eslint-community/regexpp@4.12.1': {} 1059 | 1060 | '@eslint/config-array@0.20.0': 1061 | dependencies: 1062 | '@eslint/object-schema': 2.1.6 1063 | debug: 4.4.1(supports-color@8.1.1) 1064 | minimatch: 3.1.2 1065 | transitivePeerDependencies: 1066 | - supports-color 1067 | 1068 | '@eslint/config-helpers@0.2.2': {} 1069 | 1070 | '@eslint/core@0.12.0': 1071 | dependencies: 1072 | '@types/json-schema': 7.0.15 1073 | 1074 | '@eslint/core@0.13.0': 1075 | dependencies: 1076 | '@types/json-schema': 7.0.15 1077 | 1078 | '@eslint/core@0.14.0': 1079 | dependencies: 1080 | '@types/json-schema': 7.0.15 1081 | 1082 | '@eslint/eslintrc@3.3.1': 1083 | dependencies: 1084 | ajv: 6.12.6 1085 | debug: 4.4.1(supports-color@8.1.1) 1086 | espree: 10.4.0 1087 | globals: 14.0.0 1088 | ignore: 5.3.2 1089 | import-fresh: 3.3.1 1090 | js-yaml: 4.1.0 1091 | minimatch: 3.1.2 1092 | strip-json-comments: 3.1.1 1093 | transitivePeerDependencies: 1094 | - supports-color 1095 | 1096 | '@eslint/js@9.28.0': {} 1097 | 1098 | '@eslint/json@0.12.0': 1099 | dependencies: 1100 | '@eslint/core': 0.12.0 1101 | '@eslint/plugin-kit': 0.2.8 1102 | '@humanwhocodes/momoa': 3.3.8 1103 | natural-compare: 1.4.0 1104 | 1105 | '@eslint/object-schema@2.1.6': {} 1106 | 1107 | '@eslint/plugin-kit@0.2.8': 1108 | dependencies: 1109 | '@eslint/core': 0.13.0 1110 | levn: 0.4.1 1111 | 1112 | '@eslint/plugin-kit@0.3.1': 1113 | dependencies: 1114 | '@eslint/core': 0.14.0 1115 | levn: 0.4.1 1116 | 1117 | '@humanfs/core@0.19.1': {} 1118 | 1119 | '@humanfs/node@0.16.6': 1120 | dependencies: 1121 | '@humanfs/core': 0.19.1 1122 | '@humanwhocodes/retry': 0.3.1 1123 | 1124 | '@humanwhocodes/module-importer@1.0.1': {} 1125 | 1126 | '@humanwhocodes/momoa@3.3.8': {} 1127 | 1128 | '@humanwhocodes/retry@0.3.1': {} 1129 | 1130 | '@humanwhocodes/retry@0.4.3': {} 1131 | 1132 | '@isaacs/cliui@8.0.2': 1133 | dependencies: 1134 | string-width: 5.1.2 1135 | string-width-cjs: string-width@4.2.3 1136 | strip-ansi: 7.1.0 1137 | strip-ansi-cjs: strip-ansi@6.0.1 1138 | wrap-ansi: 8.1.0 1139 | wrap-ansi-cjs: wrap-ansi@7.0.0 1140 | 1141 | '@istanbuljs/schema@0.1.3': {} 1142 | 1143 | '@jridgewell/resolve-uri@3.1.2': {} 1144 | 1145 | '@jridgewell/sourcemap-codec@1.5.0': {} 1146 | 1147 | '@jridgewell/trace-mapping@0.3.25': 1148 | dependencies: 1149 | '@jridgewell/resolve-uri': 3.1.2 1150 | '@jridgewell/sourcemap-codec': 1.5.0 1151 | 1152 | '@nodelib/fs.scandir@2.1.5': 1153 | dependencies: 1154 | '@nodelib/fs.stat': 2.0.5 1155 | run-parallel: 1.2.0 1156 | 1157 | '@nodelib/fs.stat@2.0.5': {} 1158 | 1159 | '@nodelib/fs.walk@1.2.8': 1160 | dependencies: 1161 | '@nodelib/fs.scandir': 2.1.5 1162 | fastq: 1.19.1 1163 | 1164 | '@one-ini/wasm@0.2.0': {} 1165 | 1166 | '@pkgjs/parseargs@0.11.0': 1167 | optional: true 1168 | 1169 | '@stylistic/eslint-plugin@4.4.0(eslint@9.28.0)(typescript@5.8.3)': 1170 | dependencies: 1171 | '@typescript-eslint/utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1172 | eslint: 9.28.0 1173 | eslint-visitor-keys: 4.2.1 1174 | espree: 10.4.0 1175 | estraverse: 5.3.0 1176 | picomatch: 4.0.2 1177 | transitivePeerDependencies: 1178 | - supports-color 1179 | - typescript 1180 | 1181 | '@types/chai@4.3.20': {} 1182 | 1183 | '@types/estree@1.0.8': {} 1184 | 1185 | '@types/istanbul-lib-coverage@2.0.6': {} 1186 | 1187 | '@types/json-schema@7.0.15': {} 1188 | 1189 | '@types/mocha@10.0.10': {} 1190 | 1191 | '@types/node@22.15.30': 1192 | dependencies: 1193 | undici-types: 6.21.0 1194 | 1195 | '@types/semver@7.7.0': {} 1196 | 1197 | '@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0)(typescript@5.8.3))(eslint@9.28.0)(typescript@5.8.3)': 1198 | dependencies: 1199 | '@eslint-community/regexpp': 4.12.1 1200 | '@typescript-eslint/parser': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1201 | '@typescript-eslint/scope-manager': 8.34.0 1202 | '@typescript-eslint/type-utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1203 | '@typescript-eslint/utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1204 | '@typescript-eslint/visitor-keys': 8.34.0 1205 | eslint: 9.28.0 1206 | graphemer: 1.4.0 1207 | ignore: 7.0.5 1208 | natural-compare: 1.4.0 1209 | ts-api-utils: 2.1.0(typescript@5.8.3) 1210 | typescript: 5.8.3 1211 | transitivePeerDependencies: 1212 | - supports-color 1213 | 1214 | '@typescript-eslint/parser@8.34.0(eslint@9.28.0)(typescript@5.8.3)': 1215 | dependencies: 1216 | '@typescript-eslint/scope-manager': 8.34.0 1217 | '@typescript-eslint/types': 8.34.0 1218 | '@typescript-eslint/typescript-estree': 8.34.0(typescript@5.8.3) 1219 | '@typescript-eslint/visitor-keys': 8.34.0 1220 | debug: 4.4.1(supports-color@8.1.1) 1221 | eslint: 9.28.0 1222 | typescript: 5.8.3 1223 | transitivePeerDependencies: 1224 | - supports-color 1225 | 1226 | '@typescript-eslint/project-service@8.34.0(typescript@5.8.3)': 1227 | dependencies: 1228 | '@typescript-eslint/tsconfig-utils': 8.34.0(typescript@5.8.3) 1229 | '@typescript-eslint/types': 8.34.0 1230 | debug: 4.4.1(supports-color@8.1.1) 1231 | typescript: 5.8.3 1232 | transitivePeerDependencies: 1233 | - supports-color 1234 | 1235 | '@typescript-eslint/scope-manager@8.34.0': 1236 | dependencies: 1237 | '@typescript-eslint/types': 8.34.0 1238 | '@typescript-eslint/visitor-keys': 8.34.0 1239 | 1240 | '@typescript-eslint/tsconfig-utils@8.34.0(typescript@5.8.3)': 1241 | dependencies: 1242 | typescript: 5.8.3 1243 | 1244 | '@typescript-eslint/type-utils@8.34.0(eslint@9.28.0)(typescript@5.8.3)': 1245 | dependencies: 1246 | '@typescript-eslint/typescript-estree': 8.34.0(typescript@5.8.3) 1247 | '@typescript-eslint/utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1248 | debug: 4.4.1(supports-color@8.1.1) 1249 | eslint: 9.28.0 1250 | ts-api-utils: 2.1.0(typescript@5.8.3) 1251 | typescript: 5.8.3 1252 | transitivePeerDependencies: 1253 | - supports-color 1254 | 1255 | '@typescript-eslint/types@8.34.0': {} 1256 | 1257 | '@typescript-eslint/typescript-estree@8.34.0(typescript@5.8.3)': 1258 | dependencies: 1259 | '@typescript-eslint/project-service': 8.34.0(typescript@5.8.3) 1260 | '@typescript-eslint/tsconfig-utils': 8.34.0(typescript@5.8.3) 1261 | '@typescript-eslint/types': 8.34.0 1262 | '@typescript-eslint/visitor-keys': 8.34.0 1263 | debug: 4.4.1(supports-color@8.1.1) 1264 | fast-glob: 3.3.3 1265 | is-glob: 4.0.3 1266 | minimatch: 9.0.5 1267 | semver: 7.7.2 1268 | ts-api-utils: 2.1.0(typescript@5.8.3) 1269 | typescript: 5.8.3 1270 | transitivePeerDependencies: 1271 | - supports-color 1272 | 1273 | '@typescript-eslint/utils@8.34.0(eslint@9.28.0)(typescript@5.8.3)': 1274 | dependencies: 1275 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) 1276 | '@typescript-eslint/scope-manager': 8.34.0 1277 | '@typescript-eslint/types': 8.34.0 1278 | '@typescript-eslint/typescript-estree': 8.34.0(typescript@5.8.3) 1279 | eslint: 9.28.0 1280 | typescript: 5.8.3 1281 | transitivePeerDependencies: 1282 | - supports-color 1283 | 1284 | '@typescript-eslint/visitor-keys@8.34.0': 1285 | dependencies: 1286 | '@typescript-eslint/types': 8.34.0 1287 | eslint-visitor-keys: 4.2.1 1288 | 1289 | acorn-jsx@5.3.2(acorn@8.15.0): 1290 | dependencies: 1291 | acorn: 8.15.0 1292 | 1293 | acorn@8.15.0: {} 1294 | 1295 | ajv@6.12.6: 1296 | dependencies: 1297 | fast-deep-equal: 3.1.3 1298 | fast-json-stable-stringify: 2.1.0 1299 | json-schema-traverse: 0.4.1 1300 | uri-js: 4.4.1 1301 | 1302 | ansi-regex@5.0.1: {} 1303 | 1304 | ansi-regex@6.1.0: {} 1305 | 1306 | ansi-styles@4.3.0: 1307 | dependencies: 1308 | color-convert: 2.0.1 1309 | 1310 | ansi-styles@6.2.1: {} 1311 | 1312 | are-docs-informative@0.0.2: {} 1313 | 1314 | argparse@2.0.1: {} 1315 | 1316 | assertion-error@1.1.0: {} 1317 | 1318 | balanced-match@1.0.2: {} 1319 | 1320 | brace-expansion@1.1.11: 1321 | dependencies: 1322 | balanced-match: 1.0.2 1323 | concat-map: 0.0.1 1324 | 1325 | brace-expansion@2.0.1: 1326 | dependencies: 1327 | balanced-match: 1.0.2 1328 | 1329 | braces@3.0.3: 1330 | dependencies: 1331 | fill-range: 7.1.1 1332 | 1333 | browser-stdout@1.3.1: {} 1334 | 1335 | c8@10.1.3: 1336 | dependencies: 1337 | '@bcoe/v8-coverage': 1.0.2 1338 | '@istanbuljs/schema': 0.1.3 1339 | find-up: 5.0.0 1340 | foreground-child: 3.3.1 1341 | istanbul-lib-coverage: 3.2.2 1342 | istanbul-lib-report: 3.0.1 1343 | istanbul-reports: 3.1.7 1344 | test-exclude: 7.0.1 1345 | v8-to-istanbul: 9.3.0 1346 | yargs: 17.7.2 1347 | yargs-parser: 21.1.1 1348 | 1349 | callsites@3.1.0: {} 1350 | 1351 | camelcase@6.3.0: {} 1352 | 1353 | chai@4.5.0: 1354 | dependencies: 1355 | assertion-error: 1.1.0 1356 | check-error: 1.0.3 1357 | deep-eql: 4.1.4 1358 | get-func-name: 2.0.2 1359 | loupe: 2.3.7 1360 | pathval: 1.1.1 1361 | type-detect: 4.1.0 1362 | 1363 | chalk@4.1.2: 1364 | dependencies: 1365 | ansi-styles: 4.3.0 1366 | supports-color: 7.2.0 1367 | 1368 | check-error@1.0.3: 1369 | dependencies: 1370 | get-func-name: 2.0.2 1371 | 1372 | chokidar@4.0.3: 1373 | dependencies: 1374 | readdirp: 4.1.2 1375 | 1376 | cliui@8.0.1: 1377 | dependencies: 1378 | string-width: 4.2.3 1379 | strip-ansi: 6.0.1 1380 | wrap-ansi: 7.0.0 1381 | 1382 | color-convert@2.0.1: 1383 | dependencies: 1384 | color-name: 1.1.4 1385 | 1386 | color-name@1.1.4: {} 1387 | 1388 | commander@14.0.0: {} 1389 | 1390 | comment-parser@1.4.1: {} 1391 | 1392 | concat-map@0.0.1: {} 1393 | 1394 | convert-source-map@2.0.0: {} 1395 | 1396 | cross-spawn@7.0.6: 1397 | dependencies: 1398 | path-key: 3.1.1 1399 | shebang-command: 2.0.0 1400 | which: 2.0.2 1401 | 1402 | debug@4.4.1(supports-color@8.1.1): 1403 | dependencies: 1404 | ms: 2.1.3 1405 | optionalDependencies: 1406 | supports-color: 8.1.1 1407 | 1408 | decamelize@4.0.0: {} 1409 | 1410 | deep-eql@4.1.4: 1411 | dependencies: 1412 | type-detect: 4.1.0 1413 | 1414 | deep-is@0.1.4: {} 1415 | 1416 | diff@7.0.0: {} 1417 | 1418 | eastasianwidth@0.2.0: {} 1419 | 1420 | emoji-regex@8.0.0: {} 1421 | 1422 | emoji-regex@9.2.2: {} 1423 | 1424 | enhanced-resolve@5.18.1: 1425 | dependencies: 1426 | graceful-fs: 4.2.11 1427 | tapable: 2.2.2 1428 | 1429 | escalade@3.2.0: {} 1430 | 1431 | escape-string-regexp@4.0.0: {} 1432 | 1433 | eslint-compat-utils@0.5.1(eslint@9.28.0): 1434 | dependencies: 1435 | eslint: 9.28.0 1436 | semver: 7.7.2 1437 | 1438 | eslint-plugin-es-x@7.8.0(eslint@9.28.0): 1439 | dependencies: 1440 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) 1441 | '@eslint-community/regexpp': 4.12.1 1442 | eslint: 9.28.0 1443 | eslint-compat-utils: 0.5.1(eslint@9.28.0) 1444 | 1445 | eslint-plugin-jsdoc@50.7.1(eslint@9.28.0): 1446 | dependencies: 1447 | '@es-joy/jsdoccomment': 0.50.2 1448 | are-docs-informative: 0.0.2 1449 | comment-parser: 1.4.1 1450 | debug: 4.4.1(supports-color@8.1.1) 1451 | escape-string-regexp: 4.0.0 1452 | eslint: 9.28.0 1453 | espree: 10.4.0 1454 | esquery: 1.6.0 1455 | parse-imports-exports: 0.2.4 1456 | semver: 7.7.2 1457 | spdx-expression-parse: 4.0.0 1458 | transitivePeerDependencies: 1459 | - supports-color 1460 | 1461 | eslint-plugin-n@17.18.0(eslint@9.28.0): 1462 | dependencies: 1463 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) 1464 | enhanced-resolve: 5.18.1 1465 | eslint: 9.28.0 1466 | eslint-plugin-es-x: 7.8.0(eslint@9.28.0) 1467 | get-tsconfig: 4.10.1 1468 | globals: 15.15.0 1469 | ignore: 5.3.2 1470 | minimatch: 9.0.5 1471 | semver: 7.7.2 1472 | 1473 | eslint-plugin-redos@4.4.5(eslint@9.28.0): 1474 | dependencies: 1475 | eslint: 9.28.0 1476 | recheck: 4.4.5 1477 | 1478 | eslint-scope@8.4.0: 1479 | dependencies: 1480 | esrecurse: 4.3.0 1481 | estraverse: 5.3.0 1482 | 1483 | eslint-visitor-keys@3.4.3: {} 1484 | 1485 | eslint-visitor-keys@4.2.1: {} 1486 | 1487 | eslint@9.28.0: 1488 | dependencies: 1489 | '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) 1490 | '@eslint-community/regexpp': 4.12.1 1491 | '@eslint/config-array': 0.20.0 1492 | '@eslint/config-helpers': 0.2.2 1493 | '@eslint/core': 0.14.0 1494 | '@eslint/eslintrc': 3.3.1 1495 | '@eslint/js': 9.28.0 1496 | '@eslint/plugin-kit': 0.3.1 1497 | '@humanfs/node': 0.16.6 1498 | '@humanwhocodes/module-importer': 1.0.1 1499 | '@humanwhocodes/retry': 0.4.3 1500 | '@types/estree': 1.0.8 1501 | '@types/json-schema': 7.0.15 1502 | ajv: 6.12.6 1503 | chalk: 4.1.2 1504 | cross-spawn: 7.0.6 1505 | debug: 4.4.1(supports-color@8.1.1) 1506 | escape-string-regexp: 4.0.0 1507 | eslint-scope: 8.4.0 1508 | eslint-visitor-keys: 4.2.1 1509 | espree: 10.4.0 1510 | esquery: 1.6.0 1511 | esutils: 2.0.3 1512 | fast-deep-equal: 3.1.3 1513 | file-entry-cache: 8.0.0 1514 | find-up: 5.0.0 1515 | glob-parent: 6.0.2 1516 | ignore: 5.3.2 1517 | imurmurhash: 0.1.4 1518 | is-glob: 4.0.3 1519 | json-stable-stringify-without-jsonify: 1.0.1 1520 | lodash.merge: 4.6.2 1521 | minimatch: 3.1.2 1522 | natural-compare: 1.4.0 1523 | optionator: 0.9.4 1524 | transitivePeerDependencies: 1525 | - supports-color 1526 | 1527 | espree@10.4.0: 1528 | dependencies: 1529 | acorn: 8.15.0 1530 | acorn-jsx: 5.3.2(acorn@8.15.0) 1531 | eslint-visitor-keys: 4.2.1 1532 | 1533 | esquery@1.6.0: 1534 | dependencies: 1535 | estraverse: 5.3.0 1536 | 1537 | esrecurse@4.3.0: 1538 | dependencies: 1539 | estraverse: 5.3.0 1540 | 1541 | estraverse@5.3.0: {} 1542 | 1543 | esutils@2.0.3: {} 1544 | 1545 | fast-deep-equal@3.1.3: {} 1546 | 1547 | fast-glob@3.3.3: 1548 | dependencies: 1549 | '@nodelib/fs.stat': 2.0.5 1550 | '@nodelib/fs.walk': 1.2.8 1551 | glob-parent: 5.1.2 1552 | merge2: 1.4.1 1553 | micromatch: 4.0.8 1554 | 1555 | fast-json-stable-stringify@2.1.0: {} 1556 | 1557 | fast-levenshtein@2.0.6: {} 1558 | 1559 | fastq@1.19.1: 1560 | dependencies: 1561 | reusify: 1.1.0 1562 | 1563 | file-entry-cache@8.0.0: 1564 | dependencies: 1565 | flat-cache: 4.0.1 1566 | 1567 | fill-range@7.1.1: 1568 | dependencies: 1569 | to-regex-range: 5.0.1 1570 | 1571 | find-up@5.0.0: 1572 | dependencies: 1573 | locate-path: 6.0.0 1574 | path-exists: 4.0.0 1575 | 1576 | flat-cache@4.0.1: 1577 | dependencies: 1578 | flatted: 3.3.3 1579 | keyv: 4.5.4 1580 | 1581 | flat@5.0.2: {} 1582 | 1583 | flatted@3.3.3: {} 1584 | 1585 | foreground-child@3.3.1: 1586 | dependencies: 1587 | cross-spawn: 7.0.6 1588 | signal-exit: 4.1.0 1589 | 1590 | get-caller-file@2.0.5: {} 1591 | 1592 | get-func-name@2.0.2: {} 1593 | 1594 | get-tsconfig@4.10.1: 1595 | dependencies: 1596 | resolve-pkg-maps: 1.0.0 1597 | 1598 | glob-parent@5.1.2: 1599 | dependencies: 1600 | is-glob: 4.0.3 1601 | 1602 | glob-parent@6.0.2: 1603 | dependencies: 1604 | is-glob: 4.0.3 1605 | 1606 | glob@10.4.5: 1607 | dependencies: 1608 | foreground-child: 3.3.1 1609 | jackspeak: 3.4.3 1610 | minimatch: 9.0.5 1611 | minipass: 7.1.2 1612 | package-json-from-dist: 1.0.1 1613 | path-scurry: 1.11.1 1614 | 1615 | glob@11.0.2: 1616 | dependencies: 1617 | foreground-child: 3.3.1 1618 | jackspeak: 4.1.1 1619 | minimatch: 10.0.1 1620 | minipass: 7.1.2 1621 | package-json-from-dist: 1.0.1 1622 | path-scurry: 2.0.0 1623 | 1624 | globals@14.0.0: {} 1625 | 1626 | globals@15.15.0: {} 1627 | 1628 | globals@16.2.0: {} 1629 | 1630 | graceful-fs@4.2.11: {} 1631 | 1632 | graphemer@1.4.0: {} 1633 | 1634 | has-flag@4.0.0: {} 1635 | 1636 | he@1.2.0: {} 1637 | 1638 | html-escaper@2.0.2: {} 1639 | 1640 | ignore@5.3.2: {} 1641 | 1642 | ignore@7.0.5: {} 1643 | 1644 | import-fresh@3.3.1: 1645 | dependencies: 1646 | parent-module: 1.0.1 1647 | resolve-from: 4.0.0 1648 | 1649 | imurmurhash@0.1.4: {} 1650 | 1651 | is-extglob@2.1.1: {} 1652 | 1653 | is-fullwidth-code-point@3.0.0: {} 1654 | 1655 | is-glob@4.0.3: 1656 | dependencies: 1657 | is-extglob: 2.1.1 1658 | 1659 | is-number@7.0.0: {} 1660 | 1661 | is-plain-obj@2.1.0: {} 1662 | 1663 | is-unicode-supported@0.1.0: {} 1664 | 1665 | isexe@2.0.0: {} 1666 | 1667 | istanbul-lib-coverage@3.2.2: {} 1668 | 1669 | istanbul-lib-report@3.0.1: 1670 | dependencies: 1671 | istanbul-lib-coverage: 3.2.2 1672 | make-dir: 4.0.0 1673 | supports-color: 7.2.0 1674 | 1675 | istanbul-reports@3.1.7: 1676 | dependencies: 1677 | html-escaper: 2.0.2 1678 | istanbul-lib-report: 3.0.1 1679 | 1680 | jackspeak@3.4.3: 1681 | dependencies: 1682 | '@isaacs/cliui': 8.0.2 1683 | optionalDependencies: 1684 | '@pkgjs/parseargs': 0.11.0 1685 | 1686 | jackspeak@4.1.1: 1687 | dependencies: 1688 | '@isaacs/cliui': 8.0.2 1689 | 1690 | js-yaml@4.1.0: 1691 | dependencies: 1692 | argparse: 2.0.1 1693 | 1694 | jsdoc-type-pratt-parser@4.1.0: {} 1695 | 1696 | json-buffer@3.0.1: {} 1697 | 1698 | json-schema-traverse@0.4.1: {} 1699 | 1700 | json-stable-stringify-without-jsonify@1.0.1: {} 1701 | 1702 | keyv@4.5.4: 1703 | dependencies: 1704 | json-buffer: 3.0.1 1705 | 1706 | levn@0.4.1: 1707 | dependencies: 1708 | prelude-ls: 1.2.1 1709 | type-check: 0.4.0 1710 | 1711 | locate-path@6.0.0: 1712 | dependencies: 1713 | p-locate: 5.0.0 1714 | 1715 | lodash.merge@4.6.2: {} 1716 | 1717 | log-symbols@4.1.0: 1718 | dependencies: 1719 | chalk: 4.1.2 1720 | is-unicode-supported: 0.1.0 1721 | 1722 | loupe@2.3.7: 1723 | dependencies: 1724 | get-func-name: 2.0.2 1725 | 1726 | lru-cache@10.4.3: {} 1727 | 1728 | lru-cache@11.1.0: {} 1729 | 1730 | make-dir@4.0.0: 1731 | dependencies: 1732 | semver: 7.7.2 1733 | 1734 | merge2@1.4.1: {} 1735 | 1736 | micromatch@4.0.8: 1737 | dependencies: 1738 | braces: 3.0.3 1739 | picomatch: 2.3.1 1740 | 1741 | minimatch@10.0.1: 1742 | dependencies: 1743 | brace-expansion: 2.0.1 1744 | 1745 | minimatch@3.1.2: 1746 | dependencies: 1747 | brace-expansion: 1.1.11 1748 | 1749 | minimatch@9.0.5: 1750 | dependencies: 1751 | brace-expansion: 2.0.1 1752 | 1753 | minipass@7.1.2: {} 1754 | 1755 | mocha@11.6.0: 1756 | dependencies: 1757 | browser-stdout: 1.3.1 1758 | chokidar: 4.0.3 1759 | debug: 4.4.1(supports-color@8.1.1) 1760 | diff: 7.0.0 1761 | escape-string-regexp: 4.0.0 1762 | find-up: 5.0.0 1763 | glob: 10.4.5 1764 | he: 1.2.0 1765 | js-yaml: 4.1.0 1766 | log-symbols: 4.1.0 1767 | minimatch: 9.0.5 1768 | ms: 2.1.3 1769 | picocolors: 1.1.1 1770 | serialize-javascript: 6.0.2 1771 | strip-json-comments: 3.1.1 1772 | supports-color: 8.1.1 1773 | workerpool: 9.3.2 1774 | yargs: 17.7.2 1775 | yargs-parser: 21.1.1 1776 | yargs-unparser: 2.0.0 1777 | 1778 | ms@2.1.3: {} 1779 | 1780 | natural-compare@1.4.0: {} 1781 | 1782 | optionator@0.9.4: 1783 | dependencies: 1784 | deep-is: 0.1.4 1785 | fast-levenshtein: 2.0.6 1786 | levn: 0.4.1 1787 | prelude-ls: 1.2.1 1788 | type-check: 0.4.0 1789 | word-wrap: 1.2.5 1790 | 1791 | p-limit@3.1.0: 1792 | dependencies: 1793 | yocto-queue: 0.1.0 1794 | 1795 | p-locate@5.0.0: 1796 | dependencies: 1797 | p-limit: 3.1.0 1798 | 1799 | package-json-from-dist@1.0.1: {} 1800 | 1801 | parent-module@1.0.1: 1802 | dependencies: 1803 | callsites: 3.1.0 1804 | 1805 | parse-imports-exports@0.2.4: 1806 | dependencies: 1807 | parse-statements: 1.0.11 1808 | 1809 | parse-statements@1.0.11: {} 1810 | 1811 | path-exists@4.0.0: {} 1812 | 1813 | path-key@3.1.1: {} 1814 | 1815 | path-scurry@1.11.1: 1816 | dependencies: 1817 | lru-cache: 10.4.3 1818 | minipass: 7.1.2 1819 | 1820 | path-scurry@2.0.0: 1821 | dependencies: 1822 | lru-cache: 11.1.0 1823 | minipass: 7.1.2 1824 | 1825 | pathval@1.1.1: {} 1826 | 1827 | picocolors@1.1.1: {} 1828 | 1829 | picomatch@2.3.1: {} 1830 | 1831 | picomatch@4.0.2: {} 1832 | 1833 | prelude-ls@1.2.1: {} 1834 | 1835 | punycode@2.3.1: {} 1836 | 1837 | queue-microtask@1.2.3: {} 1838 | 1839 | randombytes@2.1.0: 1840 | dependencies: 1841 | safe-buffer: 5.2.1 1842 | 1843 | readdirp@4.1.2: {} 1844 | 1845 | recheck-jar@4.4.5: 1846 | optional: true 1847 | 1848 | recheck-linux-x64@4.4.5: 1849 | optional: true 1850 | 1851 | recheck-macos-x64@4.4.5: 1852 | optional: true 1853 | 1854 | recheck-windows-x64@4.4.5: 1855 | optional: true 1856 | 1857 | recheck@4.4.5: 1858 | optionalDependencies: 1859 | recheck-jar: 4.4.5 1860 | recheck-linux-x64: 4.4.5 1861 | recheck-macos-x64: 4.4.5 1862 | recheck-windows-x64: 4.4.5 1863 | 1864 | require-directory@2.1.1: {} 1865 | 1866 | resolve-from@4.0.0: {} 1867 | 1868 | resolve-pkg-maps@1.0.0: {} 1869 | 1870 | reusify@1.1.0: {} 1871 | 1872 | rimraf@6.0.1: 1873 | dependencies: 1874 | glob: 11.0.2 1875 | package-json-from-dist: 1.0.1 1876 | 1877 | run-parallel@1.2.0: 1878 | dependencies: 1879 | queue-microtask: 1.2.3 1880 | 1881 | safe-buffer@5.2.1: {} 1882 | 1883 | semver@7.7.2: {} 1884 | 1885 | serialize-javascript@6.0.2: 1886 | dependencies: 1887 | randombytes: 2.1.0 1888 | 1889 | shebang-command@2.0.0: 1890 | dependencies: 1891 | shebang-regex: 3.0.0 1892 | 1893 | shebang-regex@3.0.0: {} 1894 | 1895 | signal-exit@4.1.0: {} 1896 | 1897 | spdx-exceptions@2.5.0: {} 1898 | 1899 | spdx-expression-parse@4.0.0: 1900 | dependencies: 1901 | spdx-exceptions: 2.5.0 1902 | spdx-license-ids: 3.0.21 1903 | 1904 | spdx-license-ids@3.0.21: {} 1905 | 1906 | string-width@4.2.3: 1907 | dependencies: 1908 | emoji-regex: 8.0.0 1909 | is-fullwidth-code-point: 3.0.0 1910 | strip-ansi: 6.0.1 1911 | 1912 | string-width@5.1.2: 1913 | dependencies: 1914 | eastasianwidth: 0.2.0 1915 | emoji-regex: 9.2.2 1916 | strip-ansi: 7.1.0 1917 | 1918 | strip-ansi@6.0.1: 1919 | dependencies: 1920 | ansi-regex: 5.0.1 1921 | 1922 | strip-ansi@7.1.0: 1923 | dependencies: 1924 | ansi-regex: 6.1.0 1925 | 1926 | strip-json-comments@3.1.1: {} 1927 | 1928 | supports-color@7.2.0: 1929 | dependencies: 1930 | has-flag: 4.0.0 1931 | 1932 | supports-color@8.1.1: 1933 | dependencies: 1934 | has-flag: 4.0.0 1935 | 1936 | tapable@2.2.2: {} 1937 | 1938 | test-exclude@7.0.1: 1939 | dependencies: 1940 | '@istanbuljs/schema': 0.1.3 1941 | glob: 10.4.5 1942 | minimatch: 9.0.5 1943 | 1944 | to-regex-range@5.0.1: 1945 | dependencies: 1946 | is-number: 7.0.0 1947 | 1948 | ts-api-utils@2.1.0(typescript@5.8.3): 1949 | dependencies: 1950 | typescript: 5.8.3 1951 | 1952 | type-check@0.4.0: 1953 | dependencies: 1954 | prelude-ls: 1.2.1 1955 | 1956 | type-detect@4.1.0: {} 1957 | 1958 | typescript-eslint@8.34.0(eslint@9.28.0)(typescript@5.8.3): 1959 | dependencies: 1960 | '@typescript-eslint/eslint-plugin': 8.34.0(@typescript-eslint/parser@8.34.0(eslint@9.28.0)(typescript@5.8.3))(eslint@9.28.0)(typescript@5.8.3) 1961 | '@typescript-eslint/parser': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1962 | '@typescript-eslint/utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3) 1963 | eslint: 9.28.0 1964 | typescript: 5.8.3 1965 | transitivePeerDependencies: 1966 | - supports-color 1967 | 1968 | typescript@5.8.3: {} 1969 | 1970 | undici-types@6.21.0: {} 1971 | 1972 | uri-js@4.4.1: 1973 | dependencies: 1974 | punycode: 2.3.1 1975 | 1976 | v8-to-istanbul@9.3.0: 1977 | dependencies: 1978 | '@jridgewell/trace-mapping': 0.3.25 1979 | '@types/istanbul-lib-coverage': 2.0.6 1980 | convert-source-map: 2.0.0 1981 | 1982 | which@2.0.2: 1983 | dependencies: 1984 | isexe: 2.0.0 1985 | 1986 | word-wrap@1.2.5: {} 1987 | 1988 | workerpool@9.3.2: {} 1989 | 1990 | wrap-ansi@7.0.0: 1991 | dependencies: 1992 | ansi-styles: 4.3.0 1993 | string-width: 4.2.3 1994 | strip-ansi: 6.0.1 1995 | 1996 | wrap-ansi@8.1.0: 1997 | dependencies: 1998 | ansi-styles: 6.2.1 1999 | string-width: 5.1.2 2000 | strip-ansi: 7.1.0 2001 | 2002 | y18n@5.0.8: {} 2003 | 2004 | yargs-parser@21.1.1: {} 2005 | 2006 | yargs-unparser@2.0.0: 2007 | dependencies: 2008 | camelcase: 6.3.0 2009 | decamelize: 4.0.0 2010 | flat: 5.0.2 2011 | is-plain-obj: 2.1.0 2012 | 2013 | yargs@17.7.2: 2014 | dependencies: 2015 | cliui: 8.0.1 2016 | escalade: 3.2.0 2017 | get-caller-file: 2.0.5 2018 | require-directory: 2.1.1 2019 | string-width: 4.2.3 2020 | y18n: 5.0.8 2021 | yargs-parser: 21.1.1 2022 | 2023 | yocto-queue@0.1.0: {} 2024 | -------------------------------------------------------------------------------- /src/cli.test.ts: -------------------------------------------------------------------------------- 1 | import 'chai/register-should.js'; 2 | import type {Props} from './index.js'; 3 | import cli from './cli.js'; 4 | 5 | interface Results { 6 | props?: Props[]; 7 | stdout: string; 8 | stderr: string; 9 | err?: unknown; 10 | } 11 | 12 | async function exec(...args: string[]): Promise { 13 | const out: string[] = []; 14 | const err: string[] = []; 15 | 16 | const res: Results = { 17 | stdout: '', 18 | stderr: '', 19 | }; 20 | 21 | try { 22 | res.props = await cli(['node', 'editorconfig', ...args], { 23 | writeOut(s: string) { 24 | out.push(s); 25 | }, 26 | writeErr(s: string) { 27 | err.push(s); 28 | }, 29 | }); 30 | } catch (er) { 31 | res.err = er; 32 | } 33 | if (out.length) { 34 | res.stdout = out.join(''); 35 | } 36 | if (err.length) { 37 | res.stderr = err.join(''); 38 | } 39 | return res; 40 | } 41 | 42 | describe('Command line interface', () => { 43 | it('helps', async() => { 44 | const res = await exec('--help'); 45 | res.stdout.should.match(/^Usage:/); 46 | }); 47 | 48 | it('Lists files', async() => { 49 | const res = await exec('foo.md', '--files'); 50 | res.stdout.trim().should.match(/\.editorconfig \[\*\.md\]$/); 51 | }); 52 | 53 | it('Lists multiple files', async() => { 54 | const res = await exec('foo.md', 'bar.js', '--files'); 55 | res.stdout.should.match(/^\[foo\.md\]/); 56 | res.stdout.trim().should.match(/\.editorconfig \[\*\]$/); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /src/cli.ts: -------------------------------------------------------------------------------- 1 | import * as editorconfig from './index.js'; 2 | import {Command, type OutputConfiguration} from 'commander'; 3 | import pkg from '../package.json'; 4 | 5 | /** 6 | * Default output routine, goes to stdout. 7 | * 8 | * @param s String to output 9 | */ 10 | function writeStdOut(s: string): void { 11 | process.stdout.write(s); 12 | } 13 | 14 | /** 15 | * Command line interface for editorconfig. Pulled out into a separate module 16 | * to make it easier to test. 17 | * 18 | * @param args Usually process.argv. Note that the first two parameters are 19 | * usually 'node' and 'editorconfig' 20 | * @param testing If testing, you may pass in a Commander OutputConfiguration 21 | * so that you can capture stdout and stderror. If `testing` is provided, 22 | * this routine will throw an error instead of calling `process.exit`. 23 | * @returns An array of combined properties, one for each file argument. 24 | */ 25 | export default async function cli( 26 | args: string[], 27 | testing?: OutputConfiguration 28 | ): Promise { 29 | const program = new Command(); 30 | 31 | let writeOut = writeStdOut; 32 | 33 | if (testing) { 34 | if (testing.writeOut) { 35 | ({writeOut} = testing); 36 | } 37 | program.configureOutput(testing); 38 | program.exitOverride(); 39 | } 40 | 41 | program.version( 42 | `EditorConfig Node.js Core Version ${pkg.version}`, 43 | '-v, --version', 44 | 'Display version information' 45 | ) 46 | .showHelpAfterError() 47 | .argument( 48 | '', 49 | 'Files to find configuration for. Can be a hyphen (-) if you want path(s) to be read from stdin.' 50 | ) 51 | .option('-f ', 'Specify conf filename other than \'.editorconfig\'') 52 | .option('-b ', 'Specify version (used by devs to test compatibility)') 53 | .option('--files', 'Output file names that contributed to the configuration, rather than the configuation itself') 54 | .option('--unset', 'Remove all properties whose final value is \'unset\'') 55 | .parse(args); 56 | 57 | const files = program.args; 58 | const opts = program.opts(); 59 | const cache = new Map(); 60 | const visited = opts.files ? 61 | files.map(() => []) : 62 | undefined; 63 | 64 | // Process sequentially so caching works 65 | async function processAll(): Promise { 66 | const p = []; 67 | let i = 0; 68 | for (const filePath of files) { 69 | p.push(await editorconfig.parse(filePath, { 70 | config: opts.f as string, 71 | version: opts.b as string, 72 | files: visited ? visited[i++] : undefined, 73 | cache, 74 | unset: Boolean(opts.unset), 75 | })); 76 | } 77 | return p; 78 | } 79 | 80 | return processAll().then(parsed => { 81 | const header = parsed.length > 1; 82 | parsed.forEach((props, i) => { 83 | if (header) { 84 | writeOut(`[${files[i]}]\n`); 85 | } 86 | if (visited) { 87 | for (const v of visited[i]) { 88 | writeOut(`${v.fileName} [${v.glob}]\n`); 89 | } 90 | } else { 91 | for (const [key, value] of Object.entries(props)) { 92 | writeOut(`${key}=${String(value)}\n`); 93 | } 94 | } 95 | }); 96 | return parsed; 97 | }); 98 | } 99 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-deprecated */ 2 | import 'chai/register-should.js'; 3 | import * as editorconfig from './index.js'; 4 | import * as fs from 'node:fs'; 5 | import * as path from 'node:path'; 6 | import {Buffer} from 'node:buffer'; 7 | 8 | describe('parse', () => { 9 | const expected: editorconfig.Props = { 10 | indent_style: 'space', 11 | indent_size: 2, 12 | end_of_line: 'lf', 13 | charset: 'utf-8', 14 | trim_trailing_whitespace: true, 15 | insert_final_newline: true, 16 | tab_width: 2, 17 | block_comment: '*', 18 | block_comment_end: '*/', 19 | block_comment_start: '/**', 20 | }; 21 | const target = path.join(__dirname, '/app.js'); 22 | 23 | it('async', async() => { 24 | const cfg = await editorconfig.parse(target); 25 | cfg.should.eql(expected); 26 | }); 27 | 28 | it('sync', () => { 29 | const visited: editorconfig.Visited[] = []; 30 | const cfg = editorconfig.parseSync(target, {files: visited}); 31 | cfg.should.eql(expected); 32 | visited.should.have.lengthOf(1); 33 | visited[0].glob.should.eql('*'); 34 | visited[0].fileName.should.match(/\.editorconfig$/); 35 | }); 36 | 37 | it('caches', async() => { 38 | const cache = new Map(); 39 | const cfg = await editorconfig.parse(target, {cache}); 40 | cfg.should.eql(expected); 41 | cache.size.should.be.eql(2); 42 | await editorconfig.parse(target, {cache}); 43 | cache.size.should.be.eql(2); 44 | }); 45 | 46 | it('caches sync', () => { 47 | const cache = new Map(); 48 | const cfg = editorconfig.parseSync(target, {cache}); 49 | cfg.should.eql(expected); 50 | cache.size.should.be.eql(2); 51 | editorconfig.parseSync(target, {cache}); 52 | cache.size.should.be.eql(2); 53 | }); 54 | }); 55 | 56 | describe('parseFromFiles', () => { 57 | const expected: editorconfig.Props = { 58 | block_comment_end: '*/', 59 | block_comment_start: '/**', 60 | block_comment: '*', 61 | charset: 'utf-8', 62 | end_of_line: 'lf', 63 | indent_size: 2, 64 | indent_style: 'space', 65 | insert_final_newline: true, 66 | tab_width: 2, 67 | trim_trailing_whitespace: true, 68 | }; 69 | const configs: editorconfig.ECFile[] = []; 70 | const configPath = path.resolve(__dirname, '../.editorconfig'); 71 | configs.push({ 72 | name: configPath, 73 | contents: fs.readFileSync(configPath), 74 | }); 75 | const target = path.join(__dirname, '/app.js'); 76 | const configs2 = [ 77 | {name: 'early', contents: Buffer.alloc(0)}, 78 | configs[0], 79 | ]; 80 | 81 | it('async', async() => { 82 | const cfg: editorconfig.Props = 83 | await editorconfig.parseFromFiles(target, Promise.resolve(configs)); 84 | cfg.should.eql(expected); 85 | }); 86 | 87 | it('sync', () => { 88 | const cfg = editorconfig.parseFromFilesSync(target, configs); 89 | cfg.should.eql(expected); 90 | }); 91 | 92 | it('handles null', () => { 93 | const cfg = editorconfig.parseFromFilesSync(target, [{ 94 | name: configPath, 95 | contents: Buffer.from('[*]\nfoo = null\n'), 96 | }]); 97 | cfg.should.eql({foo: 'null'}); 98 | }); 99 | 100 | it('caches async', async() => { 101 | const cache = new Map(); 102 | const cfg = await editorconfig.parseFromFiles( 103 | target, Promise.resolve(configs2), {cache} 104 | ); 105 | cfg.should.eql(expected); 106 | cache.size.should.be.eql(2); 107 | const cfg2 = await editorconfig.parseFromFiles( 108 | target, Promise.resolve(configs2), {cache} 109 | ); 110 | cfg2.should.eql(expected); 111 | cache.size.should.be.eql(2); 112 | }); 113 | 114 | it('caches sync', () => { 115 | const cache = new Map(); 116 | const cfg = editorconfig.parseFromFilesSync( 117 | target, configs2, {cache} 118 | ); 119 | cfg.should.eql(expected); 120 | cache.size.should.be.eql(2); 121 | const cfg2 = editorconfig.parseFromFilesSync( 122 | target, configs2, {cache} 123 | ); 124 | cfg2.should.eql(expected); 125 | cache.size.should.be.eql(2); 126 | }); 127 | 128 | it('handles minimatch escapables', () => { 129 | // Note that this `#` does not actually test the /^#/ escaping logic, 130 | // because this path will go through a `path.dirname` before that happens. 131 | // It's here to catch what would happen if minimatch started to treat # 132 | // differently inside a pattern. 133 | const bogusPath = path.resolve(__dirname, '#?*+@!()|[]{}'); 134 | const escConfigs: editorconfig.ECFile[] = [ 135 | { 136 | name: `${bogusPath}/.editorconfig`, 137 | contents: configs[0].contents, 138 | }, 139 | ]; 140 | const escTarget = `${bogusPath}/app.js`; 141 | const cfg = editorconfig.parseFromFilesSync(escTarget, escConfigs); 142 | cfg.should.eql(expected); 143 | }); 144 | }); 145 | 146 | describe('parseString', () => { 147 | const expected: editorconfig.ParseStringResult = [ 148 | [null, {root: 'true'}], 149 | ['*', { 150 | block_comment_end: '*/', 151 | block_comment_start: '/**', 152 | block_comment: '*', 153 | charset: 'utf-8', 154 | end_of_line: 'lf', 155 | indent_size: '2', 156 | indent_style: 'space', 157 | insert_final_newline: 'true', 158 | trim_trailing_whitespace: 'true', 159 | }], 160 | ['*.md', {indent_size: '4'}], 161 | ]; 162 | 163 | const configPath = path.resolve(__dirname, '../.editorconfig'); 164 | const contents = fs.readFileSync(configPath, 'utf8'); 165 | 166 | it('sync', () => { 167 | const cfg = editorconfig.parseString(contents); 168 | cfg.should.eql(expected); 169 | }); 170 | 171 | it('handles errors', () => { 172 | const cfg = editorconfig.parseString('root: '); 173 | cfg.should.eql([[null, {}]]); 174 | }); 175 | 176 | it('handles backslashes in glob', () => { 177 | const cfg = editorconfig.parseString('[a\\\\b]'); 178 | cfg.should.eql([[null, {}], ['a\\\\b', {}]]); 179 | }); 180 | 181 | it('handles blank comments', () => { 182 | const cfg = editorconfig.parseString('#'); 183 | cfg.should.eql([[null, {}]]); 184 | }); 185 | }); 186 | 187 | describe('extra behavior', () => { 188 | it('handles extended globs', () => { 189 | // These failed when we had noext: true in matchOptions 190 | const matcher = editorconfig.matcher({ 191 | root: __dirname, 192 | }, Buffer.from(`\ 193 | [*] 194 | indent_size = 4 195 | 196 | [!(package).json] 197 | indent_size = 3`)); 198 | 199 | matcher(path.join(__dirname, 'package.json')).should.include({indent_size: 4}); 200 | matcher(path.join(__dirname, 'foo.json')).should.include({indent_size: 3}); 201 | }); 202 | }); 203 | 204 | describe('unset', () => { 205 | it('pair witht the value `unset`', () => { 206 | const matcher = editorconfig.matcher({ 207 | root: __dirname, 208 | unset: true, 209 | }, Buffer.from(`\ 210 | [*] 211 | indent_size = 4 212 | 213 | [*.json] 214 | indent_size = unset 215 | `)); 216 | matcher(path.join(__dirname, 'index.js')).should.include({indent_size: 4}); 217 | matcher(path.join(__dirname, 'index.json')).should.be.eql({ }); 218 | }); 219 | }); 220 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'node:fs'; 2 | import * as path from 'node:path'; 3 | import * as semver from 'semver'; 4 | 5 | import {TokenTypes, parse_to_uint32array} from '@one-ini/wasm'; 6 | import {Buffer} from 'node:buffer'; 7 | import {Minimatch} from 'minimatch'; 8 | 9 | import pkg from '../package.json'; 10 | 11 | const escapedSep = new RegExp(path.sep.replace(/\\/g, '\\\\'), 'g'); 12 | const matchOptions = {matchBase: true, dot: true}; 13 | 14 | // These are specified by the editorconfig script 15 | export interface KnownProps { 16 | end_of_line?: 'lf' | 'crlf' | 'unset'; 17 | indent_style?: 'tab' | 'space' | 'unset'; 18 | indent_size?: number | 'tab' | 'unset'; 19 | insert_final_newline?: true | false | 'unset'; 20 | tab_width?: number | 'unset'; 21 | trim_trailing_whitespace?: true | false | 'unset'; 22 | charset?: 'latin1' | 'utf-8' | 'utf-8-bom' | 'utf-16be' | 'utf-16le' | 'unset'; 23 | } 24 | 25 | interface UnknownMap { 26 | [index: string]: unknown; 27 | } 28 | export type Props = KnownProps & UnknownMap; 29 | 30 | export interface ECFile { 31 | name: string; 32 | contents?: Buffer; 33 | } 34 | 35 | type SectionGlob = Minimatch | null; 36 | type GlobbedProps = [SectionName, Props, SectionGlob][]; 37 | 38 | export interface ProcessedFileConfig { 39 | root: boolean; 40 | name: string; 41 | config: GlobbedProps; 42 | notfound?: true; 43 | } 44 | 45 | export interface Visited { 46 | fileName: string; 47 | glob: string; 48 | } 49 | 50 | export interface Cache { 51 | get(path: string): ProcessedFileConfig | undefined; 52 | set(path: string, config: ProcessedFileConfig): this; 53 | } 54 | 55 | export interface ParseOptions { 56 | config?: string; 57 | version?: string; 58 | root?: string; 59 | files?: Visited[]; 60 | cache?: Cache; 61 | unset?: boolean; 62 | } 63 | 64 | const knownPropNames: (keyof KnownProps)[] = [ 65 | 'end_of_line', 66 | 'indent_style', 67 | 'indent_size', 68 | 'insert_final_newline', 69 | 'trim_trailing_whitespace', 70 | 'charset', 71 | ]; 72 | const knownProps = new Set(knownPropNames); 73 | 74 | export type SectionName = string | null; 75 | export interface SectionBody { 76 | [key: string]: string; 77 | } 78 | export type ParseStringResult = [SectionName, SectionBody][]; 79 | 80 | /** 81 | * Parse a buffer using the faster one-ini WASM approach into something 82 | * relatively easy to deal with in JS. 83 | * 84 | * @param data UTF8-encoded bytes. 85 | * @returns Parsed contents. Will be truncated if there was a parse error. 86 | */ 87 | export function parseBuffer(data: Buffer): ParseStringResult { 88 | const parsed = parse_to_uint32array(data); 89 | let cur: SectionBody = {}; 90 | const res: ParseStringResult = [[null, cur]]; 91 | let key: string | null = null; 92 | 93 | for (let i = 0; i < parsed.length; i += 3) { 94 | switch (parsed[i] as TokenTypes) { 95 | case TokenTypes.Section: { 96 | cur = {}; 97 | res.push([ 98 | data.toString('utf8', parsed[i + 1], parsed[i + 2]), 99 | cur, 100 | ]); 101 | break; 102 | } 103 | case TokenTypes.Key: 104 | key = data.toString('utf8', parsed[i + 1], parsed[i + 2]); 105 | break; 106 | case TokenTypes.Value: { 107 | cur[key as string] = data.toString('utf8', parsed[i + 1], parsed[i + 2]); 108 | break; 109 | } 110 | default: // Comments, etc. 111 | break; 112 | } 113 | } 114 | return res; 115 | } 116 | 117 | /** 118 | * Parses a string. If possible, you should always use ParseBuffer instead, 119 | * since this function does a UTF16-to-UTF8 conversion first. 120 | * 121 | * @param data String to parse. 122 | * @returns Parsed contents. Will be truncated if there was a parse error. 123 | * @deprecated Use {@link ParseBuffer} instead. 124 | */ 125 | export function parseString(data: string): ParseStringResult { 126 | return parseBuffer(Buffer.from(data)); 127 | } 128 | 129 | /** 130 | * Gets a list of *potential* filenames based on the path of the target 131 | * filename. 132 | * 133 | * @param filepath File we are asking about. 134 | * @param options Config file name and root directory 135 | * @returns List of potential fully-qualified filenames that might have configs. 136 | */ 137 | function getConfigFileNames(filepath: string, options: ParseOptions): string[] { 138 | const paths = []; 139 | do { 140 | filepath = path.dirname(filepath); 141 | paths.push(path.join(filepath, options.config as string)); 142 | } while (filepath !== options.root); 143 | return paths; 144 | } 145 | 146 | /** 147 | * Take a combined config for the target file, and tweak it slightly based on 148 | * which editorconfig version's rules we are using. 149 | * 150 | * @param matches Combined config. 151 | * @param version Editorconfig version to enforce. 152 | * @returns The passed-in matches object, modified in place. 153 | */ 154 | function processMatches(matches: Props, version: string): Props { 155 | // Set indent_size to 'tab' if indent_size is unspecified and 156 | // indent_style is set to 'tab'. 157 | if ( 158 | 'indent_style' in matches && 159 | matches.indent_style === 'tab' && 160 | !('indent_size' in matches) && 161 | semver.gte(version, '0.10.0') 162 | ) { 163 | matches.indent_size = 'tab'; 164 | } 165 | 166 | // Set tab_width to indent_size if indent_size is specified and 167 | // tab_width is unspecified 168 | if ( 169 | 'indent_size' in matches && 170 | !('tab_width' in matches) && 171 | matches.indent_size !== 'tab' 172 | ) { 173 | matches.tab_width = matches.indent_size; 174 | } 175 | 176 | // Set indent_size to tab_width if indent_size is 'tab' 177 | if ( 178 | 'indent_size' in matches && 179 | 'tab_width' in matches && 180 | matches.indent_size === 'tab' 181 | ) { 182 | matches.indent_size = matches.tab_width; 183 | } 184 | 185 | return matches; 186 | } 187 | 188 | function buildFullGlob(pathPrefix: string, glob: string): Minimatch { 189 | switch (glob.indexOf('/')) { 190 | case -1: 191 | glob = `**/${glob}`; 192 | break; 193 | case 0: 194 | glob = glob.substring(1); 195 | break; 196 | default: 197 | break; 198 | } 199 | // 200 | // braces_escaped_backslash2 201 | // backslash_not_on_windows 202 | glob = glob.replace(/\\\\/g, '\\\\\\\\'); 203 | // 204 | // star_star_over_separator{1,3,5,6,9,15} 205 | glob = glob.replace(/\*\*/g, '{*,**/**/**}'); 206 | 207 | // NOT path.join. Must stay in forward slashes. 208 | return new Minimatch(`${pathPrefix}/${glob}`, matchOptions); 209 | } 210 | 211 | /** 212 | * Normalize the properties read from a config file so that their key names 213 | * are lowercased for the known properties, and their values are parsed into 214 | * the correct JS types if possible. 215 | * 216 | * @param options 217 | * @returns 218 | */ 219 | function normalizeProps(options: SectionBody): Props { 220 | const props: Props = {}; 221 | for (const key in options) { 222 | if (Object.prototype.hasOwnProperty.call(options, key)) { 223 | const value = options[key]; 224 | const key2 = key.toLowerCase(); 225 | let value2: unknown = value; 226 | if (knownProps.has(key2)) { 227 | // All of the values for the known props are lowercase. 228 | value2 = String(value).toLowerCase(); 229 | } 230 | try { 231 | value2 = JSON.parse(String(value)); 232 | } catch (_e) { 233 | // Ignored 234 | } 235 | if (typeof value2 === 'undefined' || value2 === null) { 236 | // 237 | // null and undefined are values specific to JSON (no special meaning 238 | // in editorconfig) & should just be returned as regular strings. 239 | value2 = String(value); 240 | } 241 | props[key2] = value2; 242 | } 243 | } 244 | return props; 245 | } 246 | 247 | /** 248 | * Take the contents of a config file, and prepare it for use. If a cache is 249 | * provided, the result will be stored there. As such, all of the higher-CPU 250 | * work that is per-file should be done here. 251 | * 252 | * @param filepath The fully-qualified path of the file. 253 | * @param contents The contents as read from that file. 254 | * @param options Access to the cache. 255 | * @returns Processed file with globs pre-computed. 256 | */ 257 | function processFileContents( 258 | filepath: string, 259 | contents: Buffer | undefined, 260 | options: ParseOptions 261 | ): ProcessedFileConfig { 262 | let res: ProcessedFileConfig | undefined = undefined; 263 | // eslint-disable-next-line no-negated-condition 264 | if (!contents) { 265 | // Negative cache 266 | res = { 267 | root: false, 268 | notfound: true, 269 | name: filepath, 270 | config: [[null, {}, null]], 271 | }; 272 | } else { 273 | let pathPrefix = path.dirname(filepath); 274 | 275 | if (path.sep !== '/') { 276 | // Windows-only 277 | pathPrefix = pathPrefix.replace(escapedSep, '/'); 278 | } 279 | 280 | // After Windows path backslash's are turned into slashes, so that 281 | // the backslashes we add here aren't turned into forward slashes: 282 | 283 | // All of these characters are special to minimatch, but can be 284 | // forced into path names on many file systems. Escape them. Note 285 | // that these are in the order of the case statement in minimatch. 286 | pathPrefix = pathPrefix.replace(/[?*+@!()|[\]{}]/g, '\\$&'); 287 | // I can't think of a way for this to happen in the filesystems I've 288 | // seen (because of the path.dirname above), but let's be thorough. 289 | pathPrefix = pathPrefix.replace(/^#/, '\\#'); 290 | 291 | const globbed: GlobbedProps = parseBuffer(contents).map(([name, body]) => [ 292 | name, 293 | normalizeProps(body), 294 | name ? buildFullGlob(pathPrefix, name) : null, 295 | ]); 296 | 297 | res = { 298 | root: Boolean(globbed[0][1].root), // Global section: globbed[0] 299 | name: filepath, 300 | config: globbed, 301 | }; 302 | } 303 | if (options.cache) { 304 | options.cache.set(filepath, res); 305 | } 306 | return res; 307 | } 308 | 309 | /** 310 | * Get a file from the cache, or read its contents from disk, process, and 311 | * insert into the cache (if configured). 312 | * 313 | * @param filepath The fully-qualified path of the config file. 314 | * @param options Access to the cache, if configured. 315 | * @returns The processed file, or undefined if there was an error reading it. 316 | */ 317 | async function getConfig( 318 | filepath: string, 319 | options: ParseOptions 320 | ): Promise { 321 | if (options.cache) { 322 | const cached = options.cache.get(filepath); 323 | if (cached) { 324 | return cached; 325 | } 326 | } 327 | const contents = await new Promise(resolve => { 328 | fs.readFile(filepath, (_, buf) => { 329 | // Ignore errors. contents will be undefined 330 | // Perhaps only file-not-found should be ignored? 331 | resolve(buf); 332 | }); 333 | }); 334 | return processFileContents(filepath, contents, options); 335 | } 336 | 337 | /** 338 | * Get a file from the cache, or read its contents from disk, process, and 339 | * insert into the cache (if configured). Synchronous. 340 | * 341 | * @param filepath The fully-qualified path of the config file. 342 | * @param options Access to the cache, if configured. 343 | * @returns The processed file, or undefined if there was an error reading it. 344 | */ 345 | function getConfigSync( 346 | filepath: string, 347 | options: ParseOptions 348 | ): ProcessedFileConfig { 349 | if (options.cache) { 350 | const cached = options.cache.get(filepath); 351 | if (cached) { 352 | return cached; 353 | } 354 | } 355 | let contents: Buffer | undefined = undefined; 356 | try { 357 | contents = fs.readFileSync(filepath); 358 | } catch (_) { 359 | // Ignore errors 360 | // Perhaps only file-not-found should be ignored 361 | } 362 | return processFileContents(filepath, contents, options); 363 | } 364 | 365 | /** 366 | * Get all of the possibly-existing config files, stopping when one is marked 367 | * root=true. 368 | * 369 | * @param files List of potential files 370 | * @param options Access to cache if configured 371 | * @returns List of processed configs for existing files 372 | */ 373 | async function getAllConfigs( 374 | files: string[], 375 | options: ParseOptions 376 | ): Promise { 377 | const configs: ProcessedFileConfig[] = []; 378 | for (const file of files) { 379 | const config = await getConfig(file, options); 380 | if (!config.notfound) { 381 | configs.push(config); 382 | if (config.root) { 383 | break; 384 | } 385 | } 386 | } 387 | return configs; 388 | } 389 | 390 | /** 391 | * Get all of the possibly-existing config files, stopping when one is marked 392 | * root=true. Synchronous. 393 | * 394 | * @param files List of potential files 395 | * @param options Access to cache if configured 396 | * @returns List of processed configs for existing files 397 | */ 398 | function getAllConfigsSync( 399 | files: string[], 400 | options: ParseOptions 401 | ): ProcessedFileConfig[] { 402 | const configs: ProcessedFileConfig[] = []; 403 | for (const file of files) { 404 | const config = getConfigSync(file, options); 405 | if (!config.notfound) { 406 | configs.push(config); 407 | if (config.root) { 408 | break; 409 | } 410 | } 411 | } 412 | return configs; 413 | } 414 | 415 | /** 416 | * Normalize the options passed in to the publicly-visible functions. 417 | * 418 | * @param filepath The name of the target file, relative to process.cwd(). 419 | * @param options Potentially-incomplete options. 420 | * @returns The fully-qualified target file name and the normalized options. 421 | */ 422 | function opts(filepath: string, options: ParseOptions = {}): [ 423 | fileName: string, 424 | normalizedOptions: ParseOptions, 425 | ] { 426 | const resolvedFilePath = path.resolve(filepath); 427 | return [ 428 | resolvedFilePath, 429 | { 430 | config: options.config || '.editorconfig', 431 | version: options.version || pkg.version, 432 | root: path.resolve(options.root || path.parse(resolvedFilePath).root), 433 | files: options.files, 434 | cache: options.cache, 435 | unset: options.unset, 436 | }, 437 | ]; 438 | } 439 | 440 | /** 441 | * For any pair, a value of `unset` removes the effect of that pair, even if 442 | * it has been set before. This method modifies the properties object in 443 | * place to remove any property that has a value of `unset`. 444 | * 445 | * @param props Properties object to modify. 446 | */ 447 | export function unset(props: Props): void { 448 | const keys = Object.keys(props); 449 | for (const k of keys) { 450 | if (props[k] === 'unset') { 451 | // eslint-disable-next-line @typescript-eslint/no-dynamic-delete 452 | delete props[k]; 453 | } 454 | } 455 | } 456 | 457 | /** 458 | * Combine the pre-parsed results of all matching config file sections, in 459 | * order. 460 | * 461 | * @param filepath The target file path 462 | * @param configs All of the found config files, up to the root 463 | * @param options Adds to `options.files` if it exists 464 | * @returns Combined properties 465 | */ 466 | function combine( 467 | filepath: string, 468 | configs: ProcessedFileConfig[], 469 | options: ParseOptions 470 | ): Props { 471 | const ret = configs.reverse().reduce((props: Props, processed) => { 472 | for (const [name, body, glob] of processed.config) { 473 | if (glob?.match(filepath)) { 474 | Object.assign(props, body); 475 | if (options.files) { 476 | options.files.push({ 477 | fileName: processed.name, 478 | glob: name as string, 479 | }); 480 | } 481 | } 482 | } 483 | return props; 484 | }, {}); 485 | 486 | if (options.unset) { 487 | unset(ret); 488 | } 489 | 490 | return processMatches(ret, options.version as string); 491 | } 492 | 493 | /** 494 | * Low-level interface, which exists only for backward-compatibility. 495 | * Deprecated. 496 | * 497 | * @param filepath The name of the target file, relative to process.cwd(). 498 | * @param files A list of objects describing the files. 499 | * @param options All options 500 | * @returns The properties found for filepath 501 | * @deprecated 502 | */ 503 | export function parseFromFilesSync( 504 | filepath: string, 505 | files: ECFile[], 506 | options: ParseOptions = {} 507 | ): Props { 508 | const [resolvedFilePath, processedOptions] = opts(filepath, options); 509 | const configs = []; 510 | for (const ecf of files) { 511 | let cfg: ProcessedFileConfig | undefined = undefined; 512 | if (!options.cache || !(cfg = options.cache.get(ecf.name))) { // Single "="! 513 | cfg = processFileContents(ecf.name, ecf.contents, processedOptions); 514 | } 515 | if (!cfg.notfound) { 516 | configs.push(cfg); 517 | } 518 | if (cfg.root) { 519 | break; 520 | } 521 | } 522 | 523 | return combine(resolvedFilePath, configs, processedOptions); 524 | } 525 | 526 | /** 527 | * Low-level interface, which exists only for backward-compatibility. 528 | * Deprecated. 529 | * 530 | * @param filepath The name of the target file, relative to process.cwd(). 531 | * @param files A promise for a list of objects describing the files. 532 | * @param options All options 533 | * @returns The properties found for filepath 534 | * @deprecated 535 | */ 536 | export async function parseFromFiles( 537 | filepath: string, 538 | files: Promise, 539 | options: ParseOptions = {} 540 | ): Promise { 541 | // eslint-disable-next-line @typescript-eslint/no-deprecated 542 | return parseFromFilesSync(filepath, await files, options); 543 | } 544 | 545 | /** 546 | * Find all of the properties from matching sections in config files in the 547 | * same directory or toward the root of the filesystem. 548 | * 549 | * @param filepath The target file name, relative to process.cwd(). 550 | * @param options All options 551 | * @returns Combined properties for the target file 552 | */ 553 | export async function parse( 554 | filepath: string, 555 | options: ParseOptions = {} 556 | ): Promise { 557 | const [resolvedFilePath, processedOptions] = opts(filepath, options); 558 | const filepaths = getConfigFileNames(resolvedFilePath, processedOptions); 559 | const configs = await getAllConfigs(filepaths, processedOptions); 560 | return combine(resolvedFilePath, configs, processedOptions); 561 | } 562 | 563 | /** 564 | * Find all of the properties from matching sections in config files in the 565 | * same directory or toward the root of the filesystem. Synchronous. 566 | * 567 | * @param filepath The target file name, relative to process.cwd(). 568 | * @param options All options 569 | * @returns Combined properties for the target file 570 | */ 571 | export function parseSync( 572 | filepath: string, 573 | options: ParseOptions = {} 574 | ): Props { 575 | const [resolvedFilePath, processedOptions] = opts(filepath, options); 576 | const filepaths = getConfigFileNames(resolvedFilePath, processedOptions); 577 | const configs = getAllConfigsSync(filepaths, processedOptions); 578 | return combine(resolvedFilePath, configs, processedOptions); 579 | } 580 | 581 | /** 582 | * I think this may be of limited utility at the moment, but I need something 583 | * like this for testing. As such, the interface of this may change without 584 | * warning. 585 | * 586 | * Something this direction may be better for editors than the caching bits 587 | * we've got today, but that will need some thought. 588 | * 589 | * @param options All options. root will be process.cwd if not specified. 590 | * @param buffers 1 or more Buffers that have .editorconfig contents. 591 | * @returns Function that can be called multiple times for different paths. 592 | * @private 593 | */ 594 | export function matcher( 595 | options: ParseOptions, 596 | ...buffers: Buffer[] 597 | ): (filepath: string) => Props { 598 | const [_fileName, processedOptions] = opts('', options); 599 | const configs = buffers.map((buf, i) => processFileContents( 600 | path.join(processedOptions.root as string, `buffer-${i}`), 601 | buf, 602 | processedOptions 603 | )); 604 | return (filepath: string) => { 605 | const resolvedFilePath = path.resolve(filepath); 606 | return combine(resolvedFilePath, configs, processedOptions); 607 | }; 608 | } 609 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "module": "commonjs", 5 | "outDir": "lib", 6 | "declaration": true, 7 | "esModuleInterop": true, 8 | "target": "es2018", 9 | "sourceMap": false, 10 | "moduleResolution": "node", 11 | "resolveJsonModule": true, 12 | "rootDir": "src", 13 | "forceConsistentCasingInFileNames": true, 14 | "noImplicitReturns": true, 15 | "noImplicitThis": true, 16 | "noImplicitAny": true, 17 | "strictNullChecks": true, 18 | "noUnusedLocals": true, 19 | "skipLibCheck": true 20 | }, 21 | "include": [ 22 | "src/" 23 | ] 24 | } 25 | --------------------------------------------------------------------------------