├── .github
└── workflows
│ └── npm-publish.yml
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin
└── cli.js
├── package-lock.json
├── package.json
├── src
├── from
│ ├── asdf.ts
│ ├── envs.ts
│ ├── gradle.ts
│ ├── homebrew.ts
│ ├── jabba.ts
│ ├── jbang.ts
│ ├── jenv.ts
│ ├── linux.ts
│ ├── macOS.ts
│ ├── sdkman.ts
│ └── windows.ts
├── index.ts
├── logger.ts
└── utils.ts
├── test
└── test.js
└── tsconfig.json
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | release:
8 | types: [created]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3
15 | - uses: actions/setup-node@v3
16 | with:
17 | node-version: 16
18 | - run: npm ci
19 | - run: npm test
20 |
21 | publish-npm:
22 | needs: build
23 | runs-on: ubuntu-latest
24 | steps:
25 | - uses: actions/checkout@v3
26 | - uses: actions/setup-node@v3
27 | with:
28 | node-version: 16
29 | registry-url: https://registry.npmjs.org/
30 | - run: npm ci
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 |
18 | # Directory for instrumented libs generated by jscoverage/JSCover
19 | lib-cov
20 |
21 | # Coverage directory used by tools like istanbul
22 | coverage
23 | *.lcov
24 |
25 | # nyc test coverage
26 | .nyc_output
27 |
28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29 | .grunt
30 |
31 | # Bower dependency directory (https://bower.io/)
32 | bower_components
33 |
34 | # node-waf configuration
35 | .lock-wscript
36 |
37 | # Compiled binary addons (https://nodejs.org/api/addons.html)
38 | build/Release
39 |
40 | # Dependency directories
41 | node_modules/
42 | jspm_packages/
43 |
44 | # TypeScript v1 declaration files
45 | typings/
46 |
47 | # TypeScript cache
48 | *.tsbuildinfo
49 |
50 | # Optional npm cache directory
51 | .npm
52 |
53 | # Optional eslint cache
54 | .eslintcache
55 |
56 | # Microbundle cache
57 | .rpt2_cache/
58 | .rts2_cache_cjs/
59 | .rts2_cache_es/
60 | .rts2_cache_umd/
61 |
62 | # Optional REPL history
63 | .node_repl_history
64 |
65 | # Output of 'npm pack'
66 | *.tgz
67 |
68 | # Yarn Integrity file
69 | .yarn-integrity
70 |
71 | # dotenv environment variables file
72 | .env
73 | .env.test
74 |
75 | # parcel-bundler cache (https://parceljs.org/)
76 | .cache
77 |
78 | # Next.js build output
79 | .next
80 |
81 | # Nuxt.js build / generate output
82 | .nuxt
83 | dist
84 |
85 | # Gatsby files
86 | .cache/
87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
88 | # https://nextjs.org/blog/next-9-1#public-directory-support
89 | # public
90 |
91 | # vuepress build output
92 | .vuepress/dist
93 |
94 | # Serverless directories
95 | .serverless/
96 |
97 | # FuseBox cache
98 | .fusebox/
99 |
100 | # DynamoDB Local files
101 | .dynamodb/
102 |
103 | # TernJS port file
104 | .tern-port
105 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.tgz
2 | src
3 | test
4 | tsconfig.json
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | This is changelog of node-jdk-utils project.
2 |
3 | ## 0.5.1
4 | - Fixed: `/usr` detected as a wrong Java home on macOS. [#15](https://github.com/Eskibear/node-jdk-utils/issues/15)
5 |
6 | ## 0.5.0
7 | - Scan default installation directory for Zulu on Windows.[#12](https://github.com/Eskibear/node-jdk-utils/pull/12)
8 | - Traverse entires in env.PATH to cover all possible locations. Note, this increases disk I/O which will affect the performance depending on number of entries of env.PATH. [#13](https://github.com/Eskibear/node-jdk-utils/pull/13)
9 | - Add `skipFrom` option which allow you to skip scanning from specific source to improve overall performance. [#14](https://github.com/Eskibear/node-jdk-utils/pull/14)
10 |
11 | ## 0.4.6
12 | - Fix gradle toolchains Windows path structure. [#11](https://github.com/Eskibear/node-jdk-utils/pull/11)
13 |
14 | ## 0.4.5
15 | - Support to detect JDKs installed by Gradle. [#9](https://github.com/Eskibear/node-jdk-utils/issues/9)]
16 |
17 | ## 0.4.4
18 | - Better support for ASDF, searching `env.ASDF_DATA_DIR` instead of `env.ASDF_DIR`. [#8](https://github.com/Eskibear/node-jdk-utils/pull/8)
19 |
20 | ## 0.4.3
21 | - Support to detect JDKs installed by ASDF. [#7](https://github.com/Eskibear/node-jdk-utils/pull/7)
22 |
23 | ## 0.4.2
24 | ### Added
25 | - Support to detect JDKs installed by Homebrew, covering macOS Apple Silicon and Linux.
26 |
27 | ## 0.4.1
28 | ### Added
29 | - Add CLI to list all detected runtimes, which is convenient for testing coverage.
30 |
31 | ## 0.4.0
32 | ### Added
33 | - Support to detect JDKs installed by Homebrew (macOS only).
34 |
35 | ### Fixed
36 | - For candidates from envs like `PATH`, resolve symbolic links of `bin/java` to get real path of the installation.
37 |
38 | ## 0.3.1
39 | ### Changed
40 | - Simplify APIs.
41 |
42 | ## 0.3.0
43 | ### Added
44 | - Support to detect JDKs installed by jabba.
45 | - New API **getSources(runtime)** to list sources where a Java Runtime is found.
46 |
47 | ## 0.2.1
48 | ### Fixed
49 | - For macOS, add below sources to detect runtimes:
50 | - `~/Library/Java/JavaVirtualMachines`
51 | - Output of `java_home -V`
52 |
53 | ## 0.2.0
54 | ### Added
55 | - New API **getRuntime(homedir, options)**: verify if given directory is a valid runtime, and provide more information if it is.
56 | - Export type defitions for better usablity.
57 |
58 | ## 0.1.0
59 | ### Added
60 | - New API **findRuntimes(options)**: list all Java runtimes installed on local machine. It searches locations deducted from environment variables (PATH/JAVA_HOME/JDK_HOME), SDKMAN installation directory, jEnv configurations, and default installation locations of popular distributions.
61 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Yan Zhang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-jdk-utils
2 |
3 |
4 |
5 |
6 | A collection of Java related utils.
7 |
8 | ## Installation
9 | ```bash
10 | npm i jdk-utils
11 | ```
12 |
13 | ## Usage
14 |
15 | ### findJavaRuntime
16 |
17 | Find Java runtime from all possible locations on your machine.
18 | Covering:
19 | * `JAVA_HOME`.
20 | * JDK-like paths from `PATH`.
21 | * SDKMAN installation location.
22 | * jabba installation location, i.e. `~/.jabba/jdk`
23 | * [JBang](https://jbang.dev/) installation location, i.e. `~/.jbang/cache/jdks`
24 | * ASDF installation location.
25 | * JDK installations managed by [Gradle](https://docs.gradle.org/8.1/userguide/toolchains.html), e.g. `~/.gradle/jdk`
26 | * Links specified in jEnv.
27 | * Homebrew installation:
28 | * macOS Intel: `/usr/local`
29 | * macOS Apple Silicon: `/opt/homebrew`
30 | * Linux: `/home/linuxbrew/.linuxbrew`
31 | * Platform-specific conventional installation location:
32 | * Linux: `/usr/lib/jvm`
33 | * macOS: `/Library/Java/JavaVirtualMachines`, `~/Library/Java/JavaVirtualMachines`, output of `java_home -V`.
34 | * Windows: JDK-like folders under `%ProgramFiles%` and `%LocalAppData%`,
35 |
36 | Note: If you want to skip scanning a certain source for better performance, you can specify `skipFrom` options when calling the API.
37 |
38 | #### CLI
39 |
40 | Below command lists all detected JDKs with details.
41 | ```bash
42 | npx jdk-utils
43 | ```
44 |
45 |
46 | #### callback-style
47 |
48 | ```ts
49 | require("jdk-utils").findRuntimes().then(console.log)
50 | /*
51 | [{
52 | homedir: '/home/username/.sdkman/candidates/java/17.0.1-ms',
53 | }, {
54 | homedir: '/usr/lib/jvm/java-11-openjdk-amd64',
55 | },
56 | ...
57 | ]
58 | */
59 | ```
60 |
61 | #### promise-style
62 | ```ts
63 | import { findRuntimes } from "jdk-utils";
64 | await findRuntimes({checkJavac: true, withVersion: true, withTags: true});
65 | /*
66 | [{
67 | homedir: '/home/yanzh/.sdkman/candidates/java/17.0.1-ms',
68 | hasJavac: true,
69 | isFromSDKMAN: true,
70 | version: { java_version: '17.0.1', major: 17 }
71 | }, {
72 | homedir: '/usr/lib/jvm/java-11-openjdk-amd64',
73 | hasJavac: true,
74 | version: { java_version: '11.0.7', major: 11 }
75 | },
76 | ...
77 | ]
78 | */
79 | ```
80 |
81 |
--------------------------------------------------------------------------------
/bin/cli.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | async function listAll() {
4 | const utils = require("../dist/index");
5 | const label = "Listing JDKs";
6 | console.time(label);
7 | const jdks = await utils.findRuntimes({ withTags: true, withVersion: true, checkJavac: true });
8 | console.timeEnd(label);
9 | console.log("Found: ", jdks.length);
10 | console.log(jdks);
11 | }
12 |
13 | listAll();
14 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jdk-utils",
3 | "version": "0.5.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "jdk-utils",
9 | "version": "0.5.1",
10 | "license": "MIT",
11 | "bin": {
12 | "jdk-utils": "bin/cli.js"
13 | },
14 | "devDependencies": {
15 | "@types/node": "^16.11.8",
16 | "chai": "^4.3.4",
17 | "mocha": "^9.2.2",
18 | "typescript": "^4.5.2"
19 | }
20 | },
21 | "node_modules/@types/node": {
22 | "version": "16.11.8",
23 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.8.tgz",
24 | "integrity": "sha512-hmT5gfpRkkHr7DZZHMf3jBe/zNcVGN+jXSL2f8nAsYfBPxQFToKwQlS/zES4Sjp488Bi73i+p6bvrNRRGU0x9Q==",
25 | "dev": true
26 | },
27 | "node_modules/@ungap/promise-all-settled": {
28 | "version": "1.1.2",
29 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
30 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
31 | "dev": true
32 | },
33 | "node_modules/ansi-colors": {
34 | "version": "4.1.1",
35 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
36 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
37 | "dev": true,
38 | "engines": {
39 | "node": ">=6"
40 | }
41 | },
42 | "node_modules/ansi-regex": {
43 | "version": "5.0.1",
44 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
45 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
46 | "dev": true,
47 | "engines": {
48 | "node": ">=8"
49 | }
50 | },
51 | "node_modules/ansi-styles": {
52 | "version": "4.3.0",
53 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
54 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
55 | "dev": true,
56 | "dependencies": {
57 | "color-convert": "^2.0.1"
58 | },
59 | "engines": {
60 | "node": ">=8"
61 | },
62 | "funding": {
63 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
64 | }
65 | },
66 | "node_modules/anymatch": {
67 | "version": "3.1.2",
68 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
69 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
70 | "dev": true,
71 | "dependencies": {
72 | "normalize-path": "^3.0.0",
73 | "picomatch": "^2.0.4"
74 | },
75 | "engines": {
76 | "node": ">= 8"
77 | }
78 | },
79 | "node_modules/argparse": {
80 | "version": "2.0.1",
81 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
82 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
83 | "dev": true
84 | },
85 | "node_modules/assertion-error": {
86 | "version": "1.1.0",
87 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
88 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
89 | "dev": true,
90 | "engines": {
91 | "node": "*"
92 | }
93 | },
94 | "node_modules/balanced-match": {
95 | "version": "1.0.2",
96 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
97 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
98 | "dev": true
99 | },
100 | "node_modules/binary-extensions": {
101 | "version": "2.2.0",
102 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
103 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
104 | "dev": true,
105 | "engines": {
106 | "node": ">=8"
107 | }
108 | },
109 | "node_modules/brace-expansion": {
110 | "version": "1.1.11",
111 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
112 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
113 | "dev": true,
114 | "dependencies": {
115 | "balanced-match": "^1.0.0",
116 | "concat-map": "0.0.1"
117 | }
118 | },
119 | "node_modules/braces": {
120 | "version": "3.0.2",
121 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
122 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
123 | "dev": true,
124 | "dependencies": {
125 | "fill-range": "^7.0.1"
126 | },
127 | "engines": {
128 | "node": ">=8"
129 | }
130 | },
131 | "node_modules/browser-stdout": {
132 | "version": "1.3.1",
133 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
134 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
135 | "dev": true
136 | },
137 | "node_modules/camelcase": {
138 | "version": "6.3.0",
139 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
140 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
141 | "dev": true,
142 | "engines": {
143 | "node": ">=10"
144 | },
145 | "funding": {
146 | "url": "https://github.com/sponsors/sindresorhus"
147 | }
148 | },
149 | "node_modules/chai": {
150 | "version": "4.3.4",
151 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
152 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
153 | "dev": true,
154 | "dependencies": {
155 | "assertion-error": "^1.1.0",
156 | "check-error": "^1.0.2",
157 | "deep-eql": "^3.0.1",
158 | "get-func-name": "^2.0.0",
159 | "pathval": "^1.1.1",
160 | "type-detect": "^4.0.5"
161 | },
162 | "engines": {
163 | "node": ">=4"
164 | }
165 | },
166 | "node_modules/chalk": {
167 | "version": "4.1.2",
168 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
169 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
170 | "dev": true,
171 | "dependencies": {
172 | "ansi-styles": "^4.1.0",
173 | "supports-color": "^7.1.0"
174 | },
175 | "engines": {
176 | "node": ">=10"
177 | },
178 | "funding": {
179 | "url": "https://github.com/chalk/chalk?sponsor=1"
180 | }
181 | },
182 | "node_modules/chalk/node_modules/supports-color": {
183 | "version": "7.2.0",
184 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
185 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
186 | "dev": true,
187 | "dependencies": {
188 | "has-flag": "^4.0.0"
189 | },
190 | "engines": {
191 | "node": ">=8"
192 | }
193 | },
194 | "node_modules/check-error": {
195 | "version": "1.0.2",
196 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
197 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
198 | "dev": true,
199 | "engines": {
200 | "node": "*"
201 | }
202 | },
203 | "node_modules/chokidar": {
204 | "version": "3.5.3",
205 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
206 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
207 | "dev": true,
208 | "funding": [
209 | {
210 | "type": "individual",
211 | "url": "https://paulmillr.com/funding/"
212 | }
213 | ],
214 | "dependencies": {
215 | "anymatch": "~3.1.2",
216 | "braces": "~3.0.2",
217 | "glob-parent": "~5.1.2",
218 | "is-binary-path": "~2.1.0",
219 | "is-glob": "~4.0.1",
220 | "normalize-path": "~3.0.0",
221 | "readdirp": "~3.6.0"
222 | },
223 | "engines": {
224 | "node": ">= 8.10.0"
225 | },
226 | "optionalDependencies": {
227 | "fsevents": "~2.3.2"
228 | }
229 | },
230 | "node_modules/cliui": {
231 | "version": "7.0.4",
232 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
233 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
234 | "dev": true,
235 | "dependencies": {
236 | "string-width": "^4.2.0",
237 | "strip-ansi": "^6.0.0",
238 | "wrap-ansi": "^7.0.0"
239 | }
240 | },
241 | "node_modules/color-convert": {
242 | "version": "2.0.1",
243 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
244 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
245 | "dev": true,
246 | "dependencies": {
247 | "color-name": "~1.1.4"
248 | },
249 | "engines": {
250 | "node": ">=7.0.0"
251 | }
252 | },
253 | "node_modules/color-name": {
254 | "version": "1.1.4",
255 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
256 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
257 | "dev": true
258 | },
259 | "node_modules/concat-map": {
260 | "version": "0.0.1",
261 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
262 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
263 | "dev": true
264 | },
265 | "node_modules/debug": {
266 | "version": "4.3.3",
267 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
268 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
269 | "dev": true,
270 | "dependencies": {
271 | "ms": "2.1.2"
272 | },
273 | "engines": {
274 | "node": ">=6.0"
275 | },
276 | "peerDependenciesMeta": {
277 | "supports-color": {
278 | "optional": true
279 | }
280 | }
281 | },
282 | "node_modules/debug/node_modules/ms": {
283 | "version": "2.1.2",
284 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
285 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
286 | "dev": true
287 | },
288 | "node_modules/decamelize": {
289 | "version": "4.0.0",
290 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
291 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
292 | "dev": true,
293 | "engines": {
294 | "node": ">=10"
295 | },
296 | "funding": {
297 | "url": "https://github.com/sponsors/sindresorhus"
298 | }
299 | },
300 | "node_modules/deep-eql": {
301 | "version": "3.0.1",
302 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
303 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
304 | "dev": true,
305 | "dependencies": {
306 | "type-detect": "^4.0.0"
307 | },
308 | "engines": {
309 | "node": ">=0.12"
310 | }
311 | },
312 | "node_modules/diff": {
313 | "version": "5.0.0",
314 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
315 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
316 | "dev": true,
317 | "engines": {
318 | "node": ">=0.3.1"
319 | }
320 | },
321 | "node_modules/emoji-regex": {
322 | "version": "8.0.0",
323 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
324 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
325 | "dev": true
326 | },
327 | "node_modules/escalade": {
328 | "version": "3.1.1",
329 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
330 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
331 | "dev": true,
332 | "engines": {
333 | "node": ">=6"
334 | }
335 | },
336 | "node_modules/escape-string-regexp": {
337 | "version": "4.0.0",
338 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
339 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
340 | "dev": true,
341 | "engines": {
342 | "node": ">=10"
343 | },
344 | "funding": {
345 | "url": "https://github.com/sponsors/sindresorhus"
346 | }
347 | },
348 | "node_modules/fill-range": {
349 | "version": "7.0.1",
350 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
351 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
352 | "dev": true,
353 | "dependencies": {
354 | "to-regex-range": "^5.0.1"
355 | },
356 | "engines": {
357 | "node": ">=8"
358 | }
359 | },
360 | "node_modules/find-up": {
361 | "version": "5.0.0",
362 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
363 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
364 | "dev": true,
365 | "dependencies": {
366 | "locate-path": "^6.0.0",
367 | "path-exists": "^4.0.0"
368 | },
369 | "engines": {
370 | "node": ">=10"
371 | },
372 | "funding": {
373 | "url": "https://github.com/sponsors/sindresorhus"
374 | }
375 | },
376 | "node_modules/flat": {
377 | "version": "5.0.2",
378 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
379 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
380 | "dev": true,
381 | "bin": {
382 | "flat": "cli.js"
383 | }
384 | },
385 | "node_modules/fs.realpath": {
386 | "version": "1.0.0",
387 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
388 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
389 | "dev": true
390 | },
391 | "node_modules/fsevents": {
392 | "version": "2.3.2",
393 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
394 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
395 | "dev": true,
396 | "hasInstallScript": true,
397 | "optional": true,
398 | "os": [
399 | "darwin"
400 | ],
401 | "engines": {
402 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
403 | }
404 | },
405 | "node_modules/get-caller-file": {
406 | "version": "2.0.5",
407 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
408 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
409 | "dev": true,
410 | "engines": {
411 | "node": "6.* || 8.* || >= 10.*"
412 | }
413 | },
414 | "node_modules/get-func-name": {
415 | "version": "2.0.0",
416 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
417 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
418 | "dev": true,
419 | "engines": {
420 | "node": "*"
421 | }
422 | },
423 | "node_modules/glob": {
424 | "version": "7.2.0",
425 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
426 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
427 | "dev": true,
428 | "dependencies": {
429 | "fs.realpath": "^1.0.0",
430 | "inflight": "^1.0.4",
431 | "inherits": "2",
432 | "minimatch": "^3.0.4",
433 | "once": "^1.3.0",
434 | "path-is-absolute": "^1.0.0"
435 | },
436 | "engines": {
437 | "node": "*"
438 | },
439 | "funding": {
440 | "url": "https://github.com/sponsors/isaacs"
441 | }
442 | },
443 | "node_modules/glob-parent": {
444 | "version": "5.1.2",
445 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
446 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
447 | "dev": true,
448 | "dependencies": {
449 | "is-glob": "^4.0.1"
450 | },
451 | "engines": {
452 | "node": ">= 6"
453 | }
454 | },
455 | "node_modules/glob/node_modules/minimatch": {
456 | "version": "3.1.2",
457 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
458 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
459 | "dev": true,
460 | "dependencies": {
461 | "brace-expansion": "^1.1.7"
462 | },
463 | "engines": {
464 | "node": "*"
465 | }
466 | },
467 | "node_modules/growl": {
468 | "version": "1.10.5",
469 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
470 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
471 | "dev": true,
472 | "engines": {
473 | "node": ">=4.x"
474 | }
475 | },
476 | "node_modules/has-flag": {
477 | "version": "4.0.0",
478 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
479 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
480 | "dev": true,
481 | "engines": {
482 | "node": ">=8"
483 | }
484 | },
485 | "node_modules/he": {
486 | "version": "1.2.0",
487 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
488 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
489 | "dev": true,
490 | "bin": {
491 | "he": "bin/he"
492 | }
493 | },
494 | "node_modules/inflight": {
495 | "version": "1.0.6",
496 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
497 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
498 | "dev": true,
499 | "dependencies": {
500 | "once": "^1.3.0",
501 | "wrappy": "1"
502 | }
503 | },
504 | "node_modules/inherits": {
505 | "version": "2.0.4",
506 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
507 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
508 | "dev": true
509 | },
510 | "node_modules/is-binary-path": {
511 | "version": "2.1.0",
512 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
513 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
514 | "dev": true,
515 | "dependencies": {
516 | "binary-extensions": "^2.0.0"
517 | },
518 | "engines": {
519 | "node": ">=8"
520 | }
521 | },
522 | "node_modules/is-extglob": {
523 | "version": "2.1.1",
524 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
525 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
526 | "dev": true,
527 | "engines": {
528 | "node": ">=0.10.0"
529 | }
530 | },
531 | "node_modules/is-fullwidth-code-point": {
532 | "version": "3.0.0",
533 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
534 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
535 | "dev": true,
536 | "engines": {
537 | "node": ">=8"
538 | }
539 | },
540 | "node_modules/is-glob": {
541 | "version": "4.0.3",
542 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
543 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
544 | "dev": true,
545 | "dependencies": {
546 | "is-extglob": "^2.1.1"
547 | },
548 | "engines": {
549 | "node": ">=0.10.0"
550 | }
551 | },
552 | "node_modules/is-number": {
553 | "version": "7.0.0",
554 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
555 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
556 | "dev": true,
557 | "engines": {
558 | "node": ">=0.12.0"
559 | }
560 | },
561 | "node_modules/is-plain-obj": {
562 | "version": "2.1.0",
563 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
564 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
565 | "dev": true,
566 | "engines": {
567 | "node": ">=8"
568 | }
569 | },
570 | "node_modules/is-unicode-supported": {
571 | "version": "0.1.0",
572 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
573 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
574 | "dev": true,
575 | "engines": {
576 | "node": ">=10"
577 | },
578 | "funding": {
579 | "url": "https://github.com/sponsors/sindresorhus"
580 | }
581 | },
582 | "node_modules/isexe": {
583 | "version": "2.0.0",
584 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
585 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
586 | "dev": true
587 | },
588 | "node_modules/js-yaml": {
589 | "version": "4.1.0",
590 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
591 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
592 | "dev": true,
593 | "dependencies": {
594 | "argparse": "^2.0.1"
595 | },
596 | "bin": {
597 | "js-yaml": "bin/js-yaml.js"
598 | }
599 | },
600 | "node_modules/locate-path": {
601 | "version": "6.0.0",
602 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
603 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
604 | "dev": true,
605 | "dependencies": {
606 | "p-locate": "^5.0.0"
607 | },
608 | "engines": {
609 | "node": ">=10"
610 | },
611 | "funding": {
612 | "url": "https://github.com/sponsors/sindresorhus"
613 | }
614 | },
615 | "node_modules/log-symbols": {
616 | "version": "4.1.0",
617 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
618 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
619 | "dev": true,
620 | "dependencies": {
621 | "chalk": "^4.1.0",
622 | "is-unicode-supported": "^0.1.0"
623 | },
624 | "engines": {
625 | "node": ">=10"
626 | },
627 | "funding": {
628 | "url": "https://github.com/sponsors/sindresorhus"
629 | }
630 | },
631 | "node_modules/minimatch": {
632 | "version": "4.2.1",
633 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
634 | "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
635 | "dev": true,
636 | "dependencies": {
637 | "brace-expansion": "^1.1.7"
638 | },
639 | "engines": {
640 | "node": ">=10"
641 | }
642 | },
643 | "node_modules/mocha": {
644 | "version": "9.2.2",
645 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
646 | "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
647 | "dev": true,
648 | "dependencies": {
649 | "@ungap/promise-all-settled": "1.1.2",
650 | "ansi-colors": "4.1.1",
651 | "browser-stdout": "1.3.1",
652 | "chokidar": "3.5.3",
653 | "debug": "4.3.3",
654 | "diff": "5.0.0",
655 | "escape-string-regexp": "4.0.0",
656 | "find-up": "5.0.0",
657 | "glob": "7.2.0",
658 | "growl": "1.10.5",
659 | "he": "1.2.0",
660 | "js-yaml": "4.1.0",
661 | "log-symbols": "4.1.0",
662 | "minimatch": "4.2.1",
663 | "ms": "2.1.3",
664 | "nanoid": "3.3.1",
665 | "serialize-javascript": "6.0.0",
666 | "strip-json-comments": "3.1.1",
667 | "supports-color": "8.1.1",
668 | "which": "2.0.2",
669 | "workerpool": "6.2.0",
670 | "yargs": "16.2.0",
671 | "yargs-parser": "20.2.4",
672 | "yargs-unparser": "2.0.0"
673 | },
674 | "bin": {
675 | "_mocha": "bin/_mocha",
676 | "mocha": "bin/mocha"
677 | },
678 | "engines": {
679 | "node": ">= 12.0.0"
680 | },
681 | "funding": {
682 | "type": "opencollective",
683 | "url": "https://opencollective.com/mochajs"
684 | }
685 | },
686 | "node_modules/ms": {
687 | "version": "2.1.3",
688 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
689 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
690 | "dev": true
691 | },
692 | "node_modules/nanoid": {
693 | "version": "3.3.1",
694 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
695 | "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
696 | "dev": true,
697 | "bin": {
698 | "nanoid": "bin/nanoid.cjs"
699 | },
700 | "engines": {
701 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
702 | }
703 | },
704 | "node_modules/normalize-path": {
705 | "version": "3.0.0",
706 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
707 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
708 | "dev": true,
709 | "engines": {
710 | "node": ">=0.10.0"
711 | }
712 | },
713 | "node_modules/once": {
714 | "version": "1.4.0",
715 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
716 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
717 | "dev": true,
718 | "dependencies": {
719 | "wrappy": "1"
720 | }
721 | },
722 | "node_modules/p-limit": {
723 | "version": "3.1.0",
724 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
725 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
726 | "dev": true,
727 | "dependencies": {
728 | "yocto-queue": "^0.1.0"
729 | },
730 | "engines": {
731 | "node": ">=10"
732 | },
733 | "funding": {
734 | "url": "https://github.com/sponsors/sindresorhus"
735 | }
736 | },
737 | "node_modules/p-locate": {
738 | "version": "5.0.0",
739 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
740 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
741 | "dev": true,
742 | "dependencies": {
743 | "p-limit": "^3.0.2"
744 | },
745 | "engines": {
746 | "node": ">=10"
747 | },
748 | "funding": {
749 | "url": "https://github.com/sponsors/sindresorhus"
750 | }
751 | },
752 | "node_modules/path-exists": {
753 | "version": "4.0.0",
754 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
755 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
756 | "dev": true,
757 | "engines": {
758 | "node": ">=8"
759 | }
760 | },
761 | "node_modules/path-is-absolute": {
762 | "version": "1.0.1",
763 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
764 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
765 | "dev": true,
766 | "engines": {
767 | "node": ">=0.10.0"
768 | }
769 | },
770 | "node_modules/pathval": {
771 | "version": "1.1.1",
772 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
773 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
774 | "dev": true,
775 | "engines": {
776 | "node": "*"
777 | }
778 | },
779 | "node_modules/picomatch": {
780 | "version": "2.3.1",
781 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
782 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
783 | "dev": true,
784 | "engines": {
785 | "node": ">=8.6"
786 | },
787 | "funding": {
788 | "url": "https://github.com/sponsors/jonschlinkert"
789 | }
790 | },
791 | "node_modules/randombytes": {
792 | "version": "2.1.0",
793 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
794 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
795 | "dev": true,
796 | "dependencies": {
797 | "safe-buffer": "^5.1.0"
798 | }
799 | },
800 | "node_modules/readdirp": {
801 | "version": "3.6.0",
802 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
803 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
804 | "dev": true,
805 | "dependencies": {
806 | "picomatch": "^2.2.1"
807 | },
808 | "engines": {
809 | "node": ">=8.10.0"
810 | }
811 | },
812 | "node_modules/require-directory": {
813 | "version": "2.1.1",
814 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
815 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
816 | "dev": true,
817 | "engines": {
818 | "node": ">=0.10.0"
819 | }
820 | },
821 | "node_modules/safe-buffer": {
822 | "version": "5.2.1",
823 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
824 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
825 | "dev": true,
826 | "funding": [
827 | {
828 | "type": "github",
829 | "url": "https://github.com/sponsors/feross"
830 | },
831 | {
832 | "type": "patreon",
833 | "url": "https://www.patreon.com/feross"
834 | },
835 | {
836 | "type": "consulting",
837 | "url": "https://feross.org/support"
838 | }
839 | ]
840 | },
841 | "node_modules/serialize-javascript": {
842 | "version": "6.0.0",
843 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
844 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
845 | "dev": true,
846 | "dependencies": {
847 | "randombytes": "^2.1.0"
848 | }
849 | },
850 | "node_modules/string-width": {
851 | "version": "4.2.3",
852 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
853 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
854 | "dev": true,
855 | "dependencies": {
856 | "emoji-regex": "^8.0.0",
857 | "is-fullwidth-code-point": "^3.0.0",
858 | "strip-ansi": "^6.0.1"
859 | },
860 | "engines": {
861 | "node": ">=8"
862 | }
863 | },
864 | "node_modules/strip-ansi": {
865 | "version": "6.0.1",
866 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
867 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
868 | "dev": true,
869 | "dependencies": {
870 | "ansi-regex": "^5.0.1"
871 | },
872 | "engines": {
873 | "node": ">=8"
874 | }
875 | },
876 | "node_modules/strip-json-comments": {
877 | "version": "3.1.1",
878 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
879 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
880 | "dev": true,
881 | "engines": {
882 | "node": ">=8"
883 | },
884 | "funding": {
885 | "url": "https://github.com/sponsors/sindresorhus"
886 | }
887 | },
888 | "node_modules/supports-color": {
889 | "version": "8.1.1",
890 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
891 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
892 | "dev": true,
893 | "dependencies": {
894 | "has-flag": "^4.0.0"
895 | },
896 | "engines": {
897 | "node": ">=10"
898 | },
899 | "funding": {
900 | "url": "https://github.com/chalk/supports-color?sponsor=1"
901 | }
902 | },
903 | "node_modules/to-regex-range": {
904 | "version": "5.0.1",
905 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
906 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
907 | "dev": true,
908 | "dependencies": {
909 | "is-number": "^7.0.0"
910 | },
911 | "engines": {
912 | "node": ">=8.0"
913 | }
914 | },
915 | "node_modules/type-detect": {
916 | "version": "4.0.8",
917 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
918 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
919 | "dev": true,
920 | "engines": {
921 | "node": ">=4"
922 | }
923 | },
924 | "node_modules/typescript": {
925 | "version": "4.5.2",
926 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
927 | "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==",
928 | "dev": true,
929 | "bin": {
930 | "tsc": "bin/tsc",
931 | "tsserver": "bin/tsserver"
932 | },
933 | "engines": {
934 | "node": ">=4.2.0"
935 | }
936 | },
937 | "node_modules/which": {
938 | "version": "2.0.2",
939 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
940 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
941 | "dev": true,
942 | "dependencies": {
943 | "isexe": "^2.0.0"
944 | },
945 | "bin": {
946 | "node-which": "bin/node-which"
947 | },
948 | "engines": {
949 | "node": ">= 8"
950 | }
951 | },
952 | "node_modules/workerpool": {
953 | "version": "6.2.0",
954 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
955 | "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
956 | "dev": true
957 | },
958 | "node_modules/wrap-ansi": {
959 | "version": "7.0.0",
960 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
961 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
962 | "dev": true,
963 | "dependencies": {
964 | "ansi-styles": "^4.0.0",
965 | "string-width": "^4.1.0",
966 | "strip-ansi": "^6.0.0"
967 | },
968 | "engines": {
969 | "node": ">=10"
970 | },
971 | "funding": {
972 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
973 | }
974 | },
975 | "node_modules/wrappy": {
976 | "version": "1.0.2",
977 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
978 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
979 | "dev": true
980 | },
981 | "node_modules/y18n": {
982 | "version": "5.0.8",
983 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
984 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
985 | "dev": true,
986 | "engines": {
987 | "node": ">=10"
988 | }
989 | },
990 | "node_modules/yargs": {
991 | "version": "16.2.0",
992 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
993 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
994 | "dev": true,
995 | "dependencies": {
996 | "cliui": "^7.0.2",
997 | "escalade": "^3.1.1",
998 | "get-caller-file": "^2.0.5",
999 | "require-directory": "^2.1.1",
1000 | "string-width": "^4.2.0",
1001 | "y18n": "^5.0.5",
1002 | "yargs-parser": "^20.2.2"
1003 | },
1004 | "engines": {
1005 | "node": ">=10"
1006 | }
1007 | },
1008 | "node_modules/yargs-parser": {
1009 | "version": "20.2.4",
1010 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
1011 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
1012 | "dev": true,
1013 | "engines": {
1014 | "node": ">=10"
1015 | }
1016 | },
1017 | "node_modules/yargs-unparser": {
1018 | "version": "2.0.0",
1019 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
1020 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
1021 | "dev": true,
1022 | "dependencies": {
1023 | "camelcase": "^6.0.0",
1024 | "decamelize": "^4.0.0",
1025 | "flat": "^5.0.2",
1026 | "is-plain-obj": "^2.1.0"
1027 | },
1028 | "engines": {
1029 | "node": ">=10"
1030 | }
1031 | },
1032 | "node_modules/yocto-queue": {
1033 | "version": "0.1.0",
1034 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
1035 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
1036 | "dev": true,
1037 | "engines": {
1038 | "node": ">=10"
1039 | },
1040 | "funding": {
1041 | "url": "https://github.com/sponsors/sindresorhus"
1042 | }
1043 | }
1044 | },
1045 | "dependencies": {
1046 | "@types/node": {
1047 | "version": "16.11.8",
1048 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.8.tgz",
1049 | "integrity": "sha512-hmT5gfpRkkHr7DZZHMf3jBe/zNcVGN+jXSL2f8nAsYfBPxQFToKwQlS/zES4Sjp488Bi73i+p6bvrNRRGU0x9Q==",
1050 | "dev": true
1051 | },
1052 | "@ungap/promise-all-settled": {
1053 | "version": "1.1.2",
1054 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
1055 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
1056 | "dev": true
1057 | },
1058 | "ansi-colors": {
1059 | "version": "4.1.1",
1060 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
1061 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
1062 | "dev": true
1063 | },
1064 | "ansi-regex": {
1065 | "version": "5.0.1",
1066 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
1067 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
1068 | "dev": true
1069 | },
1070 | "ansi-styles": {
1071 | "version": "4.3.0",
1072 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1073 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1074 | "dev": true,
1075 | "requires": {
1076 | "color-convert": "^2.0.1"
1077 | }
1078 | },
1079 | "anymatch": {
1080 | "version": "3.1.2",
1081 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
1082 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
1083 | "dev": true,
1084 | "requires": {
1085 | "normalize-path": "^3.0.0",
1086 | "picomatch": "^2.0.4"
1087 | }
1088 | },
1089 | "argparse": {
1090 | "version": "2.0.1",
1091 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
1092 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
1093 | "dev": true
1094 | },
1095 | "assertion-error": {
1096 | "version": "1.1.0",
1097 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
1098 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
1099 | "dev": true
1100 | },
1101 | "balanced-match": {
1102 | "version": "1.0.2",
1103 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1104 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1105 | "dev": true
1106 | },
1107 | "binary-extensions": {
1108 | "version": "2.2.0",
1109 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
1110 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
1111 | "dev": true
1112 | },
1113 | "brace-expansion": {
1114 | "version": "1.1.11",
1115 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1116 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1117 | "dev": true,
1118 | "requires": {
1119 | "balanced-match": "^1.0.0",
1120 | "concat-map": "0.0.1"
1121 | }
1122 | },
1123 | "braces": {
1124 | "version": "3.0.2",
1125 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
1126 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
1127 | "dev": true,
1128 | "requires": {
1129 | "fill-range": "^7.0.1"
1130 | }
1131 | },
1132 | "browser-stdout": {
1133 | "version": "1.3.1",
1134 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
1135 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
1136 | "dev": true
1137 | },
1138 | "camelcase": {
1139 | "version": "6.3.0",
1140 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
1141 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
1142 | "dev": true
1143 | },
1144 | "chai": {
1145 | "version": "4.3.4",
1146 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
1147 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
1148 | "dev": true,
1149 | "requires": {
1150 | "assertion-error": "^1.1.0",
1151 | "check-error": "^1.0.2",
1152 | "deep-eql": "^3.0.1",
1153 | "get-func-name": "^2.0.0",
1154 | "pathval": "^1.1.1",
1155 | "type-detect": "^4.0.5"
1156 | }
1157 | },
1158 | "chalk": {
1159 | "version": "4.1.2",
1160 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1161 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1162 | "dev": true,
1163 | "requires": {
1164 | "ansi-styles": "^4.1.0",
1165 | "supports-color": "^7.1.0"
1166 | },
1167 | "dependencies": {
1168 | "supports-color": {
1169 | "version": "7.2.0",
1170 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1171 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1172 | "dev": true,
1173 | "requires": {
1174 | "has-flag": "^4.0.0"
1175 | }
1176 | }
1177 | }
1178 | },
1179 | "check-error": {
1180 | "version": "1.0.2",
1181 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
1182 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
1183 | "dev": true
1184 | },
1185 | "chokidar": {
1186 | "version": "3.5.3",
1187 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
1188 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
1189 | "dev": true,
1190 | "requires": {
1191 | "anymatch": "~3.1.2",
1192 | "braces": "~3.0.2",
1193 | "fsevents": "~2.3.2",
1194 | "glob-parent": "~5.1.2",
1195 | "is-binary-path": "~2.1.0",
1196 | "is-glob": "~4.0.1",
1197 | "normalize-path": "~3.0.0",
1198 | "readdirp": "~3.6.0"
1199 | }
1200 | },
1201 | "cliui": {
1202 | "version": "7.0.4",
1203 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
1204 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
1205 | "dev": true,
1206 | "requires": {
1207 | "string-width": "^4.2.0",
1208 | "strip-ansi": "^6.0.0",
1209 | "wrap-ansi": "^7.0.0"
1210 | }
1211 | },
1212 | "color-convert": {
1213 | "version": "2.0.1",
1214 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1215 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1216 | "dev": true,
1217 | "requires": {
1218 | "color-name": "~1.1.4"
1219 | }
1220 | },
1221 | "color-name": {
1222 | "version": "1.1.4",
1223 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1224 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1225 | "dev": true
1226 | },
1227 | "concat-map": {
1228 | "version": "0.0.1",
1229 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1230 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
1231 | "dev": true
1232 | },
1233 | "debug": {
1234 | "version": "4.3.3",
1235 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
1236 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
1237 | "dev": true,
1238 | "requires": {
1239 | "ms": "2.1.2"
1240 | },
1241 | "dependencies": {
1242 | "ms": {
1243 | "version": "2.1.2",
1244 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1245 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1246 | "dev": true
1247 | }
1248 | }
1249 | },
1250 | "decamelize": {
1251 | "version": "4.0.0",
1252 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
1253 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
1254 | "dev": true
1255 | },
1256 | "deep-eql": {
1257 | "version": "3.0.1",
1258 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
1259 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
1260 | "dev": true,
1261 | "requires": {
1262 | "type-detect": "^4.0.0"
1263 | }
1264 | },
1265 | "diff": {
1266 | "version": "5.0.0",
1267 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
1268 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
1269 | "dev": true
1270 | },
1271 | "emoji-regex": {
1272 | "version": "8.0.0",
1273 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
1274 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
1275 | "dev": true
1276 | },
1277 | "escalade": {
1278 | "version": "3.1.1",
1279 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
1280 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
1281 | "dev": true
1282 | },
1283 | "escape-string-regexp": {
1284 | "version": "4.0.0",
1285 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
1286 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
1287 | "dev": true
1288 | },
1289 | "fill-range": {
1290 | "version": "7.0.1",
1291 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1292 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1293 | "dev": true,
1294 | "requires": {
1295 | "to-regex-range": "^5.0.1"
1296 | }
1297 | },
1298 | "find-up": {
1299 | "version": "5.0.0",
1300 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
1301 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
1302 | "dev": true,
1303 | "requires": {
1304 | "locate-path": "^6.0.0",
1305 | "path-exists": "^4.0.0"
1306 | }
1307 | },
1308 | "flat": {
1309 | "version": "5.0.2",
1310 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
1311 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
1312 | "dev": true
1313 | },
1314 | "fs.realpath": {
1315 | "version": "1.0.0",
1316 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1317 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
1318 | "dev": true
1319 | },
1320 | "fsevents": {
1321 | "version": "2.3.2",
1322 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1323 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1324 | "dev": true,
1325 | "optional": true
1326 | },
1327 | "get-caller-file": {
1328 | "version": "2.0.5",
1329 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
1330 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
1331 | "dev": true
1332 | },
1333 | "get-func-name": {
1334 | "version": "2.0.0",
1335 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
1336 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
1337 | "dev": true
1338 | },
1339 | "glob": {
1340 | "version": "7.2.0",
1341 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
1342 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
1343 | "dev": true,
1344 | "requires": {
1345 | "fs.realpath": "^1.0.0",
1346 | "inflight": "^1.0.4",
1347 | "inherits": "2",
1348 | "minimatch": "^3.0.4",
1349 | "once": "^1.3.0",
1350 | "path-is-absolute": "^1.0.0"
1351 | },
1352 | "dependencies": {
1353 | "minimatch": {
1354 | "version": "3.1.2",
1355 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1356 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1357 | "dev": true,
1358 | "requires": {
1359 | "brace-expansion": "^1.1.7"
1360 | }
1361 | }
1362 | }
1363 | },
1364 | "glob-parent": {
1365 | "version": "5.1.2",
1366 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1367 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1368 | "dev": true,
1369 | "requires": {
1370 | "is-glob": "^4.0.1"
1371 | }
1372 | },
1373 | "growl": {
1374 | "version": "1.10.5",
1375 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
1376 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
1377 | "dev": true
1378 | },
1379 | "has-flag": {
1380 | "version": "4.0.0",
1381 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1382 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1383 | "dev": true
1384 | },
1385 | "he": {
1386 | "version": "1.2.0",
1387 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
1388 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
1389 | "dev": true
1390 | },
1391 | "inflight": {
1392 | "version": "1.0.6",
1393 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1394 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1395 | "dev": true,
1396 | "requires": {
1397 | "once": "^1.3.0",
1398 | "wrappy": "1"
1399 | }
1400 | },
1401 | "inherits": {
1402 | "version": "2.0.4",
1403 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1404 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1405 | "dev": true
1406 | },
1407 | "is-binary-path": {
1408 | "version": "2.1.0",
1409 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1410 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1411 | "dev": true,
1412 | "requires": {
1413 | "binary-extensions": "^2.0.0"
1414 | }
1415 | },
1416 | "is-extglob": {
1417 | "version": "2.1.1",
1418 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1419 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1420 | "dev": true
1421 | },
1422 | "is-fullwidth-code-point": {
1423 | "version": "3.0.0",
1424 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1425 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1426 | "dev": true
1427 | },
1428 | "is-glob": {
1429 | "version": "4.0.3",
1430 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1431 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1432 | "dev": true,
1433 | "requires": {
1434 | "is-extglob": "^2.1.1"
1435 | }
1436 | },
1437 | "is-number": {
1438 | "version": "7.0.0",
1439 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1440 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1441 | "dev": true
1442 | },
1443 | "is-plain-obj": {
1444 | "version": "2.1.0",
1445 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
1446 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
1447 | "dev": true
1448 | },
1449 | "is-unicode-supported": {
1450 | "version": "0.1.0",
1451 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
1452 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
1453 | "dev": true
1454 | },
1455 | "isexe": {
1456 | "version": "2.0.0",
1457 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1458 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1459 | "dev": true
1460 | },
1461 | "js-yaml": {
1462 | "version": "4.1.0",
1463 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
1464 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
1465 | "dev": true,
1466 | "requires": {
1467 | "argparse": "^2.0.1"
1468 | }
1469 | },
1470 | "locate-path": {
1471 | "version": "6.0.0",
1472 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
1473 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
1474 | "dev": true,
1475 | "requires": {
1476 | "p-locate": "^5.0.0"
1477 | }
1478 | },
1479 | "log-symbols": {
1480 | "version": "4.1.0",
1481 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
1482 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
1483 | "dev": true,
1484 | "requires": {
1485 | "chalk": "^4.1.0",
1486 | "is-unicode-supported": "^0.1.0"
1487 | }
1488 | },
1489 | "minimatch": {
1490 | "version": "4.2.1",
1491 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
1492 | "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
1493 | "dev": true,
1494 | "requires": {
1495 | "brace-expansion": "^1.1.7"
1496 | }
1497 | },
1498 | "mocha": {
1499 | "version": "9.2.2",
1500 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
1501 | "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
1502 | "dev": true,
1503 | "requires": {
1504 | "@ungap/promise-all-settled": "1.1.2",
1505 | "ansi-colors": "4.1.1",
1506 | "browser-stdout": "1.3.1",
1507 | "chokidar": "3.5.3",
1508 | "debug": "4.3.3",
1509 | "diff": "5.0.0",
1510 | "escape-string-regexp": "4.0.0",
1511 | "find-up": "5.0.0",
1512 | "glob": "7.2.0",
1513 | "growl": "1.10.5",
1514 | "he": "1.2.0",
1515 | "js-yaml": "4.1.0",
1516 | "log-symbols": "4.1.0",
1517 | "minimatch": "4.2.1",
1518 | "ms": "2.1.3",
1519 | "nanoid": "3.3.1",
1520 | "serialize-javascript": "6.0.0",
1521 | "strip-json-comments": "3.1.1",
1522 | "supports-color": "8.1.1",
1523 | "which": "2.0.2",
1524 | "workerpool": "6.2.0",
1525 | "yargs": "16.2.0",
1526 | "yargs-parser": "20.2.4",
1527 | "yargs-unparser": "2.0.0"
1528 | }
1529 | },
1530 | "ms": {
1531 | "version": "2.1.3",
1532 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1533 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1534 | "dev": true
1535 | },
1536 | "nanoid": {
1537 | "version": "3.3.1",
1538 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
1539 | "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
1540 | "dev": true
1541 | },
1542 | "normalize-path": {
1543 | "version": "3.0.0",
1544 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1545 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1546 | "dev": true
1547 | },
1548 | "once": {
1549 | "version": "1.4.0",
1550 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1551 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
1552 | "dev": true,
1553 | "requires": {
1554 | "wrappy": "1"
1555 | }
1556 | },
1557 | "p-limit": {
1558 | "version": "3.1.0",
1559 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
1560 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
1561 | "dev": true,
1562 | "requires": {
1563 | "yocto-queue": "^0.1.0"
1564 | }
1565 | },
1566 | "p-locate": {
1567 | "version": "5.0.0",
1568 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
1569 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
1570 | "dev": true,
1571 | "requires": {
1572 | "p-limit": "^3.0.2"
1573 | }
1574 | },
1575 | "path-exists": {
1576 | "version": "4.0.0",
1577 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
1578 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
1579 | "dev": true
1580 | },
1581 | "path-is-absolute": {
1582 | "version": "1.0.1",
1583 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1584 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
1585 | "dev": true
1586 | },
1587 | "pathval": {
1588 | "version": "1.1.1",
1589 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
1590 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
1591 | "dev": true
1592 | },
1593 | "picomatch": {
1594 | "version": "2.3.1",
1595 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1596 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1597 | "dev": true
1598 | },
1599 | "randombytes": {
1600 | "version": "2.1.0",
1601 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
1602 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
1603 | "dev": true,
1604 | "requires": {
1605 | "safe-buffer": "^5.1.0"
1606 | }
1607 | },
1608 | "readdirp": {
1609 | "version": "3.6.0",
1610 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1611 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1612 | "dev": true,
1613 | "requires": {
1614 | "picomatch": "^2.2.1"
1615 | }
1616 | },
1617 | "require-directory": {
1618 | "version": "2.1.1",
1619 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1620 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
1621 | "dev": true
1622 | },
1623 | "safe-buffer": {
1624 | "version": "5.2.1",
1625 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1626 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1627 | "dev": true
1628 | },
1629 | "serialize-javascript": {
1630 | "version": "6.0.0",
1631 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
1632 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
1633 | "dev": true,
1634 | "requires": {
1635 | "randombytes": "^2.1.0"
1636 | }
1637 | },
1638 | "string-width": {
1639 | "version": "4.2.3",
1640 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1641 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1642 | "dev": true,
1643 | "requires": {
1644 | "emoji-regex": "^8.0.0",
1645 | "is-fullwidth-code-point": "^3.0.0",
1646 | "strip-ansi": "^6.0.1"
1647 | }
1648 | },
1649 | "strip-ansi": {
1650 | "version": "6.0.1",
1651 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1652 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1653 | "dev": true,
1654 | "requires": {
1655 | "ansi-regex": "^5.0.1"
1656 | }
1657 | },
1658 | "strip-json-comments": {
1659 | "version": "3.1.1",
1660 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
1661 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
1662 | "dev": true
1663 | },
1664 | "supports-color": {
1665 | "version": "8.1.1",
1666 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
1667 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
1668 | "dev": true,
1669 | "requires": {
1670 | "has-flag": "^4.0.0"
1671 | }
1672 | },
1673 | "to-regex-range": {
1674 | "version": "5.0.1",
1675 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1676 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1677 | "dev": true,
1678 | "requires": {
1679 | "is-number": "^7.0.0"
1680 | }
1681 | },
1682 | "type-detect": {
1683 | "version": "4.0.8",
1684 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
1685 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
1686 | "dev": true
1687 | },
1688 | "typescript": {
1689 | "version": "4.5.2",
1690 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
1691 | "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==",
1692 | "dev": true
1693 | },
1694 | "which": {
1695 | "version": "2.0.2",
1696 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
1697 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
1698 | "dev": true,
1699 | "requires": {
1700 | "isexe": "^2.0.0"
1701 | }
1702 | },
1703 | "workerpool": {
1704 | "version": "6.2.0",
1705 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
1706 | "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
1707 | "dev": true
1708 | },
1709 | "wrap-ansi": {
1710 | "version": "7.0.0",
1711 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1712 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1713 | "dev": true,
1714 | "requires": {
1715 | "ansi-styles": "^4.0.0",
1716 | "string-width": "^4.1.0",
1717 | "strip-ansi": "^6.0.0"
1718 | }
1719 | },
1720 | "wrappy": {
1721 | "version": "1.0.2",
1722 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1723 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
1724 | "dev": true
1725 | },
1726 | "y18n": {
1727 | "version": "5.0.8",
1728 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1729 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1730 | "dev": true
1731 | },
1732 | "yargs": {
1733 | "version": "16.2.0",
1734 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
1735 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
1736 | "dev": true,
1737 | "requires": {
1738 | "cliui": "^7.0.2",
1739 | "escalade": "^3.1.1",
1740 | "get-caller-file": "^2.0.5",
1741 | "require-directory": "^2.1.1",
1742 | "string-width": "^4.2.0",
1743 | "y18n": "^5.0.5",
1744 | "yargs-parser": "^20.2.2"
1745 | }
1746 | },
1747 | "yargs-parser": {
1748 | "version": "20.2.4",
1749 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
1750 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
1751 | "dev": true
1752 | },
1753 | "yargs-unparser": {
1754 | "version": "2.0.0",
1755 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
1756 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
1757 | "dev": true,
1758 | "requires": {
1759 | "camelcase": "^6.0.0",
1760 | "decamelize": "^4.0.0",
1761 | "flat": "^5.0.2",
1762 | "is-plain-obj": "^2.1.0"
1763 | }
1764 | },
1765 | "yocto-queue": {
1766 | "version": "0.1.0",
1767 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
1768 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
1769 | "dev": true
1770 | }
1771 | }
1772 | }
1773 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jdk-utils",
3 | "version": "0.5.1",
4 | "description": "JDK related utils for Java related development.",
5 | "main": "dist/index.js",
6 | "bin": "bin/cli.js",
7 | "scripts": {
8 | "prepack": "npm run build",
9 | "build": "tsc",
10 | "test": "npm run build && mocha --reporter spec"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/Eskibear/node-jdk-utils.git"
15 | },
16 | "author": "Eskibear",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/Eskibear/node-jdk-utils/issues"
20 | },
21 | "homepage": "https://github.com/Eskibear/node-jdk-utils#readme",
22 | "devDependencies": {
23 | "@types/node": "^16.11.8",
24 | "chai": "^4.3.4",
25 | "mocha": "^9.2.2",
26 | "typescript": "^4.5.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/from/asdf.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 |
6 | const ASDF_DATA_DIR = process.env.ASDF_DATA_DIR ?? path.join(os.homedir(), ".asdf");
7 | const JDK_BASE_DIR = path.join(ASDF_DATA_DIR, "installs", "java");
8 |
9 | export async function candidates(): Promise {
10 | const ret = [];
11 | try {
12 | const files = await fs.promises.readdir(JDK_BASE_DIR, { withFileTypes: true });
13 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(JDK_BASE_DIR, file.name));
14 | ret.push(...homedirs);
15 | } catch (error) {
16 | log(error);
17 | }
18 | return ret;
19 | }
--------------------------------------------------------------------------------
/src/from/envs.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as path from "path";
3 | import { expandTilde, getRealHome, looksLikeJavaHome, JAVA_FILENAME, isMac } from "../utils";
4 |
5 | const EXCLUSIONS_ON_MAC: Set = new Set([
6 | "/usr",
7 | "/usr/"
8 | ]);
9 | export async function candidatesFromPath(): Promise {
10 | const ret = [];
11 | if (process.env.PATH) {
12 | const jdkBinFolderFromPath = process.env.PATH.split(path.delimiter)
13 | .filter(p => looksLikeJavaHome(p) || fs.existsSync(path.join(p, JAVA_FILENAME)))
14 | .map(expandTilde); // '~' can occur in envs in Unix-like systems
15 |
16 | /**
17 | * Fix for https://github.com/Eskibear/node-jdk-utils/issues/2
18 | * Homebrew creates symbolic links for each binary instead of folder.
19 | */
20 | const homeDirs = (await Promise.all(jdkBinFolderFromPath.map(p => getRealHome(path.dirname(p))))).filter(homeDir => {
21 | /**
22 | * Fix for https://github.com/Eskibear/node-jdk-utils/issues/15
23 | * /usr/bin/java is a preserved shortcut program on macOS, which is not a real java home.
24 | */
25 | return homeDir && !(isMac && EXCLUSIONS_ON_MAC.has(homeDir));
26 | });
27 | ret.push(...homeDirs);
28 | }
29 | return ret.filter(Boolean) as string[];
30 | }
31 |
32 | export async function candidatesFromSpecificEnv(envkey: string): Promise {
33 | if (process.env[envkey]) {
34 | const rmSlash = process.env[envkey]!.replace(/[\\\/]$/, ""); // remove trailing slash if exists
35 | return getRealHome(rmSlash);
36 | }
37 | return undefined;
38 | }
39 |
--------------------------------------------------------------------------------
/src/from/gradle.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 | import { isMac } from "../utils";
6 |
7 | /*
8 | * Gradle Toolchains JDKs path format
9 | *
10 | * Windows
11 | * >cd %HOMEPATH%\.gradle\jdks
12 | * >wsl find ./ -type f -name java.exe
13 | * ./adoptopenjdk-15-amd64-windows/jdk-15.0.2+7/bin/java.exe
14 | * ./amazon_com_inc_-18-amd64-windows/jdk18.0.2_9/bin/java.exe
15 | * ./eclipse_adoptium-18-amd64-windows/jdk-18.0.2.1+1/bin/java.exe
16 | *
17 | * macOS
18 | * $ cd ~/.gradle/jdks
19 | * $ find ./ -type f -name java
20 | * ./adoptopenjdk-15-x64-mac_hotspot/jdk-15.0.2+7/Contents/Home/bin/java
21 | * ./amazon_com_inc_-18-x64-mac_hotspot/jdk18.0.2_9/Contents/Home/bin/java
22 | * ./eclipse_adoptium-18-x64-mac_hotspot/jdk-18.0.2.1+1/Contents/Home/bin/java
23 | *
24 | * Linux
25 | * $ cd ~/.gradle/jdks
26 | * $ find ./ -type f -name java
27 | * ./adoptopenjdk-15-amd64-linux/jdk-15.0.2+7/bin/java
28 | * ./amazon_com_inc_-18-amd64-linux/18.0.2.9.1/bin/java
29 | * ./eclipse_adoptium-18-amd64-linux/jdk-18.0.2.1+1/bin/java
30 | *
31 | * See https://docs.gradle.org/8.1/userguide/toolchains.html
32 | */
33 | const GRADLE_USER_HOME = process.env.GRADLE_USER_HOME ?? path.join(os.homedir(), ".gradle");
34 | const JDK_BASE_DIR = path.join(GRADLE_USER_HOME, "jdks");
35 |
36 | export async function candidates(): Promise {
37 | const ret = [];
38 | try {
39 | for (const distro of await fs.promises.readdir(JDK_BASE_DIR, { withFileTypes: true })) {
40 | if (distro.isDirectory()) {
41 | const distroDir = path.join(JDK_BASE_DIR, distro.name);
42 | const files = await fs.promises.readdir(distroDir, { withFileTypes: true });
43 | const homedirs = files.filter(file => file.isDirectory()).map(file => {
44 | if (isMac) {
45 | return path.join(distroDir, file.name, "Contents", "Home");
46 | } else {
47 | return path.join(distroDir, file.name);
48 | }
49 | });
50 | ret.push(...homedirs);
51 | }
52 | }
53 | } catch (error) {
54 | log(error);
55 | }
56 | return ret;
57 | }
--------------------------------------------------------------------------------
/src/from/homebrew.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as path from "path";
3 | import { log } from "../logger";
4 | import { deDup, getRealHome, looksLikeJavaHome } from "../utils";
5 |
6 | /*
7 | $ ls -l /usr/local/opt
8 | openjdk -> ../Cellar/openjdk/15.0.1
9 | openjdk@11 -> ../Cellar/openjdk@11/11.0.12
10 | openjdk@15 -> ../Cellar/openjdk/15.0.1
11 |
12 | $ ls -l /usr/local/opt/openjdk/bin/java
13 | /usr/local/opt/openjdk/bin/java -> ../libexec/openjdk.jdk/Contents/Home/bin/java
14 |
15 | # Real path is:
16 | # /usr/local/Cellar/openjdk/15.0.1/libexec/openjdk.jdk/Contents/Home/bin/java
17 |
18 | */
19 |
20 | /**
21 | * See: https://docs.brew.sh/Installation
22 | */
23 | export const HOMEBREW_DIR_INTEL = "/usr/local/opt";
24 | export const HOMEBREW_DIR_APPLE_SILLICON = "/opt/homebrew/opt";
25 | export const HOMEBREW_DIR_LINUX = "/home/linuxbrew/.linuxbrew/opt";
26 |
27 | export async function candidates(homebrewOptPath: string): Promise {
28 | const ret = [];
29 | try {
30 | const files = await fs.promises.readdir(homebrewOptPath, { withFileTypes: true });
31 | const homeDirLinks = files.filter(file => file.isSymbolicLink() && looksLikeJavaHome(file.name)).map(file => path.join(homebrewOptPath, file.name));
32 |
33 | const actualHomeDirs = await Promise.all(deDup(homeDirLinks).map(file => getRealHome(file)))
34 | ret.push(...actualHomeDirs);
35 | } catch (error) {
36 | log(error);
37 | }
38 | return ret.filter(Boolean) as string[];
39 | }
40 |
--------------------------------------------------------------------------------
/src/from/jabba.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 |
6 | const JABBA_DIR = path.join(os.homedir(), ".jabba");
7 | const JDK_BASE_DIR = path.join(JABBA_DIR, "jdk");
8 |
9 | export async function candidates(): Promise {
10 | const ret = [];
11 | try {
12 | const files = await fs.promises.readdir(JDK_BASE_DIR, { withFileTypes: true });
13 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(JDK_BASE_DIR, file.name));
14 | ret.push(...homedirs);
15 | } catch (error) {
16 | log(error);
17 | }
18 | return ret;
19 | }
--------------------------------------------------------------------------------
/src/from/jbang.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 |
6 | const JBANG_DIR = process.env.JBANG_DIR ?? path.join(os.homedir(), ".jbang");
7 | const JDK_BASE_DIR = path.join(JBANG_DIR, "cache", "jdks");
8 |
9 | export async function candidates(): Promise {
10 | const ret = [];
11 | try {
12 | const files = await fs.promises.readdir(JDK_BASE_DIR, { withFileTypes: true });
13 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(JDK_BASE_DIR, file.name));
14 | ret.push(...homedirs);
15 | } catch (error) {
16 | log(error);
17 | }
18 | return ret;
19 | }
--------------------------------------------------------------------------------
/src/from/jenv.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 | import { deDup } from "../utils";
6 |
7 | const JENV_DIR = path.join(os.homedir(), ".jenv");
8 | const JDK_LINK_BASE_DIR = path.join(JENV_DIR, "versions");
9 |
10 | export async function candidates(): Promise {
11 | const ret = [];
12 | try {
13 | const files = await fs.promises.readdir(JDK_LINK_BASE_DIR, { withFileTypes: true });
14 | const homeDirLinks = files.filter(file => file.isSymbolicLink()).map(file => path.join(JDK_LINK_BASE_DIR, file.name));
15 | const actualHomeDirs = await Promise.all(homeDirLinks.map(file => fs.promises.realpath(file)))
16 | const uniqHomes = deDup(actualHomeDirs);
17 | ret.push(...uniqHomes);
18 | } catch (error) {
19 | log(error);
20 | }
21 | return ret;
22 | }
--------------------------------------------------------------------------------
/src/from/linux.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as path from "path";
3 | import { log } from "../logger";
4 |
5 | const JDK_BASE_DIRS = [
6 | "/usr/lib/jvm", // Ubuntu
7 | "/usr/java", // Java 8 on CentOS?
8 | // ... add more if necessary
9 | ];
10 |
11 | export async function candidates(): Promise {
12 | const ret = [];
13 | for (const baseDir of JDK_BASE_DIRS) {
14 | try {
15 | const files = await fs.promises.readdir(baseDir, { withFileTypes: true });
16 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(baseDir, file.name));
17 | ret.push(...homedirs);
18 | } catch (error) {
19 | log(error);
20 | }
21 | }
22 | return ret;
23 | }
--------------------------------------------------------------------------------
/src/from/macOS.ts:
--------------------------------------------------------------------------------
1 | import * as cp from "child_process";
2 | import * as fs from "fs";
3 | import * as os from "os";
4 | import * as path from "path";
5 | import { log } from "../logger";
6 | import { deDup } from "../utils";
7 |
8 | const JDK_BASE_DIRS = [
9 | "/Library/Java/JavaVirtualMachines",
10 | path.join(os.homedir(), "Library/Java/JavaVirtualMachines")
11 | ];
12 |
13 | export async function candidates(): Promise {
14 | const ret: string[] = [];
15 | ret.push(...await fromJavaHomeUtil());
16 | ret.push(...await fromDefaultIntallationLocation());
17 | return deDup(ret);
18 | }
19 |
20 | async function fromDefaultIntallationLocation(): Promise {
21 | const ret = [];
22 | for (const baseDir of JDK_BASE_DIRS) {
23 | try {
24 | const files = await fs.promises.readdir(baseDir, { withFileTypes: true });
25 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(baseDir, file.name, "Contents", "Home" /** macOS specific subfolder */));
26 | ret.push(...homedirs);
27 | } catch (error) {
28 | log(error);
29 | }
30 | }
31 | return ret;
32 | }
33 |
34 | /**
35 | * from `/usr/libexec/java_home -V`
36 | * @returns list of jvm homes
37 | */
38 | async function fromJavaHomeUtil(): Promise {
39 | const ret: string[] = [];
40 | const javaHomeUtility = "/usr/libexec/java_home";
41 | try {
42 | await fs.promises.access(javaHomeUtility, fs.constants.F_OK);
43 | await new Promise((resolve, _reject) => {
44 | cp.execFile(javaHomeUtility, ["-V"], {}, (_error, _stdout, stderr) => {
45 | const regexp = /".*" - ".*" (.*)/g;
46 | let match;
47 | do{
48 | match = regexp.exec(stderr);
49 | if (match) {
50 | ret.push(match[1]);
51 | }
52 | } while (match !== null);
53 | resolve();
54 | });
55 | });
56 | } catch (e) {
57 | log(e);
58 | }
59 | return ret;
60 | }
61 |
--------------------------------------------------------------------------------
/src/from/sdkman.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 |
6 | const SDKMAN_DIR = process.env.SDKMAN_DIR ?? path.join(os.homedir(), ".sdkman");
7 | const JDK_BASE_DIR = path.join(SDKMAN_DIR, "candidates", "java");
8 |
9 | export async function candidates(): Promise {
10 | const ret = [];
11 | try {
12 | const files = await fs.promises.readdir(JDK_BASE_DIR, { withFileTypes: true });
13 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(JDK_BASE_DIR, file.name));
14 | ret.push(...homedirs);
15 | } catch (error) {
16 | log(error);
17 | }
18 | return ret;
19 | }
--------------------------------------------------------------------------------
/src/from/windows.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import * as os from "os";
3 | import * as path from "path";
4 | import { log } from "../logger";
5 | import { looksLikeJavaHome } from "../utils";
6 |
7 | const PROGRAM_DIRS = Array.from(new Set([
8 | process.env.ProgramW6432,
9 | process.env.ProgramFiles,
10 | process.env.LOCALAPPDATA,
11 | path.join(os.homedir(), "AppData", "Local")
12 | ])).filter(Boolean) as string[];
13 |
14 | const POPULAR_DISTRIBUTIONS = [
15 | "Eclipse Foundation", // Adoptium
16 | "Eclipse Adoptium", // Eclipse Temurin
17 | "Java", // Oracle Java SE
18 | "Amazon Corretto",
19 | "Microsoft", // Microsoft OpenJDK
20 | path.join("SapMachine", "JDK"), // SAP Machine
21 | "Zulu", // Azul OpenJDK
22 | ];
23 |
24 | export async function candidates(): Promise {
25 | const ret = [];
26 | for (const programDir of PROGRAM_DIRS) {
27 | for (const distro of POPULAR_DISTRIBUTIONS) {
28 | const baseDir = path.join(programDir, distro);
29 | try {
30 | const files = await fs.promises.readdir(baseDir, { withFileTypes: true });
31 | const homedirs = files.filter(file => file.isDirectory()).map(file => path.join(baseDir, file.name));
32 | ret.push(...homedirs);
33 | } catch (error) {
34 | log(error);
35 | }
36 | }
37 | }
38 | return ret.filter(looksLikeJavaHome);
39 | }
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as cp from "child_process";
2 | import * as fs from "fs";
3 | import * as path from "path";
4 | import * as jbang from "./from/jbang";
5 | import * as asdf from "./from/asdf";
6 | import * as envs from "./from/envs";
7 | import * as gradle from "./from/gradle";
8 | import * as homebrew from "./from/homebrew";
9 | import * as jabba from "./from/jabba";
10 | import * as jenv from "./from/jenv";
11 | import * as linux from "./from/linux";
12 | import * as macOS from "./from/macOS";
13 | import * as sdkman from "./from/sdkman";
14 | import * as windows from "./from/windows";
15 | import * as logger from "./logger";
16 | import { deDup, isArm, isLinux, isMac, isWindows, JAVAC_FILENAME, JAVA_FILENAME } from "./utils";
17 |
18 | export { JAVAC_FILENAME, JAVA_FILENAME } from "./utils";
19 |
20 | export interface IOptions {
21 | /**
22 | * whether to parse version.
23 | */
24 | withVersion?: boolean;
25 | /**
26 | * whether to check existence of javac or javac.exe
27 | */
28 | checkJavac?: boolean;
29 | /**
30 | * whether to include tags for detailed information
31 | */
32 | withTags?: boolean;
33 |
34 | /**
35 | * whether to skip resolving from a specific source
36 | */
37 | skipFrom?: {
38 | /**
39 | * from env.JAVA_HOME
40 | */
41 | javaHomeEnv?: boolean;
42 | /**
43 | * from env.JDK_HOME
44 | */
45 | jdkHomeEnv?: boolean;
46 | /**
47 | * from env.PATH
48 | */
49 | inPathEnv?: boolean;
50 | /**
51 | * from SDKMAN
52 | */
53 | sdkman?: boolean;
54 | /**
55 | * from JENV
56 | */
57 | jenv?: boolean;
58 | /**
59 | * from Jabba
60 | */
61 | jabba?: boolean;
62 | /**
63 | * from ASDF
64 | */
65 | asdf?: boolean;
66 | /**
67 | * from Gradle locations
68 | */
69 | gradle?: boolean;
70 | /**
71 | * from JBang locations
72 | */
73 | jbang?: boolean;
74 | };
75 | }
76 |
77 | export interface IJavaVersion {
78 | java_version: string;
79 | major: number;
80 | }
81 |
82 | export interface IJavaRuntime {
83 | /**
84 | * Home directory of Java runtime.
85 | */
86 | homedir: string;
87 | /**
88 | * Version information.
89 | */
90 | version?: IJavaVersion;
91 | /**
92 | * Whether javac or javac.exe exists.
93 | */
94 | hasJavac?: boolean;
95 |
96 | /**
97 | * whether is same as env.JAVA_HOME
98 | */
99 | isJavaHomeEnv?: boolean;
100 |
101 | /**
102 | * whether is same as env.JDK_HOME
103 | */
104 | isJdkHomeEnv?: boolean;
105 |
106 | /**
107 | * whether '/bin' is one of env.PATH entries
108 | */
109 | isInPathEnv?: boolean;
110 |
111 | isFromSDKMAN?: boolean;
112 | isFromJENV?: boolean;
113 | isFromJabba?: boolean;
114 | isFromJBang?: boolean;
115 | isFromASDF?: boolean;
116 | isFromGradle?: boolean;
117 | }
118 |
119 | /**
120 | * Find Java runtime from all possible locations on your machine.
121 | *
122 | * @param options advanced options
123 | * @returns
124 | */
125 | export async function findRuntimes(options?: IOptions): Promise {
126 | const store = new RuntimeStore();
127 | const candidates: string[] = [];
128 |
129 | const updateCandidates = (homedirs: string[], updater?: (r: IJavaRuntime) => IJavaRuntime) => {
130 | if (options?.withTags) {
131 | store.updateRuntimes(homedirs, updater);
132 | } else {
133 | candidates.push(...homedirs);
134 | }
135 | }
136 |
137 | // SDKMAN
138 | if (!options?.skipFrom?.sdkman) {
139 | const fromSdkman = await sdkman.candidates();
140 | updateCandidates(fromSdkman, (r) => ({ ...r, isFromSDKMAN: true }));
141 | }
142 |
143 | // platform-specific default location
144 | if (isLinux) {
145 | updateCandidates(await linux.candidates());
146 | updateCandidates(await homebrew.candidates(homebrew.HOMEBREW_DIR_LINUX)); // Homebrew
147 | }
148 | if (isMac) {
149 | updateCandidates(await macOS.candidates());
150 | const hbOptPath = isArm ? homebrew.HOMEBREW_DIR_APPLE_SILLICON : homebrew.HOMEBREW_DIR_INTEL;
151 | updateCandidates(await homebrew.candidates(hbOptPath)); // Homebrew
152 | }
153 | if (isWindows) {
154 | updateCandidates(await windows.candidates());
155 | }
156 |
157 | // from env: JDK_HOME
158 | if (!options?.skipFrom?.jdkHomeEnv) {
159 | const fromJdkHome = await envs.candidatesFromSpecificEnv("JDK_HOME");
160 | if (fromJdkHome) {
161 | updateCandidates([fromJdkHome], (r) => ({ ...r, isJdkHomeEnv: true }));
162 | }
163 | }
164 |
165 | // from env: JAVA_HOME
166 | if (!options?.skipFrom?.javaHomeEnv) {
167 | const fromJavaHome = await envs.candidatesFromSpecificEnv("JAVA_HOME");
168 | if (fromJavaHome) {
169 | updateCandidates([fromJavaHome], (r) => ({ ...r, isJavaHomeEnv: true }));
170 | }
171 | }
172 |
173 | // from env: PATH
174 | if (!options?.skipFrom?.inPathEnv) {
175 | const fromPath = await envs.candidatesFromPath();
176 | updateCandidates(fromPath, (r) => ({ ...r, isInPathEnv: true }));
177 | }
178 |
179 | // jEnv
180 | if (!options?.skipFrom?.jenv) {
181 | const fromJENV = await jenv.candidates();
182 | updateCandidates(fromJENV, (r) => ({ ...r, isFromJENV: true }));
183 | }
184 |
185 | // jabba
186 | if (!options?.skipFrom?.jabba) {
187 | const fromJabba = await jabba.candidates();
188 | updateCandidates(fromJabba, (r) => ({ ...r, isFromJabba: true }));
189 | }
190 |
191 | // jbang
192 | if (!options?.skipFrom?.jbang) {
193 | const fromJBang = await jbang.candidates();
194 | updateCandidates(fromJBang, (r) => ({ ...r, isFromJBang: true }));
195 | }
196 | // asdf
197 | if (!options?.skipFrom?.asdf) {
198 | const fromASDF = await asdf.candidates();
199 | updateCandidates(fromASDF, (r) => ({ ...r, isFromASDF: true }));
200 | }
201 |
202 | // Gradle
203 | if (!options?.skipFrom?.gradle) {
204 | const fromGradle = await gradle.candidates();
205 | updateCandidates(fromGradle, (r) => ({ ...r, isFromGradle: true }));
206 | }
207 |
208 | // dedup and construct runtimes
209 | let runtimes: IJavaRuntime[] = options?.withTags ? store.allRuntimes()
210 | : deDup(candidates).map((homedir) => ({ homedir }));
211 |
212 | // verification
213 | if (true /* always check java binary */) {
214 | runtimes = await Promise.all(runtimes.map(checkJavaFile));
215 | if (true /* java binary is required for a valid runtime */) {
216 | runtimes = (runtimes as Array).filter(r => r.isValid);
217 | }
218 | }
219 |
220 | if (options?.checkJavac) {
221 | runtimes = await Promise.all(runtimes.map(checkJavacFile));
222 | }
223 |
224 | if (options?.withVersion) {
225 | runtimes = await Promise.all(runtimes.map(parseVersion));
226 | }
227 |
228 | // clean up private fields by default
229 | for (const r of runtimes) {
230 | delete (r as CanValidate).isValid;
231 | }
232 |
233 | return runtimes;
234 | }
235 |
236 | /**
237 | * Verify if given directory contains a valid Java runtime, and provide details if it is.
238 | *
239 | * @param homedir home directory of a Java runtime
240 | * @param options
241 | * @returns
242 | */
243 | export async function getRuntime(homedir: string, options?: IOptions): Promise {
244 | let runtime: IJavaRuntime = { homedir };
245 | runtime = await checkJavaFile(runtime);
246 | if (!(runtime as CanValidate).isValid) {
247 | return undefined;
248 | }
249 |
250 | if (options?.checkJavac) {
251 | runtime = await checkJavacFile(runtime);
252 | }
253 | if (options?.withVersion) {
254 | runtime = await parseVersion(runtime);
255 | }
256 |
257 | if (options?.withTags) {
258 | const gList = await gradle.candidates();
259 | if (gList.includes(homedir)) {
260 | runtime.isFromGradle = true;
261 | }
262 | const jbangList = await jbang.candidates();
263 | if (jbangList.includes(homedir)) {
264 | runtime.isFromJBang = true;
265 | }
266 | const aList = await asdf.candidates();
267 | if (aList.includes(homedir)) {
268 | runtime.isFromASDF = true;
269 | }
270 | const jList = await jenv.candidates();
271 | if (jList.includes(homedir)) {
272 | runtime.isFromJENV = true;
273 | }
274 | const sList = await sdkman.candidates();
275 | if (sList.includes(homedir)) {
276 | runtime.isFromSDKMAN = true;
277 | }
278 | const jbList = await jabba.candidates();
279 | if (jbList.includes(homedir)) {
280 | runtime.isFromJabba = true;
281 | }
282 | const pList = await envs.candidatesFromPath();
283 | if (pList.includes(homedir)) {
284 | runtime.isInPathEnv = true;
285 | }
286 | if (await envs.candidatesFromSpecificEnv("JAVA_HOME") === homedir) {
287 | runtime.isJavaHomeEnv = true;
288 | }
289 | if (await envs.candidatesFromSpecificEnv("JDK_HOME") === homedir) {
290 | runtime.isJdkHomeEnv = true;
291 | }
292 | }
293 | return runtime;
294 | }
295 |
296 | /**
297 | * A utility to list all sources where given Java runtime is found.
298 | *
299 | * @param r given IJavaRuntime
300 | * @returns list of sources where given runtime is found.
301 | */
302 | export function getSources(r: IJavaRuntime): string[] {
303 | const sources: string[] = [];
304 | if (r.isJdkHomeEnv) {
305 | sources.push("JDK_HOME");
306 | }
307 | if (r.isJavaHomeEnv) {
308 | sources.push("JAVA_HOME");
309 | }
310 | if (r.isInPathEnv) {
311 | sources.push("PATH");
312 | }
313 | if (r.isFromSDKMAN) {
314 | sources.push("SDKMAN");
315 | }
316 | if (r.isFromJENV) {
317 | sources.push("jEnv");
318 | }
319 | if (r.isFromJabba) {
320 | sources.push("jabba");
321 | }
322 | if (r.isFromJBang) {
323 | sources.push("JBang");
324 | }
325 | if (r.isFromASDF) {
326 | sources.push("asdf");
327 | }
328 | if (r.isFromGradle) {
329 | sources.push("Gradle");
330 | }
331 | return sources;
332 | }
333 |
334 | async function checkJavaFile(runtime: IJavaRuntime): Promise {
335 | const { homedir } = runtime;
336 | const binary = path.join(homedir, "bin", JAVA_FILENAME);
337 | try {
338 | await fs.promises.access(binary, fs.constants.F_OK);
339 | (runtime as IJavaRuntime & CanValidate).isValid = true;
340 | } catch (error) {
341 | (runtime as IJavaRuntime & CanValidate).isValid = false;
342 | }
343 | return runtime as IJavaRuntime & CanValidate;
344 | }
345 |
346 | async function checkJavacFile(runtime: IJavaRuntime): Promise {
347 | const { homedir } = runtime;
348 | const binary = path.join(homedir, "bin", JAVAC_FILENAME);
349 | try {
350 | await fs.promises.access(binary, fs.constants.F_OK);
351 | runtime.hasJavac = true;
352 | } catch (error) {
353 | runtime.hasJavac = false;
354 | }
355 | return runtime;
356 | }
357 |
358 | async function parseVersion(runtime: IJavaRuntime): Promise {
359 | const { homedir } = runtime;
360 | const releaseFile = path.join(homedir, "release");
361 | try {
362 | const content = await fs.promises.readFile(releaseFile, { encoding: "utf-8" });
363 | const regexp = /^JAVA_VERSION="(.*)"/gm;
364 | const match = regexp.exec(content.toString());
365 | if (!match) {
366 | return runtime;
367 | }
368 | const java_version = match[1];
369 | const major = parseMajorVersion(java_version);
370 |
371 | runtime.version = {
372 | java_version,
373 | major
374 | };
375 | } catch (error) {
376 | logger.log(error);
377 | }
378 |
379 | if (runtime.version === undefined) {
380 | // fallback to check version by CLI
381 | try {
382 | runtime.version = await checkJavaVersionByCLI(homedir);
383 | } catch (error) {
384 | logger.log(error);
385 | }
386 | }
387 |
388 | return runtime;
389 | }
390 |
391 | /**
392 | * Get version by parsing `JAVA_HOME/bin/java -version`, make sure binary file exists.
393 | * @deprecated as a fallback when file "release" not found
394 | */
395 | async function checkJavaVersionByCLI(javaHome: string): Promise {
396 | return new Promise((resolve, _reject) => {
397 | const javaBin = path.join(javaHome, "bin", JAVA_FILENAME); // assume java binary exists.
398 | cp.execFile(javaBin, ["-version"], {}, (_error, _stdout, stderr) => {
399 | const regexp = /version "(.*)"/g;
400 | const match = regexp.exec(stderr);
401 | if (!match) {
402 | return resolve(undefined);
403 | }
404 | const java_version = match[1];
405 | const major = parseMajorVersion(java_version);
406 | resolve({
407 | java_version,
408 | major
409 | });
410 | });
411 | });
412 | }
413 |
414 | function parseMajorVersion(version: string): number {
415 | if (!version) {
416 | return 0;
417 | }
418 | // Ignore '1.' prefix for legacy Java versions
419 | if (version.startsWith("1.")) {
420 | version = version.substring(2);
421 | }
422 | // look into the interesting bits now
423 | const regexp = /\d+/g;
424 | const match = regexp.exec(version);
425 | let javaVersion = 0;
426 | if (match) {
427 | javaVersion = parseInt(match[0]);
428 | }
429 | return javaVersion;
430 | }
431 |
432 | class RuntimeStore {
433 | private map: Map = new Map();
434 | constructor() { }
435 |
436 | public updateRuntimes(homedirs: string[], updater?: (r: IJavaRuntime) => IJavaRuntime) {
437 | for (const h of homedirs) {
438 | this.updateRuntime(h, updater);
439 | }
440 | }
441 |
442 | public updateRuntime(homedir: string, updater?: (r: IJavaRuntime) => IJavaRuntime) {
443 | const runtime = this.map.get(homedir) || { homedir };
444 | this.map.set(homedir, updater?.(runtime) ?? runtime);
445 | }
446 |
447 | public allRuntimes() {
448 | return Array.from(this.map.values());
449 | }
450 | }
451 |
452 | interface CanValidate {
453 | /**
454 | * Whether java or java.exe exists, indicating it's a valid runtime.
455 | */
456 | isValid?: boolean;
457 | }
458 |
--------------------------------------------------------------------------------
/src/logger.ts:
--------------------------------------------------------------------------------
1 | export function log(...args: any[]) {
2 | // to implement
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils.ts:
--------------------------------------------------------------------------------
1 | import * as fs from "fs";
2 | import { homedir } from "os";
3 | import { dirname, join } from "path";
4 | import * as logger from "./logger";
5 |
6 | // platform
7 | export const isWindows: boolean = process.platform.indexOf("win") === 0;
8 | export const isMac: boolean = process.platform.indexOf("darwin") === 0;
9 | export const isLinux: boolean = process.platform.indexOf("linux") === 0;
10 |
11 | // arch
12 | export const isArm: boolean = process.arch.indexOf("arm") === 0; // used to distinguish macOS Intel/Apple Sillicon
13 |
14 | export const JAVA_FILENAME = isWindows ? "java.exe" : "java";
15 | export const JAVAC_FILENAME = isWindows ? "javac.exe" : "javac";
16 |
17 | export function looksLikeJavaHome(dir: string) {
18 | const lower = dir.toLocaleLowerCase();
19 | return lower.includes("jdk") || lower.includes("java");
20 | }
21 |
22 | export function deDup(arr: string[]) {
23 | return Array.from(new Set(arr));
24 | }
25 |
26 | export function expandTilde(filepath: string) {
27 | if (filepath.charCodeAt(0) === 126 /* ~ */) {
28 | return join(homedir(), filepath.slice(1));
29 | } else {
30 |
31 | return filepath;
32 | }
33 | }
34 |
35 | /**
36 | * Get real Java Home directory, deducted from real path of 'bin/java', with symbolic links resolved.
37 | * Mainly for Homebrew.
38 | * @param javaHomePathLike e.g. some-path supposed to have 'bin/java' under it.
39 | * @returns a valid java home
40 | */
41 | export async function getRealHome(javaHomePathLike: string): Promise {
42 | const javaBinaryPath = expandTilde(join(javaHomePathLike, "bin", JAVA_FILENAME));
43 | try {
44 | const rp = await fs.promises.realpath(javaBinaryPath);
45 | return dirname(dirname(rp));
46 | } catch (error) {
47 | logger.log(error);
48 | }
49 | return undefined;
50 | }
51 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 | const expect = require("chai").expect;
3 |
4 | describe("test this module", () => {
5 | const utils = require("../dist/index");
6 | it("should work with require", () => {
7 | expect(utils).to.not.undefined;
8 | });
9 |
10 | it("should list valid JDKs", async () => {
11 | const label = "cost";
12 | console.time(label);
13 | const jdks = await utils.findRuntimes();
14 | console.timeEnd(label);
15 | console.log("JDK found: ", jdks.length);
16 | jdks.forEach(jdk => console.log(jdk.homedir));
17 | });
18 |
19 | it("should fetch versions", async () => {
20 | const label = "withVersion";
21 | console.time(label);
22 | const jdks = await utils.findRuntimes({ withVersion: true });
23 | console.timeEnd(label);
24 | console.log("JDK found: ", jdks.length);
25 | console.log("homedir", "majorVersion");
26 | jdks.forEach(jdk => console.log(jdk.homedir, jdk.version?.major));
27 | });
28 |
29 | it("should check javac", async () => {
30 | const label = "checkJavac";
31 | console.time(label);
32 | const jdks = await utils.findRuntimes({ checkJavac: true });
33 | console.timeEnd(label);
34 | console.log("JDK found: ", jdks.length);
35 | console.log("homedir", "hasJavac");
36 | jdks.forEach(jdk => console.log(jdk.homedir, jdk.hasJavac));
37 | });
38 |
39 | it("should list all possible JDKs with version", async () => {
40 | const label = "checkJavac,withVersion";
41 | console.time(label);
42 | const jdks = await utils.findRuntimes({ checkJavac: true, withVersion: true });
43 | console.timeEnd(label);
44 | console.log("JDK found: ", jdks.length);
45 | console.log("homedir", "hasJava", "hasJavac", "majorVersion");
46 | jdks.forEach(jdk => console.log(jdk.homedir, jdk.hasJavac, jdk.version?.major));
47 | });
48 |
49 | it("should list with tags", async () => {
50 | const label = "withTags";
51 | console.time(label);
52 | const jdks = await utils.findRuntimes({ withTags: true, withVersion: true, checkJavac: true });
53 | console.timeEnd(label);
54 | console.log("JDK found: ", jdks.length);
55 | console.log(jdks);
56 | });
57 | it("should list sources", async () => {
58 | const label = "getSources";
59 | console.time(label);
60 | const jdks = await utils.findRuntimes({ withTags: true, withVersion: true, checkJavac: true });
61 | console.timeEnd(label);
62 | jdks.forEach(jdk => console.log(jdk.homedir, utils.getSources(jdk)));
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */
4 |
5 | /* Projects */
6 | // "incremental": true, /* Enable incremental compilation */
7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
12 |
13 | /* Language and Environment */
14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
16 | // "jsx": "preserve", /* Specify what JSX code is generated. */
17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
25 |
26 | /* Modules */
27 | "module": "commonjs", /* Specify what module code is generated. */
28 | // "rootDir": "./", /* Specify the root folder within your source files. */
29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */
35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
36 | // "resolveJsonModule": true, /* Enable importing .json files */
37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */
38 |
39 | /* JavaScript Support */
40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
43 |
44 | /* Emit */
45 | "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */
47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
50 | "outDir": "dist", /* Specify an output folder for all emitted files. */
51 | // "removeComments": true, /* Disable emitting comments. */
52 | // "noEmit": true, /* Disable emitting files from a compilation. */
53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
61 | // "newLine": "crlf", /* Set the newline character for emitting files. */
62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
67 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
68 |
69 | /* Interop Constraints */
70 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
71 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
72 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
73 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
74 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
75 |
76 | /* Type Checking */
77 | "strict": true, /* Enable all strict type-checking options. */
78 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
79 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
80 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
81 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
82 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
83 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
84 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
85 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
86 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
87 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
88 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
89 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
90 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
91 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
92 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
93 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
94 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
95 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
96 |
97 | /* Completeness */
98 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
99 | "skipLibCheck": true /* Skip type checking all .d.ts files. */
100 | }
101 | }
102 |
--------------------------------------------------------------------------------